SpringBoot中@Autowired生效方式详解

网友投稿 334 2022-07-22


目录前言正文注册AutowiredProcessor的BeanDefinition实例化AutowiredProcessor创建bean时进行注入后记

前言

@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 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.

finishaLTjABeanFactoryInitialization(beanFactory);

// Last step: publish correspondihttp://ng event.

finishRefresh()

//...忽略部分代码

}

实际的注册逻辑交给了PostProcessorRegistrationDelegate

protected void registerBeaLTjAanPostProcessors(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 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)

((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 elements = new ArrayList<>();

Class> targetClass = clazz;

do {

final List 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生效逻辑梳理完成


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:Spring详细讲解@Autowired注解
下一篇:springBoot项目集成quartz开发定时任务案例及注意事项
相关文章

 发表评论

暂时没有评论,来抢沙发吧~