Spring注解Autowired的底層實(shí)現(xiàn)原理詳解
一、Autowired注解的用法
1、概述
使用spring開發(fā)時(shí),進(jìn)行配置主要有兩種方式,一是xml的方式,二是java config的方式。
spring技術(shù)自身也在不斷的發(fā)展和改變,從當(dāng)前springboot的火熱程度來(lái)看,java config的應(yīng)用是越來(lái)越廣泛了,在使用java config的過程當(dāng)中,我們不可避免的會(huì)有各種各樣的注解打交道,其中,我們使用最多的注解應(yīng)該就是@Autowired注解了。這個(gè)注解的功能就是為我們注入一個(gè)定義好的bean
2、應(yīng)用
應(yīng)用與構(gòu)造方法注入
應(yīng)用與setter方法注入
應(yīng)用與屬性注入
3、具體用法
@Autowired
替換:autowire屬性,自動(dòng)裝配(按照類型裝配,通過set方法,且方法可以省略)
位置:修飾屬性,set方法
語(yǔ)法:@Autowired(required="true")
注意:
1.如果容器中沒有一個(gè)可以與之匹配且required屬性為true則會(huì)報(bào)異常NoSuchBeanDefinitionException
2.如果容器中有多個(gè)可以類型可以與之匹配,則自動(dòng)切換為按照名稱裝配
3.如果容器中有多個(gè)可以類型可以與之匹配,則自動(dòng)切換為按照名稱裝配,如果名稱也沒有匹配,則報(bào)異常NoUniqueBeanDefinitionException
二、Autowired自動(dòng)裝配的過程
首先要清楚java注解的核心其實(shí)時(shí)反射
1、在Spring源代碼當(dāng)中,Autowired注解位于包org.springframework.beans.factory.annotation之中,該包的內(nèi)容如下:
核心代碼如下
private InjectionMetadata buildAutowiringMetadata(final Class<?> clazz) { LinkedList<InjectionMetadata.InjectedElement> elements = new LinkedList<>(); Class<?> targetClass = clazz;//需要處理的目標(biāo)類 do { final LinkedList<InjectionMetadata.InjectedElement> currElements = new LinkedList<>(); /*通過反射獲取該類所有的字段,并遍歷每一個(gè)字段,并通過方法findAutowiredAnnotation遍歷每一個(gè)字段的所用注解,并如果用autowired修飾了,則返回auotowired相關(guān)屬性*/ ReflectionUtils.doWithLocalFields(targetClass, field -> { AnnotationAttributes ann = findAutowiredAnnotation(field); if (ann != null) {//校驗(yàn)autowired注解是否用在了static方法上 if (Modifier.isStatic(field.getModifiers())) { if (logger.isWarnEnabled()) { logger.warn("Autowired annotation is not supported on static fields: " + field); } return; }//判斷是否指定了required boolean required = determineRequiredStatus(ann); currElements.add(new AutowiredFieldElement(field, required)); } }); //和上面一樣的邏輯,但是是通過反射處理類的method ReflectionUtils.doWithLocalMethods(targetClass, method -> { Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(method); if (!BridgeMethodResolver.isVisibilityBridgeMethodPair(method, bridgedMethod)) { return; } AnnotationAttributes ann = findAutowiredAnnotation(bridgedMethod); if (ann != null && method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) { if (Modifier.isStatic(method.getModifiers())) { if (logger.isWarnEnabled()) { logger.warn("Autowired annotation is not supported on static methods: " + method); } return; } if (method.getParameterCount() == 0) { if (logger.isWarnEnabled()) { logger.warn("Autowired annotation should only be used on methods with parameters: " + method); } } boolean required = determineRequiredStatus(ann); PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz); currElements.add(new AutowiredMethodElement(method, required, pd)); } }); //用@Autowired修飾的注解可能不止一個(gè),因此都加在currElements這個(gè)容器里面,一起處理 elements.addAll(0, currElements); targetClass = targetClass.getSuperclass(); } while (targetClass != null && targetClass != Object.class); return new InjectionMetadata(clazz, elements); }
總結(jié):
Spring對(duì)@autowired注解的實(shí)現(xiàn)邏輯位于類:AutowiredAnnotationBeanPostProcessor(后置處理器)。@Autowied的本質(zhì)就是new對(duì)象,因?yàn)閟pring的核心思想就是IOC,只是將控制權(quán)反轉(zhuǎn)給了Spring框架,由它在底層通過注解或者配置文件幫我們new對(duì)象。
到此這篇關(guān)于Spring注解Autowired的底層實(shí)現(xiàn)原理詳解的文章就介紹到這了,更多相關(guān)Spring注解Autowired內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
SpringBoot加入Guava Cache實(shí)現(xiàn)本地緩存代碼實(shí)例
這篇文章主要介紹了SpringBoot加入Guava Cache實(shí)現(xiàn)本地緩存代碼實(shí)例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-09-09淺談Java中隨機(jī)數(shù)的幾種實(shí)現(xiàn)方式
這篇文章主要介紹了Java中隨機(jī)數(shù)的幾種實(shí)現(xiàn)方式,從最簡(jiǎn)單的Math.random到多線程的并發(fā)實(shí)現(xiàn)都在本文所列之中,需要的朋友可以參考下2015-07-07詳解Java動(dòng)態(tài)代理的實(shí)現(xiàn)機(jī)制
這篇文章主要為大家詳細(xì)介紹了Java動(dòng)態(tài)代理的實(shí)現(xiàn)機(jī)制,感興趣的小伙伴們可以參考一下2016-03-03spring data jpa開啟批量插入、批量更新的問題解析
這篇文章主要介紹了spring data jpa開啟批量插入、批量更新問題,本文通過圖文實(shí)例相結(jié)合給大家介紹的非常詳細(xì),需要的朋友可以參考下2021-07-07java 實(shí)現(xiàn)計(jì)數(shù)排序和桶排序?qū)嵗a
這篇文章主要介紹了java 實(shí)現(xiàn)計(jì)數(shù)排序和桶排序?qū)嵗a的相關(guān)資料,需要的朋友可以參考下2017-02-02