上文讨论了Spring在进行依赖注入的时候,如何查找一个bean的依赖属性,本文则讨论在进行依赖属性的查找之前,进行依赖查找之前的处理流程
在Spring容器中,有两个重要的内置bean后置处理器,它们是AutowiredAnnotationBeanPostProcessor
和CommonAnnotationBeanPostProcessor
AutowiredAnnotationBeanPostProcessor
完成了对标注@Autowired
、@Value
、@Inject
属性的注入
CommonAnnotationBeanPostProcessor
完成了对JSR-250相关注解属性的注入,如@WebServiceRef
、@EJB
、@Resource
,同时,它也完成了一部分bean生命周期方法的处理,即@PostConstruct
、@PreDestroy
方法的回调
二者的功能类似,下面以AutowiredAnnotationBeanPostProcessor
进行讲解
AutowiredAnnotationBeanPostProcessor
实现了MergedBeanDefinitionPostProcessor
接口的postProcessMergedBeanDefinition
方法
public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter
implements MergedBeanDefinitionPostProcessor, PriorityOrdered, BeanFactoryAware {
// 缓存bean的注入属性元数据
private final Map<String, InjectionMetadata> injectionMetadataCache = new ConcurrentHashMap<>(256);
// ...
/**
* 解析当前bean需要注入的属性信息,生成一个注入属性元数据InjectionMetadata
*/
@Override
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
InjectionMetadata metadata = findAutowiringMetadata(beanName, beanType, null);
metadata.checkConfigMembers(beanDefinition);
}
private InjectionMetadata findAutowiringMetadata(String beanName, Class<?> clazz, @Nullable PropertyValues pvs) {
// Fall back to class name as cache key, for backwards compatibility with custom callers.
String cacheKey = (StringUtils.hasLength(beanName) ? beanName : clazz.getName());
// Quick check on the concurrent map first, with minimal locking.
InjectionMetadata metadata = this.injectionMetadataCache.get(cacheKey);
if (InjectionMetadata.needsRefresh(metadata, clazz)) {
synchronized (this.injectionMetadataCache) {
metadata = this.injectionMetadataCache.get(cacheKey);
if (InjectionMetadata.needsRefresh(metadata, clazz)) {
if (metadata != null) {
metadata.clear(pvs);
}
// 解析当前类要注入的属性的元数据
metadata = buildAutowiringMetadata(clazz);
// 缓存当前类要注入属性的元数据信息
this.injectionMetadataCache.put(cacheKey, metadata);
}
}
}
return metadata;
}
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 -> {
// 判断是否标注了相关注解信息
MergedAnnotation<?> ann = findAutowiredAnnotation(field);
if (ann != null) {
if (Modifier.isStatic(field.getModifiers())) {
return; // 可见,static属性是不会注入的
}
boolean required = determineRequiredStatus(ann);
currElements.add(new AutowiredFieldElement(field, required));
}
});
// 解析标注了注解的方法
ReflectionUtils.doWithLocalMethods(targetClass, method -> {
Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(method);
if (!BridgeMethodResolver.isVisibilityBridgeMethodPair(method, bridgedMethod)) {
return;
}
MergedAnnotation<?> ann = findAutowiredAnnotation(bridgedMethod);
if (ann != null && method.equals(ClassUtils.getMostSpecificMethod(method, clazz))) {
if (Modifier.isStatic(method.getModifiers())) {
if (logger.isInfoEnabled()) {
logger.info("Autowired annotation is not supported on static methods: " + method);
}
return;
}
if (method.getParameterCount() == 0) {
if (logger.isInfoEnabled()) {
logger.info("Autowired annotation should only be used on methods with parameters: " +
method);
}
}
boolean required = determineRequiredStatus(ann);
PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz);
currElements.add(new AutowiredMethodElement(method, required, pd));
}
});
// 加到列表的头部,注意,由于每次都放置在队列头部
// 而解析从子类递进到父类,则父类的数据会在前部
elements.addAll(0, currElements);
// 获取父类信息,准备开始下一次循环
targetClass = targetClass.getSuperclass();
} while (targetClass != null && targetClass != Object.class);
return InjectionMetadata.forElements(elements, clazz);
}
// 判断是否标注了相关注解
@Nullable
private MergedAnnotation<?> findAutowiredAnnotation(AccessibleObject ao) {
MergedAnnotations annotations = MergedAnnotations.from(ao);
for (Class<? extends Annotation> type : this.autowiredAnnotationTypes) {
MergedAnnotation<?> annotation = annotations.get(type);
if (annotation.isPresent()) {
return annotation;
}
}
return null;
}
}
到此一个bean的依赖属性元数据被解析完毕,并缓存了起来,以上的步骤发生在实例化bean之后,属性填充之前,接着便是对这个实例化完毕的bean进行属性填充
AutowiredAnnotationBeanPostProcessor
同样实现了InstantiationAwareBeanPostProcessor
接口的postProcessProperties
方法,该方法用来对属性进行填充
public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter
implements MergedBeanDefinitionPostProcessor, PriorityOrdered, BeanFactoryAware {
// 缓存bean的注入属性元数据
private final Map<String, InjectionMetadata> injectionMetadataCache = new ConcurrentHashMap<>(256);
@Override
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
// 获取前面解析完毕的依赖属性元数据
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;
}
}
public class InjectionMetadata {
// ...
public void inject(Object target, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
Collection<InjectedElement> checkedElements = this.checkedElements;
Collection<InjectedElement> elementsToIterate =
(checkedElements != null ? checkedElements : this.injectedElements);
if (!elementsToIterate.isEmpty()) {
for (InjectedElement element : elementsToIterate) {
// 通过循环,依次将属性注入目标bean
element.inject(target, beanName, pvs);
}
}
}
}
在AutowiredAnnotationBeanPostProcessor
存在两个内部类AutowiredFieldElement
、AutowiredMethodElement
,此处使用字段注入举例
private class AutowiredFieldElement extends InjectionMetadata.InjectedElement {
// ...
@Override
protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
// ...
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 {
// 这里就是上文依赖查找的调用发起的地方
value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);
} catch (BeansException ex) {
throw new UnsatisfiedDependencyException(null, beanName, new InjectionPoint(field), ex);
}
// ...
if (value != null) {
// 最后如果获取到的属性bean不为null,将其注入到目标bean中
ReflectionUtils.makeAccessible(field);
field.set(bean, value);
}
}
}
参考图: