Spring

快速入門

Spring是一個管理Bean的容器杂数,一個輕量級框架

  • 使用Spring,需要引入對應(yīng)的依賴下載地址

        <properties>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
            <springFramework.version>5.1.5.RELEASE</springFramework.version>
        </properties> 
      <dependencies>
            <!-- spring相關(guān) -->
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-web</artifactId>
                <version>${springFramework.version}</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-webmvc</artifactId>
                <version>${springFramework.version}</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-context</artifactId>
                <version>${springFramework.version}</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-jdbc</artifactId>
                <version>${springFramework.version}</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-test</artifactId>
                <version>${springFramework.version}</version>
            </dependency>
            <!--日志-->
            <dependency>
                <groupId>org.apache.logging.log4j</groupId>
                <artifactId>log4j</artifactId>
                <version>2.10.0</version>
            </dependency>
            <dependency>
                <groupId>commons-logging</groupId>
                <artifactId>commons-logging</artifactId>
                <version>1.2</version>
            </dependency>
        </dependencies>
    
  • 管理對象,必須是一個接口一個實現(xiàn)類

    /**
     * 戰(zhàn)士
     */
    public interface Fighter {
        void show();
    }
    
    /**
    * 呂布瘸洛,戰(zhàn)士類的一個實現(xiàn)類
    */
    public class LvBu implements Fighter {
        public void show() {
            System.out.println("戰(zhàn)士呂布");
        }
    }
    

IOC控制反轉(zhuǎn)/DI依賴注入

回顧歷史

之前我們創(chuàng)建對象的方式揍移,是在一個類中主動new另一個類的對象,然后再調(diào)用其方法完成功能

public class Main {
    public static void main(String[] args) {
        // 獲取對象 -- 以前的方式反肋,主動創(chuàng)建
        Fighter f1 = new LvBu();
        f1.show();
    }
}

Main類掌握著Fighter類型對象的控制權(quán)(想創(chuàng)建就創(chuàng)建)那伐,這樣帶來一個缺點,當(dāng)許多模塊都需要使用Fighter類型對象時囚玫,一旦Fighter類型對象需要發(fā)生改變喧锦,需要大量的修改其他模塊的代碼才能滿足需求读规,所以抓督,Spring提出了一種新的獲取對象的方式 -- 配置

spring配置文件

spring.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

    <!--配置一個對象-->
    <!--LvBu lvbu = new LvBu();-->
    <bean id="lvbu" class="com.neuedu.test.LvBu"></bean>
    <bean id="guanyu" class="com.neuedu.test.GuanYu"></bean>

</beans>
public class Main {
    public static void main(String[] args) {
        // 獲取對象 -- 以前的方式,主動創(chuàng)建
//        Fighter f1 = new LvBu();
//        f1.show();

        // Spring的方式獲取對象束亏,需要把對象配置在xml文件中
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");
        Fighter lvbu = (Fighter)applicationContext.getBean("lvbu");
        Fighter guanyu = (Fighter)applicationContext.getBean("guanyu");
        lvbu.show(); // 戰(zhàn)士呂布
        guanyu.show(); // 戰(zhàn)士關(guān)羽
    }
}

使用配置的方式帶來一個好處铃在,當(dāng)Fighter類型對象需要改變的時候,我們只需要修改spring.xml就可以了,不需要修改其他模塊定铜,便利了開發(fā)

IOC控制反轉(zhuǎn)

對于java應(yīng)用程序來說阳液,對象的控制權(quán)逆轉(zhuǎn)了,這個概念稱為IOC--控制反轉(zhuǎn)揣炕。
之間調(diào)用或創(chuàng)建對象都是交給java應(yīng)用程序來完成帘皿,現(xiàn)在交給spring來分配。

DI依賴注入

對于spring來說畸陡,配置一個對象鹰溜,相當(dāng)于對其他調(diào)用者注入了一個可調(diào)用的對象

IOC控制反轉(zhuǎn)和DI依賴注入沒有區(qū)別,只是針對參照物不同的不同說法

屬性注入
  • 構(gòu)造器注入(前提:必須有有參構(gòu)造器)

    <!--默認(rèn)是調(diào)用無參構(gòu)造器創(chuàng)建對象的丁恭,若沒有無參構(gòu)造器曹动,會報錯-->
    <bean id="guanyu" class="com.neuedu.test.GuanYu"></bean>
    
    public class GuanYu implements Fighter {
        private String name;
        private int age;
        public GuanYu() {}
        public GuanYu(String name, int age) {
            this.name = name;
            this.age = age;
        }
        public void show() {
            System.out.println(name+","+age);
        }
    }
    
    <!--利用有參構(gòu)造器進(jìn)行屬性注入-->
    <bean id="guanyu" class="com.neuedu.test.GuanYu">
        <!--構(gòu)造器注入屬性-->
        <!--給對象的name屬性,賦值“關(guān)羽”-->
        <constructor-arg name="name" value="關(guān)羽"></constructor-arg>
        <!--給對象的age屬性牲览,賦值14-->
        <constructor-arg name="age" value="14"></constructor-arg>
    </bean>
    

    復(fù)雜對象

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="http://www.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
        <bean id="guanyu" class="com.neuedu.test.GuanYu">
            <constructor-arg name="name" value="關(guān)羽"></constructor-arg>
            <!--屬性注入如果是對象墓陈,需要用ref關(guān)聯(lián)另一個對象id-->
            <constructor-arg name="weapon" ref="qinglong"></constructor-arg>
        </bean>
        <!--配一個QingLong-->
        <bean id="qinglong" class="com.neuedu.test.QingLong">
            <property name="dps" value="50"></property>
        </bean>
    </beans>
    

    集合

  • setter注入

    <bean id="guanyu" class="com.neuedu.test.GuanYu">
        <!--利用set方法注入屬性-->
        <property name="name" value="關(guān)羽坤"></property>
        <property name="age" value="144"></property>
    </bean>
    

    復(fù)雜對象

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="http://www.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
        <bean id="guanyu" class="com.neuedu.test.GuanYu">
            <property name="name" value="關(guān)羽"></property>
            <!--屬性注入如果是對象,需要用ref關(guān)聯(lián)另一個對象id-->
            <property name="weapon" ref="qinglong"></property>
        </bean>
        <!--配一個QingLong-->
        <bean id="qinglong" class="com.neuedu.test.QingLong">
            <property name="dps" value="50"></property>
        </bean>
    </beans>
    

    集合

        <bean id="guanyu" class="com.neuedu.test.GuanYu">
            <property name="name" value="關(guān)羽"></property>
            <!--屬性注入如果是對象第献,需要用ref關(guān)聯(lián)另一個對象id-->
            <property name="weapon" ref="qinglong"></property>
            <!--List<String>-->
            <property name="boy">
                <list>
                    <value>張飛</value>
                    <value>馬超</value>
                </list>
            </property>
            <!--List<Weapon>-->
            <property name="repository">
                <list>
                    <ref bean="qinglong"></ref>
                    <ref bean="fang"></ref>
                </list>
            </property>
            <!--Map<String,String>-->
            <property name="horse">
                <map>
                    <entry key="坐騎1" value="赤兔"></entry>
                    <entry key="坐騎2" value="的盧"></entry>
                </map>
            </property>
            <!--Map<String,Weapon>-->
            <property name="weaponMap">
                <map>
                    <entry key="武器1" value-ref="qinglong"></entry>
                    <entry key="武器2" value-ref="fang"></entry>
                </map>
            </property>
        </bean>
    
  • 接口注入(Spring不支持)

自動裝配(了解)

<!-- ==========================自動按名字裝配autowire=byName=========================== -->
<!-- ==========================自動按類型裝配autowire=byType=========================== -->
<bean id="qiyi" class="com.neuedu.test1.QiYi" autowire="byType"/>
<!-- 當(dāng)按照類型裝配時贡必,有多個符合條件的對象,需要指定primary="true"表明是主要的裝配對象 -->
<bean id="wuqi" class="com.neuedu.test1.FaZhang" primary="true">
    <property name="name" value="大法師之杖"></property>
</bean>
<bean id="kandao" class="com.neuedu.test1.KanDao">
    <property name="name" value="大法師砍刀"></property>
</bean>
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context-3.0.xsd">
    <!-- 開啟注解 -->
    <context:annotation-config />
    <bean id="guanyu" class="com.neuedu.test.GuanYu"></bean>
    <bean id="abc1" class="com.neuedu.test.QingLong">
        <qualifier value="test1"></qualifier>
    </bean>
    <bean id="abc2" class="com.neuedu.test.Fang">
        <qualifier value="test2"></qualifier>
    </bean>
</beans>
package com.neuedu.test;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;

public class GuanYu implements Fighter {
    private String name = "關(guān)羽";
    @Autowired
    @Qualifier("test2")// 轉(zhuǎn)配的com.neuedu.test.Fang
    private Weapon weapon;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public void setWeapon(Weapon weapon) {
        this.weapon = weapon;
    }
    public void show() {
        System.out.println(name);
        weapon.showInfo();
    }
}

注解自動裝配(重要)

spring.xml配置掃描包

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context-3.0.xsd">
    <context:component-scan base-package="com.neuedu.test"></context:component-scan>
    <bean id="guanyu" class="com.neuedu.test.GuanYu"></bean>
</beans>
public class Main {
    public static void main(String[] args) {
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");
        GuanYu guanyu = (GuanYu)applicationContext.getBean("guanyu");
        guanyu.show();
    }
}
@Component("test1")
public class QingLong implements Weapon {
    private int dps;
    public void setDps(int dps) {
        this.dps = dps;
    }
    public int getDps() {
        return dps;
    }
    public void showInfo() {
        System.out.println("青龍偃月庸毫,攻擊力很高");
    }
}
@Component("test2")
public class Fang implements Weapon {
    private int dps;
    public void setDps(int dps) {
        this.dps = dps;
    }
    public int getDps() {
        return dps;
    }
    public void showInfo() {
        System.out.println("方天畫戟赊级,攻擊力很高");
    }
}
@Component
public class GuanYu implements Fighter {
    private String name = "關(guān)羽";
    @Autowired
    @Qualifier("test2")
    private Weapon weapon;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public void setWeapon(Weapon weapon) {
        this.weapon = weapon;
    }
    public void show() {
        System.out.println(name);
        weapon.showInfo();
    }
}

@Component:標(biāo)記類,交給spring統(tǒng)一管理岔绸。(不同層理逊,用的)
@Autowired:注入依賴。
@Qualifier("test2"):注入依賴具體的名字盒揉。

類型 說明

@Component 通用的構(gòu)造型注解晋被,標(biāo)示該類為Spring 組件。

@Controller 標(biāo)識將該類定義為Spring MVC controller刚盈。

@Repository 標(biāo)識將該類定義為數(shù)據(jù)倉庫(例如:Dao層)羡洛。

@Service 標(biāo)識將該類定義為服務(wù)(例如:Service層)。

AOP面向切面編程

一般應(yīng)用在如性能檢測藕漱、訪問控制欲侮、事務(wù)控制、日志記錄等

![*](file:///C:\Users\ADMINI~1\AppData\Local\Temp\artD302.tmp)切面(Aspect)

![*](file:///C:\Users\ADMINI~1\AppData\Local\Temp\artD312.tmp)切面是切點和通知組成肋联,通知和切點共同定義了切面的全部內(nèi)容即:它是什么威蕉,在何時何處完成其功能;

![*](file:///C:\Users\ADMINI~1\AppData\Local\Temp\artD313.tmp)連接點(Joinpoint)

![*](file:///C:\Users\ADMINI~1\AppData\Local\Temp\artD314.tmp)連接點是在應(yīng)用執(zhí)行過程中能夠插入切面的一個點橄仍,Spring僅支持方法的連接點韧涨,即僅能在方法調(diào)用前牍戚,方法調(diào)用后,方法拋出異常時及方法調(diào)用前后插入切面代碼虑粥。

![*](file:///C:\Users\ADMINI~1\AppData\Local\Temp\artD315.tmp)切點(Pointcut)

![*](file:///C:\Users\ADMINI~1\AppData\Local\Temp\artD316.tmp)切點定義了在何處應(yīng)用切面如孝,AOP通過“切點”定位特定的連接點。切點相當(dāng)于查詢條件娩贷,一個切點可以匹配多個連接點第晰。

![*](file:///C:\Users\ADMINI~1\AppData\Local\Temp\artD317.tmp)通知(Advice)

![*](file:///C:\Users\ADMINI~1\AppData\Local\Temp\artD318.tmp)切面的工作被成為通知,定義了切面是什么及何時使用彬祖。除了描述切面要完成的工作但荤,通知還解決了何時執(zhí)行這個工作的問題,它應(yīng)該在某個方法被調(diào)用之前涧至?之后腹躁?等。

![*](file:///C:\Users\ADMINI~1\AppData\Local\Temp\artD319.tmp)Spring切面可以應(yīng)用5種類型的通知:

![*](file:///C:\Users\ADMINI~1\AppData\Local\Temp\artD32A.tmp)前置通知(Before)在目標(biāo)方法被調(diào)用之前調(diào)用通知功能南蓬;

![*](file:///C:\Users\ADMINI~1\AppData\Local\Temp\artD32B.tmp)后置通知(After)在目標(biāo)方法被完成之后調(diào)用通知功能纺非,不關(guān)心方法的輸出是什么;

![*](file:///C:\Users\ADMINI~1\AppData\Local\Temp\artD32C.tmp)環(huán)繞通知(Around advice)通知包裹了目標(biāo)方法赘方,在目標(biāo)方法調(diào)用之前和之后執(zhí)行自定義的行為烧颖;

![*](file:///C:\Users\ADMINI~1\AppData\Local\Temp\artD32D.tmp)異常通知(After-throwing)在目標(biāo)方法拋出異常后調(diào)用通知;

![*](file:///C:\Users\ADMINI~1\AppData\Local\Temp\artD32E.tmp)返回通知(After-returning)在目標(biāo)方法成功執(zhí)行之后調(diào)用通知窄陡;

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末炕淮,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子跳夭,更是在濱河造成了極大的恐慌涂圆,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,454評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件币叹,死亡現(xiàn)場離奇詭異润歉,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)颈抚,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,553評論 3 385
  • 文/潘曉璐 我一進(jìn)店門踩衩,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人贩汉,你說我怎么就攤上這事驱富。” “怎么了匹舞?”我有些...
    開封第一講書人閱讀 157,921評論 0 348
  • 文/不壞的土叔 我叫張陵褐鸥,是天一觀的道長。 經(jīng)常有香客問我策菜,道長晶疼,這世上最難降的妖魔是什么酒贬? 我笑而不...
    開封第一講書人閱讀 56,648評論 1 284
  • 正文 為了忘掉前任又憨,我火速辦了婚禮翠霍,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘蠢莺。我一直安慰自己寒匙,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 65,770評論 6 386
  • 文/花漫 我一把揭開白布躏将。 她就那樣靜靜地躺著锄弱,像睡著了一般。 火紅的嫁衣襯著肌膚如雪祸憋。 梳的紋絲不亂的頭發(fā)上会宪,一...
    開封第一講書人閱讀 49,950評論 1 291
  • 那天,我揣著相機(jī)與錄音蚯窥,去河邊找鬼掸鹅。 笑死,一個胖子當(dāng)著我的面吹牛拦赠,可吹牛的內(nèi)容都是我干的巍沙。 我是一名探鬼主播,決...
    沈念sama閱讀 39,090評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼荷鼠,長吁一口氣:“原來是場噩夢啊……” “哼句携!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起允乐,我...
    開封第一講書人閱讀 37,817評論 0 268
  • 序言:老撾萬榮一對情侶失蹤矮嫉,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后牍疏,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體敞临,經(jīng)...
    沈念sama閱讀 44,275評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,592評論 2 327
  • 正文 我和宋清朗相戀三年麸澜,在試婚紗的時候發(fā)現(xiàn)自己被綠了挺尿。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,724評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡炊邦,死狀恐怖编矾,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情馁害,我是刑警寧澤窄俏,帶...
    沈念sama閱讀 34,409評論 4 333
  • 正文 年R本政府宣布,位于F島的核電站碘菜,受9級特大地震影響凹蜈,放射性物質(zhì)發(fā)生泄漏限寞。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 40,052評論 3 316
  • 文/蒙蒙 一仰坦、第九天 我趴在偏房一處隱蔽的房頂上張望履植。 院中可真熱鬧,春花似錦悄晃、人聲如沸玫霎。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,815評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽庶近。三九已至,卻和暖如春眷蚓,著一層夾襖步出監(jiān)牢的瞬間鼻种,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,043評論 1 266
  • 我被黑心中介騙來泰國打工沙热, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留叉钥,地道東北人。 一個月前我還...
    沈念sama閱讀 46,503評論 2 361
  • 正文 我出身青樓校读,卻偏偏與公主長得像沼侣,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子歉秫,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,627評論 2 350

推薦閱讀更多精彩內(nèi)容