SpringBoot中@Autowired生效方式詳解
前言
@Component public class SimpleBean3 { @Autowired private SimpleBean simpleBean; }
@Autowired修飾的字段會被容器自動註入.那麼Spring Boot中使如何實現這一功能呢? AutowiredAnnotationBeanPostProcessor!
BeanPostProcessor implementation that autowires annotated fields, setter methods, and arbitrary config methods. Such members to be injected are detected through annotations: by default, Spring's @Autowired and @Value annotations.
Also supports JSR-330's @Inject annotation, if available, as a direct alternative to Spring's own @Autowired.
AutowiredAnnotationBeanPostProcessor(以下簡稱AutowiredProcessor)間接實現瞭InstantiationAwareBeanPostProcessor接口.通過postProcessProperties(…)完成@Autowired的註入,本文將按照下圖流程梳理AutowiredProcessor的生效邏輯.
SpringBoot-autowired.png
正文
註冊AutowiredProcessor的BeanDefinition
SpringApplication#createApplicationContext默認會創建 AnnotationConfigApplicationContext,而AnnotationConfigApplicationContext又會創建AnnotatedBeanDefinitionReader
public AnnotationConfigApplicationContext() { this.reader = new AnnotatedBeanDefinitionReader(this); this.scanner = new ClassPathBeanDefinitionScanner(this); }
AnnotatedBeanDefinitionReader構造時會調用AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry),將AutowiredProcessor的BeanDefinition註冊到容器
public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors( BeanDefinitionRegistry registry, @Nullable Object source) { //忽略部分代碼... if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) { RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class); def.setSource(source); beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)); } //忽略部分代碼... return beanDefs; }
實例化AutowiredProcessor
在AbstractApplicationContext的refresh階段,會註冊並實例化所有的BeanPostProcessor
public void refresh() throws BeansException, IllegalStateException { //...忽略部分代碼 // Allows post-processing of the bean factory in context subclasses. postProcessBeanFactory(beanFactory); // Invoke factory processors registered as beans in the context. invokeBeanFactoryPostProcessors(beanFactory); // ########### 這裡註冊所有的BeanPostProcessor ########## // Register bean processors that intercept bean creation. registerBeanPostProcessors(beanFactory); // Initialize message source for this context. initMessageSource(); // Initialize event multicaster for this context. initApplicationEventMulticaster(); // Initialize other special beans in specific context subclasses. onRefresh(); // Check for listener beans and register them. registerListeners(); // Instantiate all remaining (non-lazy-init) singletons. finishBeanFactoryInitialization(beanFactory); // Last step: publish corresponding event. finishRefresh() //...忽略部分代碼 }
實際的註冊邏輯交給瞭PostProcessorRegistrationDelegate
protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) { PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this); }
在PostProcessorRegistrationDelegate中,獲取到所有的BeanPostProcessor(基於BeanDefinition),並將其分為幾種類型,並按照不同的優先級進行處理化,這塊不是這篇文章的重點,我們隻需要知道在這裡AutowiredProcessor被註冊就可以瞭.
創建bean時進行註入
以SimpleBean3的註入為例, 它是單例的,在AbstractApplicationContext.refresh()的finishBeanFactoryInitialization(beanFactory)時創建.
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) { //...忽略部分代碼 // Instantiate all remaining (non-lazy-init) singletons. beanFactory.preInstantiateSingletons(); }
調用到瞭BeanFactory.preInstantiateSingletons(),走到getBean()邏輯
public void preInstantiateSingletons() throws BeansException { //...忽略部分代碼 List<String> beanNames = new ArrayList<>(this.beanDefinitionNames); // Trigger initialization of all non-lazy singleton beans... for (String beanName : beanNames) { RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName); if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) { if (isFactoryBean(beanName)) { Object bean = getBean(FACTORY_BEAN_PREFIX + beanName); if (bean instanceof FactoryBean) { final FactoryBean<?> factory = (FactoryBean<?>) bean; boolean isEagerInit; if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) { isEagerInit = AccessController.doPrivileged((PrivilegedAction<Boolean>) ((SmartFactoryBean<?>) factory)::isEagerInit, getAccessControlContext()); } else { isEagerInit = (factory instanceof SmartFactoryBean && ((SmartFactoryBean<?>) factory).isEagerInit()); } if (isEagerInit) { getBean(beanName); } } } else { getBean(beanName); } } } //...忽略部分代碼 }
經過一連串的輾轉,最終調用到AbstractAutowireCapableBeanFactory#populateBean
附上調用鏈路
image.png
在populateBean中,會將所有的BeanPostProcessor應用在這個bean上,包括AutowiredProcessor
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) { //...忽略部分代碼 PropertyDescriptor[] filteredPds = null; if (hasInstAwareBpps) { if (pvs == null) { pvs = mbd.getPropertyValues(); } for (BeanPostProcessor bp : getBeanPostProcessors()) { if (bp instanceof InstantiationAwareBeanPostProcessor) { InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp; //###### 調用到postProcessProperties ##### PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName); if (pvsToUse == null) { if (filteredPds == null) { filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching); } pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName); if (pvsToUse == null) { return; } } pvs = pvsToUse; } } } //...忽略部分代碼 }
AutowiredProcessor的postProcessProperties()會進行註入操作,這需要找到註入的元數據(InjectionMetadata)
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) { //### 找到AutowringMetadata ##### InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs); try { // #### 註入 ### metadata.inject(bean, beanName, pvs); } catch (BeanCreationException ex) { throw ex; } catch (Throwable ex) { throw new BeanCreationException(beanName, "Injection of autowired dependencies failed", ex); } return pvs; }
findAutowiringMetadata()又調用到buildAutowiringMetadata(),生成代表可註入元素的InjectMetadata
private InjectionMetadata buildAutowiringMetadata(final Class<?> clazz) { List<InjectionMetadata.InjectedElement> elements = new ArrayList<>(); Class<?> targetClass = clazz; do { final List<InjectionMetadata.InjectedElement> currElements = new ArrayList<>(); ReflectionUtils.doWithLocalFields(targetClass, field -> { //###### 找到帶有可註入註解的字段 AnnotationAttributes ann = findAutowiredAnnotation(field); if (ann != null) { if (Modifier.isStatic(field.getModifiers())) { if (logger.isInfoEnabled()) { logger.info("Autowired annotation is not supported on static fields: " + field); } return; } boolean required = determineRequiredStatus(ann); currElements.add(new AutowiredFieldElement(field, required)); } }); //...忽略部分代碼 }
findAutowiredAnnotation()根據AutowiredProcessor的實例字段autowiredAnnotationTypes,去查看是否匹配,這個字段是在AutowiredProcessor創建時初始化,可以看到支持@Autowired,@Value,@Inject三種類型的註入標識.最終據此完成註入
public AutowiredAnnotationBeanPostProcessor() { this.autowiredAnnotationTypes.add(Autowired.class); this.autowiredAnnotationTypes.add(Value.class); try { this.autowiredAnnotationTypes.add((Class<? extends Annotation>) ClassUtils.forName("javax.inject.Inject", AutowiredAnnotationBeanPostProcessor.class.getClassLoader())); logger.trace("JSR-330 'javax.inject.Inject' annotation found and supported for autowiring"); } catch (ClassNotFoundException ex) { // JSR-330 API not available - simply skip. } }
後記
最後再來梳理一下整個流程.
首先是AutowiredPorcessor的BeanDefinition的註冊
=> 創建ApplicationContext
=> 創建AnnotatedBeanDefinitionReader
=> 註冊BeanDefinition registerAnnotationConfigProcessors
然後是AutowiredProcessor註冊為bean
=> registerBeanPostProcessors
最後是註入
=> 獲取bean getBean()
=> 創建bean doCreateBean()
=>生成bean populateBean()
=> 應用AutowiredProcessor ibp.postProcessProperties()
=> 找到可註入的字段 buildAutowiringMetadata
=> 註入 metadata.inject
至此,@Autowired生效邏輯梳理完成
到此這篇關於SpringBoot中@Autowired生效方式詳解的文章就介紹到這瞭,更多相關SpringBoot @Autowired內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!
推薦閱讀:
- Java Autowired註解深入分析
- Java超詳細分析@Autowired原理
- 關於Spring的@Autowired依賴註入常見錯誤的總結
- Spring @Autowired註解超詳細示例
- Java @Autowired註解底層原理詳細分析