前言
源码版本:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.8.RELEASE</version>
</dependency>
上一篇看了spring如何使用ConfigurationClassPostProcessor来解析配置文件的。本篇主要看AbstractApplicationContext的registerBeanPostProcessors方法,
// Register bean processors that intercept bean creation.
registerBeanPostProcessors(beanFactory);
从方法上面的注释可以知道,这个方法是注册Bean后置处理的。
正文
下面直接定位至PostProcessorRegistrationDelegate的registerBeanPostProcessors方法:
public static void registerBeanPostProcessors(
ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
// 获取工厂中类型为BeanPostProcessor的beanName的集合
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
// Register BeanPostProcessorChecker that logs an info message when
// a bean is created during BeanPostProcessor instantiation, i.e. when
// a bean is not eligible for getting processed by all BeanPostProcessors.
int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
// Separate between BeanPostProcessors that implement PriorityOrdered,
// Ordered, and the rest.
// 分离实现了PriorityOrdered,Ordered的BeanPostProcessors和剩余的,其实就是将BeanPostProcessors分类
List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
List<String> orderedPostProcessorNames = new ArrayList<>();
List<String> nonOrderedPostProcessorNames = new ArrayList<>();
for (String ppName : postProcessorNames) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) { // 分离实现PriorityOrdered的
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
priorityOrderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) { // 再分离实现MergedBeanDefinitionPostProcessor的
internalPostProcessors.add(pp);
}
}
else if (beanFactory.isTypeMatch(ppName, Ordered.class)) { //分离实现Ordered的
orderedPostProcessorNames.add(ppName);
}
else { // 其余的,剩下的
nonOrderedPostProcessorNames.add(ppName);
}
}
// First, register the BeanPostProcessors that implement PriorityOrdered.
// 首先,注册实现了PriorityOrdered的BeanPostProcessors
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);// 排序
registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors); // 注册
// Next, register the BeanPostProcessors that implement Ordered.
// 然后,注册实现了Ordered的BeanPostProcessors
List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
for (String ppName : orderedPostProcessorNames) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
orderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
sortPostProcessors(orderedPostProcessors, beanFactory); // 排序
registerBeanPostProcessors(beanFactory, orderedPostProcessors); // 注册
// Now, register all regular BeanPostProcessors.
// 注册所有的常规的BeanPostProcessors
List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
for (String ppName : nonOrderedPostProcessorNames) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
nonOrderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
// 注册
registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);
// Finally, re-register all internal BeanPostProcessors.
// 最后,重新注册所有常规的BeanPostProcessors(就是实现MergedBeanDefinitionPostProcessor的BeanPostProcessors)
sortPostProcessors(internalPostProcessors, beanFactory); // 排序
registerBeanPostProcessors(beanFactory, internalPostProcessors); // 注册
// Re-register post-processor for detecting inner beans as ApplicationListeners,
// moving it to the end of the processor chain (for picking up proxies etc).
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));// 添加一个ApplicationListenerDetector
}
注释都写到代码里面了。这个方法也不复杂,总体来说就一个功能:就是注册BeanPostProcessors。下面是整个方法的流程图:
MergedBeanDefinitionPostProcessor
在上面的方法中,多次出现了MergedBeanDefinitionPostProcessor,下面来看看这个接口是干啥的;先来看看这个类的注释:
/**
* Post-processor callback interface for <i>merged</i> bean definitions at runtime.
* {@link BeanPostProcessor} implementations may implement this sub-interface in order
* to post-process the merged bean definition (a processed copy of the original bean
* definition) that the Spring {@code BeanFactory} uses to create a bean instance.
* 后置处理的回调接口,为了在运行时合并bean信息。
* BeanPostProcessor的实现类可以实现这个子接口,以便Spring BeanFactory在创建bean实例时需要合并bean信息(一个对原始bean信息处理过的副本)
*
* <p>The {@link #postProcessMergedBeanDefinition} method may for example introspect
* the bean definition in order to prepare some cached metadata before post-processing
* actual instances of a bean. It is also allowed to modify the bean definition but
* <i>only</i> for definition properties which are actually intended for concurrent
* modification. Essentially, this only applies to operations defined on the
* {@link RootBeanDefinition} itself but not to the properties of its base classes.
* postProcessMergedBeanDefinition这个方法可以 例如:为了在实际实例化bean的后置处理之前准备一些缓存的元数据去自定义bean信息。
* 它还允许修改bean定义,但只允许对实际用于并发修改的定义属性进行修改。
* 本质上,这只适用于在RootBeanDefinition本身上定义的操作,而不适用于其基类的属性
*
*/
总结起来就是:可以修改bean的一些属性信息。
其实在这个地方的registerBeanPostProcessors方法中(spring-context 5.2.8中),放到internalPostProcessors中的MergedBeanDefinitionPostProcessor接口的实现类有两个,
一个是AutowiredAnnotationBeanPostProcessor,一个是CommonAnnotationBeanPostProcessor,这里只写了AutowiredAnnotationBeanPostProcessor,
其实CommonAnnotationBeanPostProcessor主要就是处理下面这几个的,感兴趣的可以去看看他的具体实现。
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.annotation.Resource;
import javax.ejb.EJB;
import javax.xml.namespace.QName;
import javax.xml.ws.Service;
import javax.xml.ws.WebServiceClient;
import javax.xml.ws.WebServiceRef;
AutowiredAnnotationBeanPostProcessor
这个类是MergedBeanDefinitionPostProcessor的实现类,从命名上面就可以看出这个类做自动装配方面的事情的。
构造方法
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.
}
}
构造方法就是向autowiredAnnotationTypes中放入Autowired,Value和Inject。
postProcessMergedBeanDefinition方法
@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;
}
这个方法主要流程就是:
- 判断缓存
- 加锁
- 构建数据
- 存缓存
其中用到了双重检验锁,这个方法最重要的就是buildAutowiringMetadata这个方法。
private InjectionMetadata buildAutowiringMetadata(final Class<?> clazz) {
if (!AnnotationUtils.isCandidateClass(clazz, this.autowiredAnnotationTypes)) {
return InjectionMetadata.EMPTY;
}
List<InjectionMetadata.InjectedElement> elements = new ArrayList<>();
Class<?> targetClass = clazz;
do {
// 构建currElements,用来存储符合条件的数据
final List<InjectionMetadata.InjectedElement> currElements = new ArrayList<>();
// 遍历当前类的参数
ReflectionUtils.doWithLocalFields(targetClass, field -> {
// 查找符合条件的参数(就是被构造函数中的三个注解修饰的)
MergedAnnotation<?> 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;
}
// 获取required参数
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);
}
}
// 获取required参数
boolean required = determineRequiredStatus(ann);
PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz);
// 添加到currElements
currElements.add(new AutowiredMethodElement(method, required, pd));
}
});
elements.addAll(0, currElements);
targetClass = targetClass.getSuperclass();
}
while (targetClass != null && targetClass != Object.class); // 向上遍历,直到父类为Object为止。
return InjectionMetadata.forElements(elements, clazz); // 返回
}
这个方法主要就是以下几点:
- 不断向上遍历,直到父类为
Object为止。 - 遍历类的参数和方法,找到符合条件(被
@Autowired,@Value,@Inject修饰)的参数和方法,最后放入集合中 - 将集合封装后返回
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;
}
这个方法就是在遍历autowiredAnnotationTypes,判断参数或方法是否被autowiredAnnotationTypes里面的注解修饰,有就直接返回了。
现在,通过findAutowiringMetadata方法,已经找到了被相应注解修饰的参数和方法,接下来就是执行checkConfigMembers方法了。
这个方法在org.springframework.beans.factory.annotation.InjectionMetadata类中。
public void checkConfigMembers(RootBeanDefinition beanDefinition) {
Set<InjectedElement> checkedElements = new LinkedHashSet<>(this.injectedElements.size());
for (InjectedElement element : this.injectedElements) {
Member member = element.getMember();
if (!beanDefinition.isExternallyManagedConfigMember(member)) {
beanDefinition.registerExternallyManagedConfigMember(member);
checkedElements.add(element);
if (logger.isTraceEnabled()) {
logger.trace("Registered injected element on class [" + this.targetClass.getName() + "]: " + element);
}
}
}
this.checkedElements = checkedElements;
}
这个方法就是遍历从findAutowiringMetadata方法拿到的数据,返回封装这些数据,最后放入到RootBeanDefinition中,也就是bean定义信息中。
最后
至此,spring中的后置处理就已经注册完成了,至于什么时候被调用,就要继续往后面看了。