spring注解驅動系列--自動裝配

Spring利用依賴注入(DI),完成對IOC容器中中各個組件的依賴關系賦值;依賴注入是spring ioc的具體體現,主要是通過各種注解進行屬性的自動注入。

一、@Autowired:自動注入

一、注解介紹

1、默認優先按照類型去容器中找對應的組件;
2、如果找到多個相同類型的組件,再將屬性的名稱作為組件的id去容器中查找
3、@Qualifier("bookDao"):使用@Qualifier指定需要裝配的組件的id,而不是使用屬性名
4、自動裝配默認一定要將屬性賦值好,沒有就會報錯;
? ? ? 可以使用@Autowired(required=false);
5、@Primary:讓Spring進行自動裝配的時候,默認使用首選的bean;
? ? 也可以繼續使用@Qualifier指定需要裝配的bean的名字
?? ? ? ? BookService{
?? ? ? ? ? ? ?@Autowired
?? ? ? ? ? ? ?BookDao ?bookDao;
?? ? ? ? }

二、AutowiredAnnotationBeanPostProcessor

?@Autowired主要是通過AutowiredAnnotationBeanPostProcessor這個類實現的

三、使用地方?

1、[標注在方法位置]:@Bean+方法參數;參數從容器中獲取;默認不寫@Autowired效果是一樣的;都能自動裝配
2、[標在構造器上]:如果組件只有一個有參構造器,這個有參構造器的@Autowired可以省略,參數位置的組件還是可以自動從容器中獲取
3、放在參數位置

/*** @Bean標注的方法創建對象的時候,方法參數的值從容器中獲取* @param car* @return*/@Beanpublic Color color(Car car){Color color = new Color();color.setCar(car);return color;}

二、@Resource(JSR250)和@Inject(JSR330)

Spring還支持使用@Resource(JSR250)和@Inject(JSR330)[java規范的注解]?

一、@Resource:

可以和@Autowired一樣實現自動裝配功能;默認是按照組件名稱進行裝配的;
不支持@Primary功能也沒有@Autowired(reqiured=false)這種功能;?

二、@Inject:

?需要導入javax.inject的包,和Autowired的功能一樣。沒有required=false的功能;?

注意:@Autowired:Spring定義的; @Resource、@Inject都是java規范?

三、自定義組件

一、自定義組件想要使用Spring容器底層的一些組件

自定義組件想要使用Spring容器底層的一些組件,例如:想要獲取底層ApplicationContext(IOC)組件,BeanFactory等等。可以自定義實現xxxAware接口,在創建對象的時候,會調用接口規定的方法注入相關組件?;把Spring底層一些組件注入到自定義的Bean中。一般xxxAware接口功能都是使用xxxProcessor實現;

例如:ApplicationContextAware==》ApplicationContextAwareProcessor;

?ApplicationContextAware接口只有一個方法

public interface ApplicationContextAware extends Aware { void setApplicationContext(ApplicationContext var1) throws BeansException;

}

而ApplicationContextAwareProcessor是實現BeanPostProcessor接口里面的方法(后置處理器)

public interface BeanPostProcessor {@Nullabledefault Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {return bean;}@Nullabledefault Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {return bean;}
}

然后ApplicationContextAwareProcessor會在對象初始化前調用postProcessBeforeInitialization將ApplicationContext設置進實現?ApplicationContextAware接口的對象的setApplicationContext方法中,然后我們想要使用的時候,只需要將ApplicationContext對象保存在當前對象中即可,具體栗子如下:

/**
實現對應的xxxAware,然后實現對應的方法,
例如:ApplicationContextAware,當red對象生成后,ApplicationContextAwareProcessor還在初始化
前將ApplicationContext 傳入到setApplicationContext這個方法中,然后red方法會保存在當前屬性中,
在red對象中,寫對應的業務邏輯是如果需要獲取容器中的對象可以通過ApplicationContext 進行獲取。
**/
@Component
public class Red implements ApplicationContextAware,BeanNameAware,EmbeddedValueResolverAware {private ApplicationContext applicationContext;@Overridepublic void setApplicationContext(ApplicationContext applicationContext) throws BeansException {// TODO Auto-generated method stubSystem.out.println("傳入的ioc:"+applicationContext);this.applicationContext = applicationContext;}@Overridepublic void setBeanName(String name) {// TODO Auto-generated method stubSystem.out.println("當前bean的名字:"+name);}@Overridepublic void setEmbeddedValueResolver(StringValueResolver resolver) {// TODO Auto-generated method stubString resolveStringValue = resolver.resolveStringValue("你好 ${os.name} 我是 #{20*18}");System.out.println("解析的字符串:"+resolveStringValue);}}

?二、ApplicationContextAware接口實現原理,源碼展示


class ApplicationContextAwareProcessor implements BeanPostProcessor {private final ConfigurableApplicationContext applicationContext;private final StringValueResolver embeddedValueResolver;public ApplicationContextAwareProcessor(ConfigurableApplicationContext applicationContext) {this.applicationContext = applicationContext;this.embeddedValueResolver = new EmbeddedValueResolver(applicationContext.getBeanFactory());}@Nullablepublic Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {AccessControlContext acc = null;// 判斷red實現的是哪一個接口if (System.getSecurityManager() != null && (bean instanceof EnvironmentAware || bean instanceof EmbeddedValueResolverAware || bean instanceof ResourceLoaderAware || bean instanceof ApplicationEventPublisherAware || bean instanceof MessageSourceAware || bean instanceof ApplicationContextAware)) {acc = this.applicationContext.getBeanFactory().getAccessControlContext();}if (acc != null) {// 權限檢查,如:判斷能不能夠訪問對應的方法 AccessController.doPrivileged(() -> {this.invokeAwareInterfaces(bean);return null;}, acc);} else {// 主要是調用這個方法this.invokeAwareInterfaces(bean);}return bean;}/**主要是匹配對應實現的接口,例如:匹配到ApplicationContextAware,會調用setApplicationContext將applicationContext設置進實現接口的對象方法中**/private void invokeAwareInterfaces(Object bean) {if (bean instanceof Aware) {if (bean instanceof EnvironmentAware) {((EnvironmentAware)bean).setEnvironment(this.applicationContext.getEnvironment());}if (bean instanceof EmbeddedValueResolverAware) {((EmbeddedValueResolverAware)bean).setEmbeddedValueResolver(this.embeddedValueResolver);}if (bean instanceof ResourceLoaderAware) {((ResourceLoaderAware)bean).setResourceLoader(this.applicationContext);}if (bean instanceof ApplicationEventPublisherAware) {((ApplicationEventPublisherAware)bean).setApplicationEventPublisher(this.applicationContext);}if (bean instanceof MessageSourceAware) {((MessageSourceAware)bean).setMessageSource(this.applicationContext);}if (bean instanceof ApplicationContextAware) {((ApplicationContextAware)bean).setApplicationContext(this.applicationContext);}}}public Object postProcessAfterInitialization(Object bean, String beanName) {return bean;}
}

四、Profile

Spring為我們提供的可以根據當前環境,動態的激活和切換一系列組件的功能。

@Profile:指定組件在哪個環境的情況下才能被注冊到容器中,不指定,任何環境下都能注冊這個組件

1、加了環境標識的bean,只有這個環境被激活的時候才能注冊到容器中。默認是default環境

2、寫在配置類上,只有是指定的環境的時候,整個配置類里面的所有配置才能開始生效

3、沒有標注環境標識的bean在,任何環境下都是加載的;

栗子:

@Profile("prod")

@Profile("dev")

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/718570.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/718570.shtml
英文地址,請注明出處:http://en.pswp.cn/news/718570.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

高中數學:函數奇偶性

一、定義 偶函數:定義域關于原點對稱,圖像關于Y軸對稱 f(x)f(-x) 奇函數:定義域關于原點對稱,圖像關于原點中心對稱 f(x)f(-x)0 等價于 f(-x)-f(x) 二、函數奇偶性的四種情況 注意: 即奇又偶的函數,只有…

Linux入門到入土

Linxu Linux 簡介 Linux 內核最初只是由芬蘭人林納斯托瓦茲(Linus Torvalds)在赫爾辛基大學上學時出于個人愛好而編寫的。 Linux 是一套免費使用和自由傳播的類 Unix 操作系統,是一個基于 POSIX(可移植操作系統接口&#xff09…

【復現】宏景HCM 任意文件讀取漏洞_63

目錄 一.概述 二 .漏洞影響 三.漏洞復現 1. 漏洞一: 四.修復建議: 五. 搜索語法: 六.免責聲明 一.概述 宏景HCM 將人才標簽技術應用于員工招聘、人才選拔等環節,通過多維度的標簽體系,形成不同專業序列的人才畫…

CV | 醫學影像上的圖像分割模型調研【更新于20240304】

mamba相關的圖像分割:VM-Unet,Manba-Unet,BRAU-Net,MDD-Unet,EGE-Unet,U-Mamba 2024.01.01_BRAU-Net Paper:BRAU-Net: U-Shaped Hybrid CNN-Transformer Network for Medical Image Segmentation https://arxiv.org/pdf/2401.00722.pdf 2024.01.09_U-Mamba Paper:U…

猴子吃桃問題(python版)

文章預覽: 題目python解法一:運行結果 python解法二:運行結果 python解法三:運行結果 題目 猴子吃桃問題:猴子第一天摘下若干個桃子,當即吃了一半,還不過癮,又多吃了一個。 第二天早…

python 腳本設置輸出顏色

在Python腳本中設置輸出顏色,通常可以使用colorama庫,它可以在Windows、Linux和macOS等平臺上工作。colorama庫擴展了Python的標準庫,使得在控制臺輸出彩色文本更加簡單。 首先,你需要安裝colorama庫。如果你還沒有安裝&#xff…

數據倉庫 vs. 數據湖:解析兩者的區別與優劣

在當今數字化時代,數據成為了企業最寶貴的資產之一。為了更好地管理和利用數據,企業需要建立合適的數據存儲和管理系統。在這個過程中,數據倉庫和數據湖成為了兩種常見的選擇。雖然它們都旨在幫助企業管理數據,但在實際應用中&…

flurl升級之后沒有FlurlNewtonsoftJsonSerializer

新建NewtonsoftJsonSerializer.cs /// <summary> /// ISerializer implementation based on Newtonsoft.Json. /// Default serializer used in calls to GetJsonAsync, PostJsonAsync, etc. /// </summary> public class NewtonsoftJsonSerializer : IJsonSerial…

Qt 簡約美觀的加載動畫 第九季

這次和大家分享6個非常清爽的加載動畫. &#x1f60a; 效果如下 &#x1f60a; 一共三個文件 , 可以直接編譯運行的呢 //main.cpp #include "LoadingAnimWidget.h" #include <QApplication> #include <QGridLayout> int main(int argc, char *argv[]) …

原理篇-- 定時任務xxl-job-服務端(admin)項目啟動過程--JobTriggerPoolHelper 初始化 (3)

文章目錄 前言一、JobTriggerPoolHelper 作用&#xff1a;二、JobTriggerPoolHelper 源碼介紹&#xff1a;2.1. start() 方法&#xff1a;2.2 任務觸發&#xff1a;2.3 XxlJobTrigger.trigger 任務執行&#xff1a;2.4 processTrigger 任務的執行&#xff1a;2.5 runExecutor 任…

【JAVA重要知識 | 第三篇】深入理解并暴打AQS原理、ReentrantLock鎖

文章目錄 3.深入理解AQS、ReentrantLock3.1AQS3.1.1AQS簡介3.1.2核心結構&#xff08;1&#xff09;設計模型&#xff08;2&#xff09;組成部分&#xff08;3&#xff09;State關鍵字 3.1.3實現的兩類隊列&#xff08;1&#xff09;同步隊列①CLH②Node③主要行為 img條件隊列…

中霖教育:注冊安全工程師考是科目有哪些?

注冊安全工程師的類型是職業資格證書&#xff0c;需要滿足報名條件才能參加考試&#xff0c;考試通過就能發放證書。報名時間一般在八月份&#xff0c;考試時間在十月底左右。 考試科目&#xff1a; 《安全生產法律法規》 《安全生產管理》 《安全生產技術基礎》 《安全生…

golang實現openssl自簽名雙向認證

第一步&#xff1a;生成CA、服務端、客戶端證書 1. 生成CA根證書 生成CA證書私鑰 openssl genrsa -out ca.key 4096創建ca.conf 文件 [ req ] default_bits 4096 distinguished_name req_distinguished_name[ req_distinguished_name ] countryName …

Node.js基礎---Express路由

1. 路由的概念 1. 什么是路由 廣義上來講&#xff0c;路由就是映射關系 2. Express 中的路由 在 Express 中&#xff0c;路由指的是客戶端的請求與服務器處理函數之間的映射關系 Express 中的路由分三部分&#xff1a;請求的類型、請求的URL地址&#xff0c;處理函數。如下&am…

怎么使用curl2py自動構造爬蟲代碼并進行網絡爬蟲

目錄 一、了解curl2py 二、安裝curl2py 三、使用curl2py生成爬蟲代碼 四、實際案例&#xff1a;爬取網頁數據 五、總結與建議 在當今數據驅動的時代&#xff0c;網絡爬蟲成為了獲取數據的重要工具。對于初學者來說&#xff0c;手動編寫爬蟲代碼可能是一項挑戰。幸運的是&a…

PyTorch-神經網絡

神經網絡&#xff0c;這也是深度學習的基石&#xff0c;所謂的深度學習&#xff0c;也可以理解為很深層的神經網絡。說起這里&#xff0c;有一個小段子&#xff0c;神經網絡曾經被打入了冷宮&#xff0c;因為SVM派的崛起&#xff0c;SVM不了解的同學可以去google一下&#xff0…

JavaScript 基礎學習筆記(五):函數、作用域、匿名函數

目錄 一、函數 1.1 聲明和調用 1.2 形參和實參 1.3 返回值 二、作用域 2.1 全局作用域 2.2 局部作用域 三、匿名函數 3.1 函數表達式 3.2 立即執行函數 一、函數 理解函數的封裝特性&#xff0c;掌握函數的語法規則 1.1 聲明和調用 函數可以把具有相同或相似邏輯的代…

NLP_文本張量表示方法(代碼示例)

目標 了解什么是文本張量表示及其作用.文本張量表示的幾種方法及其實現. 1 文本張量表示 將一段文本使用張量進行表示&#xff0c;其中一般將詞匯為表示成向量&#xff0c;稱作詞向量&#xff0c;再由各個詞向量按順序組成矩陣形成文本表示. ["人生", "該&q…

無極低碼:五分鐘快速上手,開啟編程新時代

無極低碼平臺憑借其革命性的設計理念和強大的功能特性&#xff0c;正在徹底改變軟件開發的傳統格局。該平臺專為開發者、初創企業和各類研發團隊量身打造&#xff0c;旨在提供一種快速而高效的解決方案&#xff0c;以應對日益增長的業務需求和技術挑戰。 1.無極低碼的核心價值在…

2024《》

vue-cli到哪做了那些事 vue-cli是vue.js的腳手架&#xff0c;用于自動生成vue.jswebpack的項目模板&#xff0c;快速搭建Vue.js項目。 vue cli內置了webpack的一些功能&#xff0c;這些是用webpack打包時需要我們自己配置的&#xff0c;例如&#xff1a; 1.ES6代碼轉換成ES5代…