Spring Boot常用注解(二) - 注入Bean的注解

1. 概述

Spring Boot常用注解(一) - 聲明Bean的注解 中學習了Spring Boot中聲明Bean的注解
那Spring容器中的Bean是怎么實現(xiàn)自動裝配(依賴)的呢骤素?
這就是接下來學習的注入注解咯

注入Bean的注解:

  • @Autowired
  • @Inject
  • @Resource

2. @Autowired注解

@Autowired注解源碼:

package org.springframework.beans.factory.annotation;

/**
 1. @since 2.5
 2. @see AutowiredAnnotationBeanPostProcessor
 3. @see Qualifier
 4. @see Value
 */
@Target({ElementType.CONSTRUCTOR, ElementType.METHOD, ElementType.PARAMETER, ElementType.FIELD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Autowired {

    boolean required() default true;
}
  1. @Autowired注解作用在構造函數(shù)棚品、方法捧搞、方法參數(shù)置鼻、類字段以及注解上
  2. @Autowired注解可以實現(xiàn)Bean的自動注入

2.1 @Autowired注解原理

在Spring Boot應用啟動時不恭,Spring容器會自動裝載一個org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor處理器,當容器掃掃描到@Autowired注解時啦扬,就會在IoC容器就會找相應類型的Bean内狗,并且實現(xiàn)注入。

2.2 @Autowired注解使用

在Web MVC中控制層(Controller)訪問的是業(yè)務層(Service)唤蔗,而業(yè)務層(Service)訪問的是數(shù)據(jù)層(Dao),使用@Autowired注解實現(xiàn)注入

數(shù)據(jù)層:

package com.example.demo.chapter1.useannotation.autowired.dao;

/**
 * 數(shù)據(jù)層接口探遵,用于訪問數(shù)據(jù)庫窟赏,返回數(shù)據(jù)給業(yè)務層
 * */
public interface IDao {
    public String get();
}

/**
 * 數(shù)據(jù)層接口實現(xiàn)類
 * 
 * 1.數(shù)據(jù)層Bean用@Repository標注
 * 2.當前Bean的名稱是"autowiredUserDaoImpl"
 * 3.設置當前Bean的為原型模式,即每次獲取Bean時都創(chuàng)建一個新實例
 * */
@Repository("autowiredUserDaoImpl")
@Scope("prototype")
public class UserDaoImpl implements IDao {

    public String get() {
        return "@Autowired注解實現(xiàn)自動裝配";
    }
}

業(yè)務層:

package com.example.demo.chapter1.useannotation.autowired.service;

/**
 * 業(yè)務層接口
 * 從數(shù)據(jù)層獲取數(shù)據(jù)箱季,處理結果返回給控制層
 * */
public interface IService {
    public String get();
}

/**
 * 業(yè)務層接口實現(xiàn)
 * 
 * 1.數(shù)據(jù)層Bean用@Service標注
 * 2.當前Bean的名稱是"autowiredUserServiceImpl"
 * 3.設置當前Bean的為原型模式涯穷,即每次獲取Bean時都創(chuàng)建一個新實例
 * 4.業(yè)務層有一個數(shù)據(jù)層接口IDao,使用@Autowired注解標注
 * */

@Service("autowiredUserServiceImpl")
@Scope("prototype")
public class UserServiceImpl implements IService {
    /**
     * @Autowired實現(xiàn)自動裝配
     * Spring IoC容器掃描到@Autowired注解會去查詢IDao的實現(xiàn)類藏雏,并自動注入
     * */
    @Autowired
    private IDao dao;

    @Override
    public String get() {
        return dao.get();
    }
}
  1. Bean通過注解@Service聲明為一個Spring容器管理的Bean拷况,Spring容器會掃描classpath路徑下的所有類,找到帶有@Service注解的UserServiceImpl類掘殴,并根據(jù)Spring注解對其進行初始化和增強赚瘦,命名為autowiredUserServiceImpl
  2. Spring容器如果發(fā)現(xiàn)此類屬性dao也有注解@Autowired,則會從Spring容器中查找一個已經(jīng)初始化好的IDao的實現(xiàn)類奏寨,如果沒有找到起意,則先初始化一個IDao實現(xiàn)類

控制層:

package com.example.demo.chapter1.useannotation.autowired.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.example.demo.chapter1.useannotation.autowired.service.IService;

/**
 1. 控制層
 2. 
 3. 1.控制層使用@RestController注解標注,返回json格式的字符串
 4. 2.獲取業(yè)務層返回的數(shù)據(jù)病瞳,輸出到客戶端
 5. 3.請求:http:localhost:8080/autowiredController
 6. */
@RestController
public class AutowiredController {
    @Autowired
    private IService service;

    @RequestMapping("/autowiredController")
    public String get () {
        return service.get();
    }
}

測試結果:

  1. 啟動Spring Boot應用
  2. 瀏覽器輸入:http:localhost:8080/autowiredController
  3. 返回結果:


    2019102606.png

2.3 @Qualifier注解

@Qualifier注解源碼:

package org.springframework.beans.factory.annotation;

/**
 * @since 2.5
 * @see Autowired
 */
@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.TYPE, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Qualifier {

    String value() default "";

}
  1. 如果Spring 容器中有兩個數(shù)據(jù)層接口IDao的實現(xiàn)類
  2. 而業(yè)務層通過@Autowired注解標注的是IDao接口
  3. 這時就需要@Qualifier注解來指定需要自動裝配的Bean的名稱
  4. 否則會報如下的錯:
Description:

Field dao in com.example.demo.chapter1.useannotation.autowired.service.UserServiceImpl required a single bean, but 2 were found:
    - autowiredAdminDaoImpl: defined in file [D:\eclipse\workspace\boot\demo\target\classes\com\example\demo\chapter1\useannotation\autowired\dao\AdminDaoImpl.class]
    - autowiredUserDaoImpl: defined in file [D:\eclipse\workspace\boot\demo\target\classes\com\example\demo\chapter1\useannotation\autowired\dao\UserDaoImpl.class]


Action:

Consider marking one of the beans as @Primary, updating the consumer to accept multiple beans, or using @Qualifier to identify the bean that should be consumed

2.4 @Qualifier注解使用

數(shù)據(jù)層接口IDao:

public interface IDao {
    public String get();
}

IDao實現(xiàn)類 - UserDaoImpl

@Repository("autowiredUserDaoImpl")
@Scope("prototype")
public class UserDaoImpl implements IDao {

    public String get() {
        return "@Autowired注解實現(xiàn)自動裝配 - UserDaoImpl";
    }
}

IDao實現(xiàn)類 - AdminDaoImpl

@Repository("autowiredAdminDaoImpl")
@Scope("prorotype")
public class AdminDaoImpl implements IDao {

    @Override
    public String get() {
        return "@Autowired注解實現(xiàn)自動裝配 - AdminDaoImpl";
    }
}

@Qualifier注解使用:

@Service("autowiredUserServiceImpl")
@Scope("prototype")
public class UserServiceImpl implements IService {
    /**
     * @Autowired實現(xiàn)自動裝配
     * Spring IoC容器掃描到@Autowired注解會去查詢IDao的實現(xiàn)類揽咕,并自動注入
     * */
    @Autowired
    @Qualifier("autowiredUserDaoImpl")
    private IDao dao;

    @Override
    public String get() {
        return dao.get();
    }
}

測試結果:


2019102607.png

2.5 @Autowired注解的requird屬性

在使用@Autowired注解時,首先在容器中查詢對應類型的bean

  1. 如果查詢結果Bean剛好為一個套菜,自動注入
  2. 如果查詢結果Bean不止一個亲善,通過@Qualifier注解指定自動裝配Bean的名稱
  3. 如果沒有查詢到對應類型的Bean,由于默認@Autowired(required=true)笼踩,會拋出異常逗爹,解決方法是使用@Autoiwired(quired=false)
  4. @Autowired(quired=true)意味著依賴是必須的
  5. @Autowired(quired=false)等于告訴 Spring:在找不到匹配 Bean 時也不報錯

數(shù)據(jù)層接口:

package com.example.demo.chapter1.useannotation.autowired.dao;

/**
 * 數(shù)據(jù)層接口
 * */
public interface ITask {
    public String get();
}

業(yè)務層接口:

package com.example.demo.chapter1.useannotation.autowired.service;

@Service("taskServiceImpl")
@Scope("prototype")
public class TaskServiceImpl implements IService {

    @Autowired
    private ITask task;

    @Override
    public String get() {
        return task.get();
    }
}

如果沒有接口ITask的實現(xiàn)類亡嫌,啟動Spring Boot應用會報如下錯:
沒有找到ITask的實現(xiàn)類

Description:

Field task in com.example.demo.chapter1.useannotation.autowired.service.TaskServiceImpl required a bean of type 'com.example.demo.chapter1.useannotation.autowired.dao.ITask' that could not be found.


Action:

Consider defining a bean of type 'com.example.demo.chapter1.useannotation.autowired.dao.ITask' in your configuration.

解決方法 - 添加required=false

@Service("autowiredTaskServiceImpl")
@Scope("prototype")
public class TaskServiceImpl implements IService {

    /**
     * 接口ITask沒有實現(xiàn)類
     * 添加required=false不報錯
     * */
    @Autowired(required=false)
    private ITask task;

    @Override
    public String get() {
        return task.get();
    }
}

>推薦一下我的公眾號: 【geekjc】嚎于,一起學習交流編程知識,分享經(jīng)驗挟冠,各種有趣的事于购,更多精彩內容,掃碼進入小程序知染。

tuiguang.png
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末肋僧,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子控淡,更是在濱河造成了極大的恐慌嫌吠,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,948評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件掺炭,死亡現(xiàn)場離奇詭異辫诅,居然都是意外死亡,警方通過查閱死者的電腦和手機涧狮,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,371評論 3 385
  • 文/潘曉璐 我一進店門炕矮,熙熙樓的掌柜王于貴愁眉苦臉地迎上來么夫,“玉大人,你說我怎么就攤上這事肤视〉祷荆” “怎么了?”我有些...
    開封第一講書人閱讀 157,490評論 0 348
  • 文/不壞的土叔 我叫張陵邢滑,是天一觀的道長腐螟。 經(jīng)常有香客問我,道長困后,這世上最難降的妖魔是什么遭垛? 我笑而不...
    開封第一講書人閱讀 56,521評論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮操灿,結果婚禮上锯仪,老公的妹妹穿的比我還像新娘。我一直安慰自己趾盐,他們只是感情好庶喜,可當我...
    茶點故事閱讀 65,627評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著救鲤,像睡著了一般久窟。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上本缠,一...
    開封第一講書人閱讀 49,842評論 1 290
  • 那天斥扛,我揣著相機與錄音,去河邊找鬼丹锹。 笑死稀颁,一個胖子當著我的面吹牛,可吹牛的內容都是我干的楣黍。 我是一名探鬼主播匾灶,決...
    沈念sama閱讀 38,997評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼租漂!你這毒婦竟也來了阶女?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 37,741評論 0 268
  • 序言:老撾萬榮一對情侶失蹤哩治,失蹤者是張志新(化名)和其女友劉穎秃踩,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體业筏,經(jīng)...
    沈念sama閱讀 44,203評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡憔杨,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,534評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了驾孔。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片芍秆。...
    茶點故事閱讀 38,673評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡惯疙,死狀恐怖,靈堂內的尸體忽然破棺而出妖啥,到底是詐尸還是另有隱情霉颠,我是刑警寧澤,帶...
    沈念sama閱讀 34,339評論 4 330
  • 正文 年R本政府宣布荆虱,位于F島的核電站蒿偎,受9級特大地震影響,放射性物質發(fā)生泄漏怀读。R本人自食惡果不足惜诉位,卻給世界環(huán)境...
    茶點故事閱讀 39,955評論 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望菜枷。 院中可真熱鬧苍糠,春花似錦、人聲如沸啤誊。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,770評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽蚊锹。三九已至瞳筏,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間牡昆,已是汗流浹背姚炕。 一陣腳步聲響...
    開封第一講書人閱讀 32,000評論 1 266
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留丢烘,地道東北人柱宦。 一個月前我還...
    沈念sama閱讀 46,394評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像铅协,于是被迫代替她去往敵國和親捷沸。 傳聞我的和親對象是個殘疾皇子摊沉,可洞房花燭夜當晚...
    茶點故事閱讀 43,562評論 2 349

推薦閱讀更多精彩內容