Spring?Boot?@Autowired?@Resource屬性賦值時(shí)機(jī)探究
@Resource
先貼出測試類
@Service
public class TransactionServiceTest {
@Resource
private IQrcodeAdScheduleService qrcodeAdScheduleService;
}Spring Boot啟動(dòng)之后調(diào)用棧信息

圖1

圖2
由圖1,圖2可知InjectionMetadata.inject()執(zhí)行屬性織入邏輯,下面是部分細(xì)節(jié)
protected void inject(Object target, @Nullable String requestingBeanName, @Nullable PropertyValues pvs)
throws Throwable {
if (this.isField) {
Field field = (Field) this.member;
ReflectionUtils.makeAccessible(field);
//通過反射對目標(biāo)target對象也就是我們之前定義的TransactionServiceTest的屬性賦值
field.set(target, getResourceToInject(target, requestingBeanName));
}
}其中,CommonAnnotationBeanPostProcessor.ResourceElement的member屬性存儲的是Filed信息,對于本示例就是:

圖3
@Autowired
對于@Autowired來說,就是AutowiredAnnotationBeanPostProcessor.AutowiredFieldElement.inject():
protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
Field field = (Field) this.member;
Object value;
if (this.cached) {
value = resolvedCachedArgument(beanName, this.cachedFieldValue);
}
else {
DependencyDescriptor desc = new DependencyDescriptor(field, this.required);
desc.setContainingClass(bean.getClass());
Set<String> autowiredBeanNames = new LinkedHashSet<>(1);
Assert.state(beanFactory != null, "No BeanFactory available");
TypeConverter typeConverter = beanFactory.getTypeConverter();
try {
//遞歸調(diào)用createBean()實(shí)例化目標(biāo)bean的屬性bean實(shí)例
value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);
}
catch (BeansException ex) {
throw new UnsatisfiedDependencyException(null, beanName, new InjectionPoint(field), ex);
}
synchronized (this) {
if (!this.cached) {
if (value != null || this.required) {
this.cachedFieldValue = desc;
registerDependentBeans(beanName, autowiredBeanNames);
if (autowiredBeanNames.size() == 1) {
String autowiredBeanName = autowiredBeanNames.iterator().next();
if (beanFactory.containsBean(autowiredBeanName) &&
beanFactory.isTypeMatch(autowiredBeanName, field.getType())) {
this.cachedFieldValue = new ShortcutDependencyDescriptor(
desc, autowiredBeanName, field.getType());
}
}
}
else {
this.cachedFieldValue = null;
}
this.cached = true;
}
}
}
if (value != null) {
//通過field進(jìn)行賦值
ReflectionUtils.makeAccessible(field);
field.set(bean, value);
}
}
}其他的流程一毛一樣啊~
以上就是Spring Boot @Autowired @Resource屬性賦值時(shí)機(jī)探究的詳細(xì)內(nèi)容,更多關(guān)于SpringBoot @Autowired @Resource的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Java EasyExcel讀寫excel如何解決poi讀取大文件內(nèi)存溢出問題
這篇文章主要介紹了Java EasyExcel讀寫excel如何解決poi讀取大文件內(nèi)存溢出問題,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-06-06
SpringBoot + JPA @ManyToMany的操作要點(diǎn)說明
這篇文章主要介紹了SpringBoot + JPA @ManyToMany的操作要點(diǎn)說明,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-12-12
SpringBoot在項(xiàng)目停止(服務(wù)停止/關(guān)閉退出)之后執(zhí)行的方法
這篇文章主要給大家介紹了SpringBoot在項(xiàng)目停止(服務(wù)停止/關(guān)閉退出)之后執(zhí)行的兩種方法,實(shí)現(xiàn)DisposableBean接口和使用@PreDestroy注解,文中有詳細(xì)的代碼講解,具有一定的參考價(jià)值,需要的朋友可以參考下2023-12-12
Java中控制多線程順序執(zhí)行的六種實(shí)現(xiàn)方案
在多線程編程中,線程的執(zhí)行順序本質(zhì)上是不確定的,由操作系統(tǒng)調(diào)度器決定,但在某些業(yè)務(wù)場景中,我們需要確保線程按照特定順序執(zhí)行,所以本文介紹了Java中控制多線程順序執(zhí)行的六種實(shí)現(xiàn)方案,需要的朋友可以參考下2025-09-09
SpringCloud Ribbon 負(fù)載均衡的實(shí)現(xiàn)
Ribbon是一個(gè)客戶端負(fù)載均衡器,它提供了對HTTP和TCP客戶端的行為的大量控制。這篇文章主要介紹了SpringCloud Ribbon 負(fù)載均衡的實(shí)現(xiàn),感興趣的小伙伴們可以參考一下2019-01-01
詳解Spring boot/Spring 統(tǒng)一錯(cuò)誤處理方案的使用
這篇文章主要介紹了詳解Spring boot/Spring 統(tǒng)一錯(cuò)誤處理方案的使用,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-06-06
java下載指定文件并返回給前端返回流文件的實(shí)現(xiàn)步驟
在Java中我們可以根據(jù)文件地址返回一個(gè)文件流,以便對文件進(jìn)行讀取、寫入等操作,下面這篇文章主要給大家介紹了關(guān)于java下載指定文件并返回給前端返回流文件的實(shí)現(xiàn)步驟,需要的朋友可以參考下2024-03-03
idea中打開項(xiàng)目時(shí)import project和open區(qū)別詳解
本文主要介紹了idea中打開項(xiàng)目時(shí)import project和open區(qū)別詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-06-06

