参考资料:
《Spring IoC源码学习:@Autowire 详解》
全系列文章:
《Spring:bean的生命周期与@Autowire(1)》
目录
一、AbstractAutowireCapableBeanFactory#applyMergedBeanDefinitionPostProcessors
二、AutowiredAnnotationBeanPostProcessor#postProcessMergedBeanDefinition
三、InstantiationAwareBeanPostProcessor#postProcessAfterInstantiation
四、AutowiredAnnotationBeanPostProcessor#postProcessPropertyValues
写在开头:本文为学习后的总结,可能有不到位的地方,错误的地方,欢迎各位指正。
前文中我们走完了createBeanInstance的流程,完成了bean的实例化,本文中我们继续走完后续的流程。
一、AbstractAutowireCapableBeanFactory#applyMergedBeanDefinitionPostProcessors
doCreateBean继续往下走,就到了applyMergedBeanDefinitionPostProcessors方法。
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args)
throws BeanCreationException {
// 1、实例化bean
instanceWrapper = createBeanInstance(beanName, mbd, args);
// 2、应用后置处理器MergedBeanDefinitionPostProcessor,允许修改MergedBeanDefinition
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
}
调用applyMergedBeanDefinitionPostProcessors方法,遍历MergedBeanDefinitionPostProcessor接口的实现类,调用postProcessMergedBeanDefinition方法。
protected void applyMergedBeanDefinitionPostProcessors(RootBeanDefinition mbd, Class<?> beanType, String beanName) {
// 1.获取BeanFactory中已注册的BeanPostProcessor
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof MergedBeanDefinitionPostProcessor) {
// 2.调用MergedBeanDefinitionPostProcessor的postProcessMergedBeanDefinition方法,
// 对指定bean的给定MergedBeanDefinition进行后置处理,@Autowire注解在这边对元数据进行预解析
MergedBeanDefinitionPostProcessor bdp = (MergedBeanDefinitionPostProcessor) bp;
bdp.postProcessMergedBeanDefinition(mbd, beanType, beanName);
}
}
}
前文中我们了解到,AutowiredAnnotationBeanPostProcessor也是接口的实现类,因此这里也会调用该类的方法。
二、AutowiredAnnotationBeanPostProcessor#postProcessMergedBeanDefinition
@Override
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
if (beanType != null) {
// 1.在指定Bean中查找使用@Autowire注解的元数据
InjectionMetadata metadata = findAutowiringMetadata(beanName, beanType, null);
// 2.检查元数据中的注解信息
metadata.checkConfigMembers(beanDefinition);
}
}
1、findAutowiringMetadata
findAutowiringMetadata方法会查找当前bean的InjectionMetadata缓存,如果没有,则调用buildAutowiringMetadata方法生成。
private InjectionMetadata findAutowiringMetadata(String beanName, Class<?> clazz, PropertyValues pvs) {
// Fall back to class name as cache key, for backwards compatibility with custom callers.
// 1.设置cacheKey的值(beanName 或者 className)
String cacheKey = (StringUtils.hasLength(beanName) ? beanName : clazz.getName());
// Quick check on the concurrent map first, with minimal locking.
// 2.检查beanName对应的InjectionMetadata是否已经存在于缓存中
InjectionMetadata metadata = this.injectionMetadataCache.get(cacheKey);
// 3.检查InjectionMetadata是否需要刷新(为空或者class变了)
if (InjectionMetadata.needsRefresh(metadata, clazz)) {
synchronized (this.injectionMetadataCache) {
// 4.加锁后,再次从缓存中获取beanName对应的InjectionMetadata
metadata = this.injectionMetadataCache.get(cacheKey);
// 5.加锁后,再次检查InjectionMetadata是否需要刷新
if (InjectionMetadata.needsRefresh(metadata, clazz)) {
if (metadata != null) {
// 6.如果需要刷新,并且metadata不为空,则先移除
metadata.clear(pvs);
}
try {
// 7.解析@Autowired注解的信息,生成元数据(包含clazz和clazz里解析到的注入的元素,
// 这里的元素包括AutowiredFieldElement和AutowiredMethodElement)
metadata = buildAutowiringMetadata(clazz);
// 8.将解析的元数据放到injectionMetadataCache缓存,以备复用,每一个类只解析一次
this.injectionMetadataCache.put(cacheKey, metadata);
} catch (NoClassDefFoundError err) {
throw new IllegalStateException("Failed to introspect bean class [" + clazz.getName() +
"] for autowiring metadata: could not find class that it depends on", err);
}
}
}
}
return metadata;
}
2、buildAutowiringMetadata
private InjectionMetadata buildAutowiringMetadata(final Class<?> clazz) {
// 1.用于存放所有解析到的注入的元素的变量
LinkedList<InjectionMetadata.InjectedElement> elements = new LinkedList<InjectionMetadata.InjectedElement>();
Class<?> targetClass = clazz;
// 2.循环遍历
do {
// 2.1 定义存放当前循环的Class注入的元素(有序)
final LinkedList<InjectionMetadata.InjectedElement> currElements =
new LinkedList<InjectionMetadata.InjectedElement>();
// 2.2 如果targetClass的属性上有@Autowired注解,则用工具类获取注解信息
ReflectionUtils.doWithLocalFields(targetClass, new ReflectionUtils.FieldCallback() {
@Override
public void doWith(Field field) throws IllegalArgumentException, IllegalAccessException {
// 2.2.1 获取field上的@Autowired注解信息
AnnotationAttributes ann = findAutowiredAnnotation(field);
if (ann != null) {
// 2.2.2 校验field是否被static修饰,如果是则直接返回,因为@Autowired注解不支持static修饰的field
if (Modifier.isStatic(field.getModifiers())) {
if (logger.isWarnEnabled()) {
logger.warn("Autowired annotation is not supported on static fields: " + field);
}
return;
}
// 2.2.3 获取@Autowired注解的required的属性值(required:值为true时,如果没有找到bean时,自动装配应该失败;false则不会)
boolean required = determineRequiredStatus(ann);
// 2.2.4 将field、required封装成AutowiredFieldElement,添加到currElements
currElements.add(new AutowiredFieldElement(field, required));
}
}
});
// 2.3 如果targetClass的方法上有@Autowired注解,则用工具类获取注解信息
ReflectionUtils.doWithLocalMethods(targetClass, new ReflectionUtils.MethodCallback() {
@Override
public void doWith(Method method) throws IllegalArgumentException, IllegalAccessException {
// 2.3.1 找到桥接方法
Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(method);
// 2.3.2 判断方法的可见性,如果不可见则直接返回
if (!BridgeMethodResolver.isVisibilityBridgeMethodPair(method, bridgedMethod)) {
return;
}
// 2.3.3 获取method上的@Autowired注解信息
AnnotationAttributes ann = findAutowiredAnnotation(bridgedMethod);
if (ann != null && method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) {
// 2.3.4 校验method是否被static修饰,如果是则直接返回,因为@Autowired注解不支持static修饰的method
if (Modifier.isStatic(method.getModifiers())) {
if (logger.isWarnEnabled()) {
logger.warn("Autowired annotation is not supported on static methods: " + method);
}
return;
}
// 2.3.5 @Autowired注解标识在方法上的目的就是将容器内的Bean注入到方法的参数中,没有参数就违背了初衷
if (method.getParameterTypes().length == 0) {
if (logger.isWarnEnabled()) {
logger.warn("Autowired annotation should only be used on methods with parameters: " +
method);
}
}
// 2.3.6 获取@Autowired注解的required的属性值
boolean required = determineRequiredStatus(ann);
// 2.3.7 获取method的属性描述器
PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz);
// 2.3.8 将method、required、pd封装成AutowiredMethodElement,添加到currElements
currElements.add(new AutowiredMethodElement(method, required, pd));
}
}
});
// 2.4 将本次循环获取到的注解信息添加到elements
elements.addAll(0, currElements);
// 2.5 在解析完targetClass之后,递归解析父类,将所有的@Autowired的属性和方法收集起来,且类的层级越高其属性会被越优先注入
targetClass = targetClass.getSuperclass();
}
while (targetClass != null && targetClass != Object.class); // 2.6 递归解析targetClass父类(直至父类为Object结束)
// 2.7 将clazz和解析到的注入的元素封装成InjectionMetadata
return new InjectionMetadata(clazz, elements);
}
3、checkConfigMembers
检查元数据中的注解信息。
public void checkConfigMembers(RootBeanDefinition beanDefinition) {
Set<InjectedElement> checkedElements = new LinkedHashSet<InjectedElement>(this.injectedElements.size());
// 1.遍历检查所有要注入的元素
for (InjectedElement element : this.injectedElements) {
Member member = element.getMember();
// 2.如果beanDefinition的externallyManagedConfigMembers属性不包含该member
if (!beanDefinition.isExternallyManagedConfigMember(member)) {
// 3.将该member添加到beanDefinition的externallyManagedConfigMembers属性
beanDefinition.registerExternallyManagedConfigMember(member);
// 4.并将element添加到checkedElements
checkedElements.add(element);
if (logger.isDebugEnabled()) {
logger.debug("Registered injected element on class [" + this.targetClass.getName() + "]: " + element);
}
}
}
// 5.赋值给checkedElements(检查过的元素)
this.checkedElements = checkedElements;
}
到这里为止,使用 @Autowire 修饰的方法和属性的相关元数据信息都已经放到 injectionMetadataCache 缓存中,用于后续使用。
三、InstantiationAwareBeanPostProcessor#postProcessAfterInstantiation
完成了@Autowire注解的预解析,doCreateBean流程继续往下走,走到了属性注入方法populateBean(前面还有一步addSingletonFactory方法,这个步骤是为了避免循环依赖二创建的三层缓存,有兴趣的可以看我这篇文章了解下《Spring:如何解决单例bean中的属性循环依赖》)
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args)
throws BeanCreationException {
// 1、实例化bean
instanceWrapper = createBeanInstance(beanName, mbd, args);
// 2、应用后置处理器MergedBeanDefinitionPostProcessor,允许修改MergedBeanDefinition
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
// 3、创建三层缓存,为避免循环依赖做准备
addSingletonFactory(beanName, new ObjectFactory<Object>() {
@Override
public Object getObject() throws BeansException {
return getEarlyBeanReference(beanName, mbd, bean);
}
});
// 4、属性注入
populateBean(beanName, mbd, instanceWrapper);
// ...
}
在bean实例化前,我们调用了 InstantiationAwareBeanPostProcessor的postProcessBeforeInstantiation方法,到了属性注入这一步,实例化步骤已经完成了,因此我们需要调用实例化后方法,即postProcessAfterInstantiation。
protected void populateBean(String beanName, RootBeanDefinition mbd, BeanWrapper bw) {
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
// 如果mbd不是合成的 && 存在InstantiationAwareBeanPostProcessor,则遍历处理InstantiationAwareBeanPostProcessor
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
// 在bean实例化后,属性填充之前被调用,允许修改bean的属性,如果返回false,则跳过之后的属性填充
if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
// 如果返回false,将continueWithPropertyPopulation赋值为false,代表要跳过之后的属性填充
continueWithPropertyPopulation = false;
break;
}
}
}
}
}
四、AutowiredAnnotationBeanPostProcessor#postProcessPropertyValues
populateBean方法中,应用后置处理器 InstantiationAwareBeanPostProcessor 的方法 postProcessPropertyValues,进行属性填充前的再次处理。由于AutowiredAnnotationBeanPostProcessor继承自AutowiredAnnotationBeanPostProcessor,这里便会执行@@Autowire的自动注入。
protected void populateBean(String beanName, RootBeanDefinition mbd, BeanWrapper bw) {
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
// 如果mbd不是合成的 && 存在InstantiationAwareBeanPostProcessor,则遍历处理InstantiationAwareBeanPostProcessor
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
// 在bean实例化后,属性填充之前被调用,允许修改bean的属性,如果返回false,则跳过之后的属性填充
if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
// 如果返回false,将continueWithPropertyPopulation赋值为false,代表要跳过之后的属性填充
continueWithPropertyPopulation = false;
break;
}
}
}
}
// ...
// 注册过InstantiationAwareBeanPostProcessors 或者 需要依赖检查
if (hasInstAwareBpps || needsDepCheck) {
PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
if (hasInstAwareBpps) {
// 应用后置处理器InstantiationAwareBeanPostProcessor
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
// 应用后置处理器InstantiationAwareBeanPostProcessor的方法postProcessPropertyValues,
// 进行属性填充前的再次处理。例子:现在最常用的@Autowire属性注入就是这边注入依赖的bean实例对象
pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
if (pvs == null) {
return;
}
}
}
}
if (needsDepCheck) {
// 依赖检查,对应depends-on属性
checkDependencies(beanName, mbd, filteredPds, pvs);
}
}
}
@Override
public PropertyValues postProcessPropertyValues(
PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeanCreationException {
// 1.在指定Bean中查找使用@Autowire注解的元数据
InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);
try {
// 2.InjectionMetadata: 执行inject()方法,开始执行属性注入或方法注入
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;
}
public void inject(Object target, String beanName, PropertyValues pvs) throws Throwable {
// 1.如果checkedElements存在,则使用checkedElements,否则使用injectedElements
Collection<InjectedElement> elementsToIterate =
(this.checkedElements != null ? this.checkedElements : this.injectedElements);
if (!elementsToIterate.isEmpty()) {
boolean debug = logger.isDebugEnabled();
for (InjectedElement element : elementsToIterate) {
if (debug) {
logger.debug("Processing injected element of bean '" + beanName + "': " + element);
}
// 2.解析@Autowired注解生成的元数据类:AutowiredFieldElement、AutowiredMethodElement,
// 这两个类继承InjectionMetadata.InjectedElement,各自重写了inject方法。
element.inject(target, beanName, pvs);
}
}
}
解析 @Autowired 注解生成的元数据类:AutowiredFieldElement、AutowiredMethodElement,这两个类继承InjectionMetadata.InjectedElement,各自重写了 inject 方法。对于属性注入来说,会走到 AutowiredFieldElement 中的 inject 方法。
@Override
protected void inject(Object bean, String beanName, PropertyValues pvs) throws Throwable {
// 1.拿到该元数据的属性值
Field field = (Field) this.member;
Object value;
// 2.如果缓存中已经存在,则直接从缓存中解析属性
if (this.cached) {
value = resolvedCachedArgument(beanName, this.cachedFieldValue);
} else {
// 3.将field封装成DependencyDescriptor
DependencyDescriptor desc = new DependencyDescriptor(field, this.required);
desc.setContainingClass(bean.getClass());
Set<String> autowiredBeanNames = new LinkedHashSet<String>(1);
TypeConverter typeConverter = beanFactory.getTypeConverter();
try {
// 4.解析当前属性所匹配的bean实例,并把解析到的bean实例的beanName存储在autowiredBeanNames中
value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);
} catch (BeansException ex) {
throw new UnsatisfiedDependencyException(null, beanName, new InjectionPoint(field), ex);
}
synchronized (this) {
if (!this.cached) {
// 5.value不为空或者required为true
if (value != null || this.required) {
// 6.如果属性依赖注入的bean不止一个(Array,Collection,Map),缓存cachedFieldValue放的是DependencyDescriptor
this.cachedFieldValue = desc;
// 7.注册依赖关系到缓存(beanName 依赖 autowiredBeanNames)
registerDependentBeans(beanName, autowiredBeanNames);
// 8.如果属性依赖注入的bean只有一个(正常都是一个)
if (autowiredBeanNames.size() == 1) {
String autowiredBeanName = autowiredBeanNames.iterator().next();
if (beanFactory.containsBean(autowiredBeanName)) {
// @Autowired标识属性类型和Bean的类型要匹配,因此Array,Collection,Map类型的属性不支持缓存属性Bean名称
// 9.检查autowiredBeanName对应的bean的类型是否为field的类型
if (beanFactory.isTypeMatch(autowiredBeanName, field.getType())) {
// 10.将该属性解析到的bean的信息封装成ShortcutDependencyDescriptor,
// 以便之后可以通过getBean方法来快速拿到bean实例
this.cachedFieldValue = new ShortcutDependencyDescriptor(
desc, autowiredBeanName, field.getType());
}
}
}
} else {
this.cachedFieldValue = null;
}
// 11.缓存标识设为true
this.cached = true;
}
}
}
if (value != null) {
// 12.设置字段访问性
ReflectionUtils.makeAccessible(field);
// 13.通过反射为属性赋值,将解析出来的bean实例赋值给field
field.set(bean, value);
}
}
到这里位置,我们就完成了bean的属性自动注入。
本文中的生命周期方法结合流程图展示如下: