AutowiredAnnotationBeanPostProcessor间接实现了BeanPostProcessor接口,属于Spring中的一个扩展,主要用于处理 @Autowired 和 @Value 注解。其关系如下图。
一、案例准备
1、配置类
package com.example.demo.config;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@ComponentScan("com.example.demo")
@Configuration
public class AppConfiguration {
}
2、实体类
package com.example.demo.entity;
import java.io.Serializable;
public class User implements Serializable {
private Long id;
private String name;
private Integer age;
@Override
public String toString() {
return "User{" +
"id=" + id +
", name='" + name + '\'' +
", age=" + age +
'}';
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
}
3、业务处理类
package com.example.demo.service.impl;
import com.example.demo.entity.User;
import com.example.demo.service.MenuService;
import com.example.demo.service.RoleService;
import com.example.demo.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class UserServiceImpl implements UserService {
// 测试 @Autowired 注解添加到属性上
@Autowired
private RoleService roleService;
// @Value("${xx}") // @Value也能放在方法上,取值会作为方法参数的值,不过貌似只支持String类型参数
// 测试 @Autowired 注解添加到方法上
@Autowired
public void importMenuService(MenuService menuService) {
menuService.print();
}
@Override
public void print() {
System.out.println("UserServiceImpl");
}
}
-----------------------------------------------------------------------
package com.example.demo.service.impl;
import com.example.demo.service.RoleService;
import org.springframework.stereotype.Service;
@Service
public class RoleServiceImpl implements RoleService {
@Override
public void print() {
System.out.println("RoleServiceImpl");
}
}
-----------------------------------------------------------------------
package com.example.demo.service.impl;
import com.example.demo.service.MenuService;
import org.springframework.stereotype.Service;
@Service
public class MenuServiceImpl implements MenuService {
@Override
public void print() {
System.out.println("MenuServiceImpl");
}
}
4、测试类
package com.example.demo.main;
import com.example.demo.config.AppConfiguration;
import com.example.demo.service.impl.UserServiceImpl;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class SpringTest {
public static void main(String[] args) {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
applicationContext.register(AppConfiguration.class);
applicationContext.refresh();
UserServiceImpl userService = applicationContext.getBean(UserServiceImpl.class);
userService.print();
}
}
5、输出
MenuServiceImpl
UserServiceImpl
二、源码解析(基于Spring-5.3.32版本)
1、断点调试大致流程
提示:
未阅读过Spring源码的朋友可以重点看以下两个方法,静下心来看相信你会懂哒!
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
doWithLocalFields(Class<?> clazz, FieldCallback fc)
// 测试类中的代码
applicationContext.refresh();
|
V
// 开始初始化Spring容器中的Bean
finishBeanFactoryInitialization(beanFactory);
|
V
beanFactory.preInstantiateSingletons();
|
V
// 初始化某个具体对象(可在循环到要测试的Bean对象时断点调试,本案例为userServiceImpl)
getBean(beanName);
|
V
doGetBean(name, null, null, false);
|
V
createBean(beanName, mbd, args);
|
V
// 真正创建并初始化对象
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
|
V
// 可等到for循环走到AutowiredAnnotationBeanPostProcessor时,
// 断点进入processor.postProcessMergedBeanDefinition(mbd, beanType, beanName);
// 该方法会将当前对象中所有加了 @Autowired 和 @Value 注解的属性和方法找出来并缓存
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
|
V
// 属性填充,在此方法内完成 @Autowired 和 @Value 注解处理
populateBean(beanName, mbd, instanceWrapper);
|
V
// 可等到for循环走到AutowiredAnnotationBeanPostProcessor时调试进入该方法
PropertyValues pvsToUse = bp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
|
V
InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);
|
V
metadata = buildAutowiringMetadata(clazz);
|
V
doWithLocalFields(Class<?> clazz, FieldCallback fc)
|
V
// 将当前对象中所有加了 @Autowired 和 @Value 注解的属性和方法找出来并缓存
fc.doWith(field);
|
V
metadata.inject(bean, beanName, pvs);
|
V
// 到这一步,通过反射 为属性赋值 或 调用对应的方法
element.inject(target, beanName, pvs);
2、源码分析
鉴于作者比较懒,就直接从
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyMergedBeanDefinitionPostProcessors
开始吧。
(1)org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory
applyMergedBeanDefinitionPostProcessors
protected void applyMergedBeanDefinitionPostProcessors(RootBeanDefinition mbd, Class<?> beanType, String beanName) {
for (MergedBeanDefinitionPostProcessor processor : getBeanPostProcessorCache().mergedDefinition) {
// 等 processor 值为 AutowiredAnnotationBeanPostProcessor 时,断点进入该方法
processor.postProcessMergedBeanDefinition(mbd, beanType, beanName);
}
}
(2)org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor
postProcessMergedBeanDefinition
@Override
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
// 寻找自动注入元数据,即加了@Autowired和@Value注解的属性和方法
InjectionMetadata metadata = findAutowiringMetadata(beanName, beanType, null);
// 校验查找的数据结果
metadata.checkConfigMembers(beanDefinition);
}
findAutowiringMetadata
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(Class<?> clazz) {
if (!AnnotationUtils.isCandidateClass(clazz, this.autowiredAnnotationTypes)) {
return InjectionMetadata.EMPTY;
}
final List<InjectionMetadata.InjectedElement> elements = new ArrayList<>();
Class<?> targetClass = clazz;
do {
final List<InjectionMetadata.InjectedElement> fieldElements = new ArrayList<>();
// doWithLocalFields 方法中还有一个 for 循环,所以当前方法块(即:field -> {})有可能执行多次
// 这一块是处理属性的
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;
}
boolean required = determineRequiredStatus(ann);
// 将找到的属性添加到 fieldElements 中
fieldElements.add(new AutowiredFieldElement(field, required));
}
});
final List<InjectionMetadata.InjectedElement> methodElements = new ArrayList<>();
// 下面这一块是处理方法的
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))) {
// Autowired 不支持处理静态方法
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);
// 将找到的方法添加到 methodElements 中
methodElements.add(new AutowiredMethodElement(method, required, pd));
}
});
// 将方法和属性合并到 elements 中
elements.addAll(0, sortMethodElements(methodElements, targetClass));
elements.addAll(0, fieldElements);
targetClass = targetClass.getSuperclass();
}
while (targetClass != null && targetClass != Object.class);
// 关键的一步,将结果放入到 this.injectedElements 中。
return InjectionMetadata.forElements(elements, clazz);
}
// this.injectedElements 属性以及下列方法在 org.springframework.beans.factory.annotation.InjectionMetadata 类中
public static InjectionMetadata forElements(Collection<InjectedElement> elements, Class<?> clazz) {
return (elements.isEmpty() ? new InjectionMetadata(clazz, Collections.emptyList()) :
new InjectionMetadata(clazz, elements));
}
public InjectionMetadata(Class<?> targetClass, Collection<InjectedElement> elements) {
this.targetClass = targetClass;
this.injectedElements = elements;
}
findAutowiredAnnotation
@Nullable
private MergedAnnotation<?> findAutowiredAnnotation(AccessibleObject ao) {
MergedAnnotations annotations = MergedAnnotations.from(ao);
// this.autowiredAnnotationTypes 为成员变量,赋值可看当前类的构造器方法
// 主要为 Autowired.class 和 Value.class,从下列代码也能看出对于取值 Autowired 优先级大于 Value 优先级
for (Class<? extends Annotation> type : this.autowiredAnnotationTypes) {
MergedAnnotation<?> annotation = annotations.get(type);
// 是否存在 ${type} 注解
if (annotation.isPresent()) {
// 存在直接返回
return annotation;
}
}
return null;
}
public AutowiredAnnotationBeanPostProcessor()
public AutowiredAnnotationBeanPostProcessor() {
// 构造时添加Autowired和Value注解类型
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.
}
}
checkConfigMembers
public void checkConfigMembers(RootBeanDefinition beanDefinition) {
// this.injectedElements 具体赋值看文章后面的 buildAutowiringMetadata 方法
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);
}
}
// 将结果赋给 this.checkedElements
this.checkedElements = checkedElements;
}
(3)org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory
populateBean
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
......
......省略
......
PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
......
......省略
......
boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);
PropertyDescriptor[] filteredPds = null;
if (hasInstAwareBpps) {
if (pvs == null) {
pvs = mbd.getPropertyValues();
}
for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
// 当 bp 取值为 AutowiredAnnotationBeanPostProcessor时,断点调试进入该方法,该方法会对前面找出来的属性和方法分别进行赋值和调用
PropertyValues pvsToUse = bp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
if (filteredPds == null) {
filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
pvsToUse = bp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
return;
}
}
pvs = pvsToUse;
}
}
......
......省略
......
}
(4)org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor
postProcessProperties
@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;
}
(5)org.springframework.beans.factory.annotation.InjectionMetadata
inject
public void inject(Object target, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
// this.checkedElements 取值看上述 postProcessMergedBeanDefinition 方法
Collection<InjectedElement> checkedElements = this.checkedElements;
Collection<InjectedElement> elementsToIterate =
(checkedElements != null ? checkedElements : this.injectedElements);
if (!elementsToIterate.isEmpty()) {
for (InjectedElement element : elementsToIterate) {
// 反射赋值或调用方法
// 若当前元素是属性,则看(6)
// 若当前元素是方法,则看(7)
element.inject(target, beanName, pvs);
}
}
}
(6)org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.AutowiredFieldElement#inject
@Override
protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
// 强转为属性
Field field = (Field) this.member;
Object value;
if (this.cached) {
try {
value = resolveCachedArgument(beanName, this.cachedFieldValue);
}
catch (BeansException ex) {
// Unexpected target bean mismatch for cached argument -> re-resolve
this.cached = false;
logger.debug("Failed to resolve cached argument", ex);
value = resolveFieldValue(field, bean, beanName);
}
}
else {
// 解析属性的值。
// 若当前属性尚未实例化,则该方法最终又会调用getBean方法先实例化当前属性
value = resolveFieldValue(field, bean, beanName);
}
if (value != null) {
ReflectionUtils.makeAccessible(field);
// 反射为属性赋值
field.set(bean, value);
}
}
(7)org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.AutowiredMethodElement#inject
@Override
protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
if (checkPropertySkipping(pvs)) {
return;
}
// 强转为方法
Method method = (Method) this.member;
Object[] arguments;
if (this.cached) {
try {
arguments = resolveCachedArguments(beanName, this.cachedMethodArguments);
}
catch (BeansException ex) {
// Unexpected target bean mismatch for cached argument -> re-resolve
this.cached = false;
logger.debug("Failed to resolve cached argument", ex);
arguments = resolveMethodArguments(method, bean, beanName);
}
}
else {
// 解析方法参数。
// 若当前方法参数尚未实例化,则该方法最终又会调用getBean方法先实例化当前方法参数
arguments = resolveMethodArguments(method, bean, beanName);
}
if (arguments != null) {
try {
ReflectionUtils.makeAccessible(method);
// 反射调用方法
method.invoke(bean, arguments);
}
catch (InvocationTargetException ex) {
throw ex.getTargetException();
}
}
}
总结:简单地来讲分为两部分,第一部分就是先找出加了@Autowired和@Value注解的属性和方法并进行缓存(AutowiredAnnotationBeanPostProcessor后置处理器的postProcessMergedBeanDefinition方法);第二部分就是对这些缓存的元素进行处理,若元素为属性,则通过反射赋值;若为方法,则通过反射调用(AutowiredAnnotationBeanPostProcessor后置处理器的postProcessProperties方法)。