Spring|Spring @Autowired注解自动装配过程
BeanPostProcessor 【Spring|Spring @Autowired注解自动装配过程】在开始之前先介绍一下BeanPostProcessor(后置处理器)BeanPostProcessor接口作用是:在Spring容器完成Bean的实例化、配置和其他的初始化前后添加一些自己的逻辑处理。
方法 | 说明 |
---|---|
postProcessBeforeInitialization | 实例化、依赖注入完毕,在调用显示的初始化之前完成一些定制的初始化任务 |
postProcessAfterInitialization | 实例化、依赖注入、初始化完毕时执行 |
方法 | 说明 |
---|---|
instantiate bean | 实例化 bean |
populate bean | 为 bean 设置 property 参数 |
initialize bean | 初始化 bean(对创建好的 bean 做一些修饰动作) |
文章图片
现在开始讲解自动装配的流程
第一步:创建bean
类 | 方法 | 说明 |
---|---|---|
AbstractBeanFactory | doGetBean | 先从缓存中寻找是否存在对应bean,没有则创建 |
DefaultSingletonBeanRegistry | getSingleton | 查询是否有对应的单例bean,没有则创建 |
AbstractAutowireCapableBeanFactory | createBean | 向下调用创建bean |
AbstractAutowireCapableBeanFactory | doCreateBean | 实例化、填充属性 |
AbstractAutowireCapableBeanFactory | createBeanInstance | 向下调用创建bean |
AbstractAutowireCapableBeanFactory | applyMergedBeanDefinitionPostProcessors | 合并bean的处理信息 |
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException {
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
//尝试从缓存中
instanceWrapper = (BeanWrapper)this.factoryBeanInstanceCache.remove(beanName);
}
//如果缓存中没有,则根据对应的策略创建bean(RootBeanDefinition)
//使用其构造函数 constructor 使用Java 反射实例化了 bean
if (instanceWrapper == null) {
instanceWrapper = this.createBeanInstance(beanName, mbd, args);
}
----省略一部分代码----
synchronized(mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
//第一大步
//调用MergedBeanDefinitionPostProcessor 后处理器,合并bean的定义信息
//Autowire等注解信息就是在这一步完成预解析,并且将注解需要的信息放入缓存
this.applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
} catch (Throwable var17) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Post-processing of merged bean definition failed", var17);
}
mbd.postProcessed = true;
}
}
----省略一部分代码----
try {
// 对bean属性进行填充,注入bean中的属性,会递归初始化依赖的bean
this.populateBean(beanName, mbd, instanceWrapper);
exposedObject = this.initializeBean(beanName, exposedObject, mbd);
} catch (Throwable var18) {
if (var18 instanceof BeanCreationException && beanName.equals(((BeanCreationException)var18).getBeanName())) {
throw (BeanCreationException)var18;
}throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Initialization of bean failed", var18);
}
----省略一部分代码----
- 第一步 缓存中是否存在bean,若不存在,则根据策略创建bean
- 第二步 调用MergedBeanDefinitionPostProcessor,预解析@autowired注解的类
- 第三步 将所有属性都注入到创建的bean中
再看用于预解析的applyMergedBeanDefinitionPostProcessors方法
protected void applyMergedBeanDefinitionPostProcessors(RootBeanDefinition mbd, Class> beanType, String beanName) {
Iterator var4 = this.getBeanPostProcessors().iterator();
//循环调用MergedBeanDefinitionPostProcessor接口的类的postProcessMergedBeanDefinition方法
while(var4.hasNext()) {
BeanPostProcessor bp = (BeanPostProcessor)var4.next();
if (bp instanceof MergedBeanDefinitionPostProcessor) {
MergedBeanDefinitionPostProcessor bdp = (MergedBeanDefinitionPostProcessor)bp;
bdp.postProcessMergedBeanDefinition(mbd, beanType, beanName);
}
}
}
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class> beanType, String beanName) {
InjectionMetadata metadata = https://www.it610.com/article/this.findAutowiringMetadata(beanName, beanType, (PropertyValues)null);
metadata.checkConfigMembers(beanDefinition);
}
首先findAutowiringMetadata就是查询构建autowire元数据
private InjectionMetadata findAutowiringMetadata(String beanName, Class> clazz, @Nullable PropertyValues pvs) {
String cacheKey = StringUtils.hasLength(beanName)?beanName:clazz.getName();
InjectionMetadata metadata = https://www.it610.com/article/(InjectionMetadata)this.injectionMetadataCache.get(cacheKey);
if(InjectionMetadata.needsRefresh(metadata, clazz)) {
Map var6 = this.injectionMetadataCache;
synchronized(this.injectionMetadataCache) {
metadata = (InjectionMetadata)this.injectionMetadataCache.get(cacheKey);
if(InjectionMetadata.needsRefresh(metadata, clazz)) {
if(metadata != null) {
metadata.clear(pvs);
}
//构建Autowired元数据
metadata = this.buildAutowiringMetadata(clazz);
this.injectionMetadataCache.put(cacheKey, metadata);
}
}
}
return metadata;
}
private InjectionMetadata buildAutowiringMetadata(Class> clazz) {
ArrayList elements = new ArrayList();
Class targetClass = clazz;
do {
ArrayList currElements = new ArrayList();
//遍历这个类的所有的field去寻找又Autowired修饰的field
ReflectionUtils.doWithLocalFields(targetClass, (field) -> {
AnnotationAttributes ann = this.findAutowiredAnnotation(field);
if(ann != null) {
//如果这个field是静态static的就警告并停止
if(Modifier.isStatic(field.getModifiers())) {
if(this.logger.isWarnEnabled()) {
this.logger.warn("Autowired annotation is not supported on static fields: " + field);
}
return;
}
//这里就取了Autowired的一个required属性,这个属性的作用是
//如果这个是false就表明在自动装配的时候没有发现又对应的实例
//就跳过去,如果是true没有发现有与之匹配的就会抛出个异常,仅此而已
boolean required = this.determineRequiredStatus(ann);
currElements.add(new AutowiredAnnotationBeanPostProcessor.AutowiredFieldElement(field, required));
}
});
//接着是遍历这个类里面的方法
ReflectionUtils.doWithLocalMethods(targetClass, (method) -> {
Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(method);
if(BridgeMethodResolver.isVisibilityBridgeMethodPair(method, bridgedMethod)) {
AnnotationAttributes ann = this.findAutowiredAnnotation(bridgedMethod);
//同样的静态方法不能自动装配
if(ann != null && method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) {
if(Modifier.isStatic(method.getModifiers())) {
if(this.logger.isWarnEnabled()) {
this.logger.warn("Autowired annotation is not supported on static methods: " + method);
}
return;
}
if(method.getParameterCount() == 0 && this.logger.isWarnEnabled()) {
this.logger.warn("Autowired annotation should only be used on methods with parameters: " + method);
}
boolean required = this.determineRequiredStatus(ann);
PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz);
currElements.add(new AutowiredAnnotationBeanPostProcessor.AutowiredMethodElement(method, required, pd));
}
}
});
elements.addAll(0, currElements);
targetClass = targetClass.getSuperclass();
} while(targetClass != null && targetClass != Object.class);
return new InjectionMetadata(clazz, elements);
}
- 第一步 将标记@Autowired的字段封装为AutowiredFieldElement对象。
- 第二步 将标记@Autowired的方法并且此方法是字段的getter或setter方法封装到AutowiredMethodElement对象
public void checkConfigMembers(RootBeanDefinition beanDefinition) {
LinkedHashSet checkedElements = new LinkedHashSet(this.injectedElements.size());
//injectedElements这个集合就是类里面所有被Autowired修饰过的field或method
Iterator var3 = this.injectedElements.iterator();
//遍历这个集合
//把method或者field放入externallyManagedConfigMembers缓存中
while(var3.hasNext()) {
InjectionMetadata.InjectedElement element = (InjectionMetadata.InjectedElement)var3.next();
Member member = element.getMember();
if(!beanDefinition.isExternallyManagedConfigMember(member)) {
beanDefinition.registerExternallyManagedConfigMember(member);
checkedElements.add(element);
if(logger.isDebugEnabled()) {
logger.debug("Registered injected element on class [" + this.targetClass.getName() + "]: " + element);
}
}
}
this.checkedElements = checkedElements;
}
整个postProcessMergedBeanDefinition的工作就此完成,总结一下就是扫描类中被@autowired注释并且非static的字段域或方法,并且存放到内存中
接下来就要开始属性注入了
即doCreateBean中的populateBean方法
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
//如果实例为空但是还有属性,抛出异常
if(bw == null) {
if(mbd.hasPropertyValues()) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
}
} else {
boolean continueWithPropertyPopulation = true;
//这边主要是根据InstantiationAwareBeanPostProcessor 判断是否继续给该bean配置属性
if(!mbd.isSynthetic() && this.hasInstantiationAwareBeanPostProcessors()) {
Iterator pvs = this.getBeanPostProcessors().iterator();
while(pvs.hasNext()) {
BeanPostProcessor hasInstAwareBpps = (BeanPostProcessor)pvs.next();
if(hasInstAwareBpps instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor needsDepCheck = (InstantiationAwareBeanPostProcessor)hasInstAwareBpps;
if(!needsDepCheck.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
continueWithPropertyPopulation = false;
break;
}
}
}
}
if(continueWithPropertyPopulation) {
Object pvs1 = mbd.hasPropertyValues()?mbd.getPropertyValues():null;
//判断如果是按照名字或者类型注入的就进入这条分支
if(mbd.getResolvedAutowireMode() == 1 || mbd.getResolvedAutowireMode() == 2) {
MutablePropertyValues hasInstAwareBpps1 = new MutablePropertyValues((PropertyValues)pvs1);
if(mbd.getResolvedAutowireMode() == 1) {
this.autowireByName(beanName, mbd, bw, hasInstAwareBpps1);
}
if(mbd.getResolvedAutowireMode() == 2) {
this.autowireByType(beanName, mbd, bw, hasInstAwareBpps1);
}
pvs1 = hasInstAwareBpps1;
}
boolean hasInstAwareBpps2 = this.hasInstantiationAwareBeanPostProcessors();
boolean needsDepCheck1 = mbd.getDependencyCheck() != 0;
if(hasInstAwareBpps2 || needsDepCheck1) {
if(pvs1 == null) {
pvs1 = mbd.getPropertyValues();
}
PropertyDescriptor[] filteredPds = this.filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
if(hasInstAwareBpps2) {
Iterator var9 = this.getBeanPostProcessors().iterator();
while(var9.hasNext()) {
BeanPostProcessor bp = (BeanPostProcessor)var9.next();
//这里循环调用了InstantiationAwareBeanPostProcessor实现类的postProcessPropertyValues
//方法,我们Autowire注解解析类AutowiredAnnotationBeanPostProcessor也是该接口的实现类
if(bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor)bp;
pvs1 = ibp.postProcessPropertyValues((PropertyValues)pvs1, filteredPds, bw.getWrappedInstance(), beanName);
if(pvs1 == null) {
return;
}
}
}
}
if(needsDepCheck1) {
this.checkDependencies(beanName, mbd, filteredPds, (PropertyValues)pvs1);
}
}
if(pvs1 != null) {
this.applyPropertyValues(beanName, mbd, bw, (PropertyValues)pvs1);
}
}
}
}
最后做个总结 总的来说 IOC自动装配分为三步
第一步:实例化bean
第二步:填充属性参数
第三步:初始化bean
参考博客:
https://blog.csdn.net/nuomizhende45/article/details/84960303
https://www.shangyang.me/2017/04/01/spring-core-container-sourcecode-analysis-beans-instantiating-process/
https://www.shangyang.me/2017/04/05/spring-core-container-sourcecode-analysis-annotation-autowired/
推荐阅读
- Activiti(一)SpringBoot2集成Activiti6
- SpringBoot调用公共模块的自定义注解失效的解决
- 解决SpringBoot引用别的模块无法注入的问题
- 2018-07-09|2018-07-09 Spring 的DBCP,c3p0
- spring|spring boot项目启动websocket
- 生活与游戏日记(第182篇)(〔成长瞬间〕关注解决问题2019.10)
- Spring|Spring Boot 整合 Activiti6.0.0
- Spring集成|Spring集成 Mina
- springboot使用redis缓存
- Spring|Spring 框架之 AOP 原理剖析已经出炉!!!预定的童鞋可以识别下发二维码去看了