spring-ioc基礎學習(2)基于注解方式的ioc配置

使用java注解的方式去實現(xiàn)IOC的配置

主要目標:

  • 1.學習spring基于java注解的配置方式
  • 2.熟悉spring配置注解

進行環(huán)境搭建

  • 1.創(chuàng)建maven項目
  • 2.引入spring依賴包
<dependencies>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>5.2.6.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>druid</artifactId>
        <version>1.1.21</version>
    </dependency>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.1.47</version>
    </dependency>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
        <scope>test</scope>
    </dependency>
</dependencies>
  • 3.創(chuàng)建spring-ioc.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.xsd">
</beans>
  • 4.創(chuàng)建數(shù)據(jù)庫配置文件db.properties
mysql.username=mall
mysql.password=mall
mysql.url=jdbc:mysql://192.168.1.150:3306/mall
mysql.driver=com.mysql.jdbc.Driver
  • 5.創(chuàng)建接口和類
com.learn.controller
UserController
com.learn.service
IUserService
com.learn.service.impl
UserServiceImpl
com.learn.dao
IUserDao
com.learn.dao.impl
UserDaoImpl
com.learn.bean
User
Role

開始學習基礎內容

- 1.對類進行注解標注,將bean注冊到容器中有4種方式:

1.使用xml進行配置bean標簽
2.使用@Component以及相關的標簽進行注解后,使用包掃描方式進行注冊
3.使用@Bean注解
4.使用@Import注解

本例主要使用@Component方式進行注冊bean

@Component,@Controller,@Service,@Repository 四個注解性質基本相同具體如下:

@Component

@Component:spring 注冊組件的注解,@Service,@Controller,@Repository等的注冊功能都是由該注解提供,使用該標注后對應類將注冊到容器中

源碼:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Indexed
public @interface Component {

    /**
     * The value may indicate a suggestion for a logical component name,
     * to be turned into a Spring bean in case of an autodetected component.
     * @return the suggested component name, if any (or empty String otherwise)
     */
    String value() default "";

}
@Controller

@Controller:控制器纷铣,推薦給controller層添加此注解

源碼

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Controller {

    /**
     * The value may indicate a suggestion for a logical component name,
     * to be turned into a Spring bean in case of an autodetected component.
     * @return the suggested component name, if any (or empty String otherwise)
     */
    @AliasFor(annotation = Component.class)
    String value() default "";

}
@Service

@Service:業(yè)務邏輯关炼,推薦給業(yè)務邏輯層添加此注解

源碼

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Service {

    /**
     * The value may indicate a suggestion for a logical component name,
     * to be turned into a Spring bean in case of an autodetected component.
     * @return the suggested component name, if any (or empty String otherwise)
     */
    @AliasFor(annotation = Component.class)
    String value() default "";

}
@Repository

@Repository:倉庫管理,推薦給數(shù)據(jù)訪問層添加此注解

源碼

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Repository {

    /**
     * The value may indicate a suggestion for a logical component name,
     * to be turned into a Spring bean in case of an autodetected component.
     * @return the suggested component name, if any (or empty String otherwise)
     */
    @AliasFor(annotation = Component.class)
    String value() default "";

}

從源碼上看@Controller,@Service,@Repository的源碼沒有區(qū)別,只是名稱定義不同,實現(xiàn)功能上三者完全一致,只是表示不同意義,方便開發(fā)者更直觀的定義各個類的意義.
并且能對不同類型的bean進行一個區(qū)別,方便進行操作.

2.給各個類加上@Component相關注解

Controller類加上@Controller注解
例如:

@Controller//將組建添加到容器中--標注為控制器
public class UserController 

ServiceImpl相關的類均加上@Service注解
例如:

@Service//配置對象加載到容器中--標注為業(yè)務邏輯類
public class UserServiceImpl implements IUserService 

給DaoImpl相關類加上@Repository注解

@Repository//配置對象加載到容器中--標注為數(shù)據(jù)訪問
public class UserDaoImpl implements IUserDao{

給其他需要注冊的類加上@Component注解
例如

@Component
public class User 

3.在spring-ioc.xml文件中進行包掃描相關配置,將指定包內的被我們標注要注冊的類均注冊到spring容器中

示例:

 <context:component-scan base-package="com.learn" >
</context:component-scan>
//base-package為指定的包路徑
context:component-scan標簽

包含2個子標簽,7個屬性

如圖:
context:component-scan源碼

各個標簽和屬性的意義示例:
<context:component-scan base-package="com.wjx.betalot" <!-- 掃描的基本包路徑 -->
                        annotation-config="true" <!-- 是否激活屬性注入注解 -->
                        name-generator="org.springframework.context.annotation.AnnotationBeanNameGenerator"  <!-- Bean的ID策略生成器 -->
                        resource-pattern="**/*.class" <!-- 對資源進行篩選的正則表達式,這邊是個大的范疇见转,具體細分在include-filter與exclude-filter中進行 -->
                        scope-resolver="org.springframework.context.annotation.AnnotationScopeMetadataResolver" <!-- scope解析器 蒜哀,與scoped-proxy只能同時配置一個 -->
                        scoped-proxy="no" <!-- scope代理,與scope-resolver只能同時配置一個 -->
                        use-default-filters="false" <!-- 是否使用默認的過濾器乘客,默認值true -->
                                  >
            <!-- 注意:若使用include-filter去定制掃描內容淀歇,要在use-default-filters="false"的情況下,不然會“失效”浪默,被默認的過濾機制所覆蓋 -->                   
            <!-- annotation是對注解進行掃描 -->
            <context:include-filter type="annotation" expression="org.springframework.stereotype.Component"/> 
            <!-- assignable是對類或接口進行掃描 -->
            <context:include-filter type="assignable" expression="com.wjx.betalot.performer.Performer"/>
            <context:include-filter type="assignable" expression="com.wjx.betalot.performer.impl.Sonnet"/>
            
            <!-- 注意:在use-default-filters="false"的情況下,exclude-filter是針對include-filter里的內容進行排除 -->
            <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
            <context:exclude-filter type="assignable" expression="com.wjx.betalot.performer.impl.RainPoem"/>
            <context:exclude-filter type="regex" expression=".service.*"/> 

</context:component-scan>

<context:exclude-filter>和<context:include-filter>兩個標簽的tyep類型決定加載與排除的規(guī)則,具體type類型有如下幾種

/*
annotation:按照注解進行排除碰逸,標注了指定注解的組件不要,expression表示要過濾
的注解
assignable:指定排除某個具體的類阔加,按照類排除,expression表示不注冊的具體類名
aspectj:后面講aop的時候說明要使用的aspectj表達式
custom:定義一個typeFilter,自己寫代碼決定哪些類被過濾掉
regex:使用正則表達式過濾
*/

參考鏈接https://www.cnblogs.com/fightingcoding/p/component-scan.html

4.完成包掃描后可以使用自動注入來獲取bean實例

自動注入實現(xiàn)有兩個標簽分別是

@Autowired
@Resource

@Autowired標簽的使用

使用@Autowired來實現(xiàn)自動注入

·默認優(yōu)先根據(jù)類型去匹配
·如果匹配到多個類型則會按照名字匹配
·如果名又沒有匹配到則會報錯:
1.可以去修改屬性的名字對應bean的名字:userServiceImpl
2.可以去修改Bean的名字對應屬性的名字:@Service("userService")
3.可以通過@Qualifier設置屬性的名字(覆蓋) :@Qualifier("userServiceImpl")
4.可以通過@Primary 設置其中一個Bean為主要的自動注入Bean:@Primary
5.使用泛型作為自動注入限定符

注意:
    1. 如果只找到一個约急,則直接進行賦值
    1. 如果沒有找到苗分,則直接拋出異常
    1. 如果找到多個,那么會按照變量名作為id繼續(xù)匹配
      1. 匹配上直接進行裝配
      2. 如果匹配不上則直接報異常
    1. 當定義@Autowired的required為false時,沒有匹配上是不會報錯的,默認為ture
示例
    /**
     * @Autowired 也可以寫在構造器上面
     * ·默認優(yōu)先根據(jù)參數(shù)類型去匹配
     * ·如果匹配到多個類型則會按照參數(shù)名字匹配*/
    @Autowired
    public UserController(UserService userService) {
        this.userService = userService;
    }
   /**
     * @Autowired 也可以寫在方法上面
     * ·默認優(yōu)先根據(jù)參數(shù)類型去匹配
     * ·如果匹配到多個類型則會按照參數(shù)名字匹配
     * @Qualifier注解也可以作用在屬性上奴饮,用來被當作id去匹配容器中的對象择浊,如果沒有此注解,那么直接按照類型進行匹配
     * @param userService*/
    @Autowired
    public void createUserSerive(@Qualifier("userServiceImpl")UserService userService){
        this.userService=userService;
    }
@Autowired源碼
@Target({ElementType.CONSTRUCTOR, ElementType.METHOD, ElementType.PARAMETER, ElementType.FIELD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Autowired {

    /**
     * Declares whether the annotated dependency is required.
     * <p>Defaults to {@code true}.
     */
    boolean required() default true;
}

@Autowired和@Resource都可以自動進行bean注入,但是有一定區(qū)別

1.@Autowired:是spring中提供的注解投剥,@Resource:是jdk中定義的注解担孔,依靠的是java的標準
2.@Autowired默認是按照類型進行裝配吃警,默認情況下要求依賴的對象必須存在啄育,@Resource默認是按照名字進行匹配的,同時可以指定name屬性挑豌。
3.@Autowired只適合spring框架,而@Resource擴展性更好

5.對類的注入設置依賴關系@DependsOn

使用@DependsOn標簽可以設定當前類的注入需要依賴哪些類,將對應類寫入其中后,寫入的類會優(yōu)先于當前類加載到容器中

示例
@Repository//配置對象加載到容器中--標注為數(shù)據(jù)訪問
@DependsOn({"user","role"})
public class UserDaoImpl implements IUserDao

6.將類的注入方式設置為懶加載模式@Lazy

使用@Lazy標簽標注類后,該類將不會自動加載,而是在主動調用后才進行加載

示例
@Repository//配置對象加載到容器中--標注為數(shù)據(jù)訪問
@Lazy//配置對象為懶加載
public class UserDaoImpl implements IUserDao

7.設定bean的作用域使用@Scope標簽

@Scope標簽默認為單例模式,可以根據(jù)情況設置為原型模式(多實例)

示例
@Repository//配置對象加載到容器中--標注為數(shù)據(jù)訪問
@Scope(value = "prototype")
public class UserDaoImpl implements IUserDao

8.設定生命周期控制使用@PostConstruct和@PreDestroy兩個注釋

@PostConstruct設置的是bean初始化時的方法;
@PreDestroy設置的是bean銷毀時調用的方法

示例
//    配置對象初始化時調用的方法
    @PostConstruct
    public void init(){
        System.out.println(" userDaoImpl init");
    }
//    配置對象銷毀時的調用方法
    @PreDestroy
    public void destroy(){
        System.out.println("userDaoImpl destroy");
    }

總結

1.bean注冊到容器中的方式
2.@Component的細節(jié)和使用
3.包掃描配置方式context:component-scan
4.自動注入@Autowired和@Resource
5.對類的注入設置依賴關系@DependsOn
6.將類的注入方式設置為懶加載模式@Lazy
7.設定bean的作用域使用@Scope標簽
8.設定生命周期@PostConstruct和@PreDestroy
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市址貌,隨后出現(xiàn)的幾起案子饰迹,更是在濱河造成了極大的恐慌,老刑警劉巖啊鸭,帶你破解...
    沈念sama閱讀 207,113評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異赂摆,居然都是意外死亡钟些,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評論 2 381
  • 文/潘曉璐 我一進店門汪拥,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人迫筑,你說我怎么就攤上這事宗弯。” “怎么了蒙保?”我有些...
    開封第一講書人閱讀 153,340評論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長逝嚎。 經(jīng)常有香客問我,道長涤妒,這世上最難降的妖魔是什么单雾? 我笑而不...
    開封第一講書人閱讀 55,449評論 1 279
  • 正文 為了忘掉前任硅堆,我火速辦了婚禮,結果婚禮上渐逃,老公的妹妹穿的比我還像新娘。我一直安慰自己茄菊,他們只是感情好,可當我...
    茶點故事閱讀 64,445評論 5 374
  • 文/花漫 我一把揭開白布竖哩。 她就那樣靜靜地躺著脊僚,像睡著了一般。 火紅的嫁衣襯著肌膚如雪增淹。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,166評論 1 284
  • 那天虑润,我揣著相機與錄音,去河邊找鬼姜骡。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 38,442評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼朵栖,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了陨溅?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 37,105評論 0 261
  • 序言:老撾萬榮一對情侶失蹤雹有,失蹤者是張志新(化名)和其女友劉穎臼寄,沒想到半個月后霸奕,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體吉拳,經(jīng)...
    沈念sama閱讀 43,601評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡留攒,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,066評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了炼邀。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,161評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡什猖,死狀恐怖红淡,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情在旱,我是刑警寧澤,帶...
    沈念sama閱讀 33,792評論 4 323
  • 正文 年R本政府宣布驻仅,位于F島的核電站登渣,受9級特大地震影響,放射性物質發(fā)生泄漏胜茧。R本人自食惡果不足惜仇味,卻給世界環(huán)境...
    茶點故事閱讀 39,351評論 3 307
  • 文/蒙蒙 一雹顺、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧贩挣,春花似錦、人聲如沸王财。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,352評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至论颅,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間恃疯,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,584評論 1 261
  • 我被黑心中介騙來泰國打工郑口, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留盾鳞,地道東北人。 一個月前我還...
    沈念sama閱讀 45,618評論 2 355
  • 正文 我出身青樓乒裆,卻偏偏與公主長得像,于是被迫代替她去往敵國和親鹤耍。 傳聞我的和親對象是個殘疾皇子验辞,可洞房花燭夜當晚...
    茶點故事閱讀 42,916評論 2 344