相关阅读
- Spring Boot源码简析 DefaultListableBeanFactory
- Spring Boot源码简析 @EnableAspectJAutoProxy
- Spring Boot源码简析 事务管理
简介
本文基于SpringBoot 2.6.2
对AutowiredAnnotationBeanPostProcessor
的使用进行源码分析。
作用域
构造方法
每个Bean最多只能拥有一个标注了required
属性设置为true的注解Autowired
的构造方法,Spring容器会使用该构造方法创建Bean,并注入其依赖;但可以拥有多个标注了required
属性未设置为true的注解Autowired
的构造方法,这些构造方法都是候选构造方法,Spring容器会选择匹配Bean依赖最多的构造方法创建Bean,如果没有选出合适的构造方法,则使用首要/默认的构造方法如果存在的话;
@RestController
public class DemoController {
private final DemoService demoService;
@Autowired
public DemoController(DemoService demoService) {
this.demoService = demoService;
}
}
字段
标注了注解Autowired
的字段的依赖注入发生在构造方法调用之后,配置方法调用之前;
@RestController
public class DemoController {
@Autowired
private DemoService demoService;
}
配置方法
标注了注解Autowired
的配置方法可以拥有随意的方法名和参数列表,每个参数都会在Spring容器中找到匹配的Bean;标注了注解Autowired
的字段的setter方法是配置方法的一种特殊形式;
@RestController
public class DemoController {
private DemoService demoService;
@Autowired
private void test(DemoService demoService) {
this.demoService = demoService;
}
}
@Lookup方法
标注了注解Lookup
的方法会在运行时被Spring容器替换,即可以每次都是从Spring容器中获取最新的依赖(依赖为多例时,此时每次获取的依赖都不一样);
@RestController
public abstract class DemoController implements CommandLineRunner {
@Lookup
public abstract DemoService test();
@Override
public void run(String... args) throws Exception {
for (int i = 0; i < 5; i++) {
System.out.println(test());
}
}
}
简析
首先分析注入点的解析过程,然后再分析注入点的注入时机;
注入点解析
构造方法
AbstractAutowireCapableBeanFactory.createBeanInstance
方法中会调用determineConstructorsFromBeanPostProcessors
方法查找可以自动注入的候选构造方法,若存在,则调用autowireConstructor
完成Bean创建,核心代码如下:
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
...
// Candidate constructors for autowiring?
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
return autowireConstructor(beanName, mbd, ctors, args);
}
...
}
determineConstructorsFromBeanPostProcessors
方法遍历执行Spring容器中所有的SmartInstantiationAwareBeanPostProcessor
的determineCandidateConstructors
方法,若得到的候选构造方法不为null则直接返回使用,代码如下:
protected Constructor<?>[] determineConstructorsFromBeanPostProcessors(@Nullable Class<?> beanClass, String beanName)
throws BeansException {
if (beanClass != null && hasInstantiationAwareBeanPostProcessors()) {
// 遍历容器中所有的SmartInstantiationAwareBeanPostProcessor
for (SmartInstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().smartInstantiationAware) {
Constructor<?>[] ctors = bp.determineCandidateConstructors(beanClass, beanName);
if (ctors != null) {
// 若存在则直接返回使用
return ctors;
}
}
}
return null;
}
此时容器中会存在AutowiredAnnotationBeanPostProcessor
(AutowiredAnnotationBeanPostProcessor
在AnnotationConfigUtil.registerAnnotationConfigProcessors
中注册),构造方法和@Lookup
方法的解析都在方法AutowiredAnnotationBeanPostProcessor.determineCandidateConstructors
中,其中构造方法解析的核心代码如下:
public Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, final String beanName)
throws BeanCreationException {
// @Lookup方法解析
...
// 构造方法解析
// 此处实现了缓存,若已处理则可以跳过
Constructor<?>[] candidateConstructors = this.candidateConstructorsCache.get(beanClass);
if (candidateConstructors == null) {
synchronized (this.candidateConstructorsCache) {
candidateConstructors = this.candidateConstructorsCache.get(beanClass);
// DCL
if (candidateConstructors == null) {
// 解析候选构造方法
Constructor<?>[] rawCandidates;
try {
rawCandidates = beanClass.getDeclaredConstructors();
}
catch (Throwable ex) {
throw new BeanCreationException(beanName,
"Resolution of declared constructors on bean Class [" + beanClass.getName() +
"] from ClassLoader [" + beanClass.getClassLoader() + "] failed", ex);
}
List<Constructor<?>> candidates = new ArrayList<>(rawCandidates.length);
Constructor<?> requiredConstructor = null;
Constructor<?> defaultConstructor = null;
// 查找首要构造方法,非Kotlin类直接返回null
Constructor<?> primaryConstructor = BeanUtils.findPrimaryConstructor(beanClass);
int nonSyntheticConstructors = 0;
// 遍历本类的所有构造方法,无论访问权限
for (Constructor<?> candidate : rawCandidates) {
if (!candidate.isSynthetic()) {
nonSyntheticConstructors++;
}
else if (primaryConstructor != null) {
continue;
}
// 查找构造方法上是否有注入注解(默认支持Autowired、Value、Inject)
MergedAnnotation<?> ann = findAutowiredAnnotation(candidate);
if (ann == null) {
Class<?> userClass = ClassUtils.getUserClass(beanClass);
if (userClass != beanClass) {
try {
Constructor<?> superCtor =
userClass.getDeclaredConstructor(candidate.getParameterTypes());
// 再次查找构造方法上是否有注入注解(默认支持Autowired、Value、Inject)
ann = findAutowiredAnnotation(superCtor);
}
catch (NoSuchMethodException ex) {
// Simply proceed, no equivalent superclass constructor found...
}
}
}
if (ann != null) {
if (requiredConstructor != null) {
// 已经存在标注了required属性设置为true的注解Autowired的构造方法,则不允许再有其它标注了注解Autowired的构造方法
throw new BeanCreationException(beanName,
"Invalid autowire-marked constructor: " + candidate +
". Found constructor with 'required' Autowired annotation already: " +
requiredConstructor);
}
// 注解的required属性是否为true
boolean required = determineRequiredStatus(ann);
if (required) {
if (!candidates.isEmpty()) {
throw new BeanCreationException(beanName,
"Invalid autowire-marked constructors: " + candidates +
". Found constructor with 'required' Autowired annotation: " +
candidate);
}
// 缓存标注了required属性设置为true的注解`Autowired`的构造方法
requiredConstructor = candidate;
}
// 缓存候选构造方法
candidates.add(candidate);
}
else if (candidate.getParameterCount() == 0) {
// 缓存默认构造方法
defaultConstructor = candidate;
}
}
if (!candidates.isEmpty()) {
if (requiredConstructor == null) {
if (defaultConstructor != null) {
// 添加默认构造方法,做为退路
candidates.add(defaultConstructor);
}
else if (candidates.size() == 1 && logger.isInfoEnabled()) {
// 此时仅有一个标注了required属性未设置为true的注解Autowired的构造方法,那么该注解的required属性等效为true
logger.info("Inconsistent constructor declaration on bean with name '" + beanName +
"': single autowire-marked constructor flagged as optional - " +
"this constructor is effectively required since there is no " +
"default constructor to fall back to: " + candidates.get(0));
}
}
candidateConstructors = candidates.toArray(new Constructor<?>[0]);
}
else if (rawCandidates.length == 1 && rawCandidates[0].getParameterCount() > 0) {
// 仅存在一个有参数的构造方法,则作为候选构造方法
candidateConstructors = new Constructor<?>[] {rawCandidates[0]};
}
else if (nonSyntheticConstructors == 2 && primaryConstructor != null &&
defaultConstructor != null && !primaryConstructor.equals(defaultConstructor)) {
// 使用首要和默认构造方法
candidateConstructors = new Constructor<?>[] {primaryConstructor, defaultConstructor};
}
else if (nonSyntheticConstructors == 1 && primaryConstructor != null) {
// 仅使用首要构造方法
candidateConstructors = new Constructor<?>[] {primaryConstructor};
}
else {
// 无候选构造方法
candidateConstructors = new Constructor<?>[0];
}
this.candidateConstructorsCache.put(beanClass, candidateConstructors);
}
}
}
return (candidateConstructors.length > 0 ? candidateConstructors : null);
}
字段
AbstractAutowireCapableBeanFactory.doCreateBean
方法中创建出Bean实例后,会遍历执行Spring容器中所有MergedBeanDefinitionPostProcessor.postProcessMergedBeanDefinition
方法用于修改Bean的RootBeanDefinition
,代码如下:
protected void applyMergedBeanDefinitionPostProcessors(RootBeanDefinition mbd, Class<?> beanType, String beanName) {
for (MergedBeanDefinitionPostProcessor processor : getBeanPostProcessorCache().mergedDefinition) {
processor.postProcessMergedBeanDefinition(mbd, beanType, beanName);
}
}
此时容器中会存在AutowiredAnnotationBeanPostProcessor
(AutowiredAnnotationBeanPostProcessor
在AnnotationConfigUtil.registerAnnotationConfigProcessors
中注册),其postProcessMergedBeanDefinition
方法代码如下:
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) {
String cacheKey = (StringUtils.hasLength(beanName) ? beanName : clazz.getName());
// 此处实现了缓存,若已处理则可以跳过
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);
}
// 构建InjectionMetadata
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;
}
List<InjectionMetadata.InjectedElement> elements = new ArrayList<>();
Class<?> targetClass = clazz;
do {
final List<InjectionMetadata.InjectedElement> currElements = new ArrayList<>();
// 字段的解析
// 遍历本类的所有字段,无论访问权限
ReflectionUtils.doWithLocalFields(targetClass, field -> {
// 查找字段上是否有注入注解(默认支持Autowired、Value、Inject)
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属性是否为true
boolean required = determineRequiredStatus(ann);
// 缓存该待注入字段信息
currElements.add(new AutowiredFieldElement(field, required));
}
});
// 配置方法的解析
...
elements.addAll(0, currElements);
// 继续搜索父类,直到父类不存在或者父类就是Object类
targetClass = targetClass.getSuperclass();
}
while (targetClass != null && targetClass != Object.class);
return InjectionMetadata.forElements(elements, clazz);
}
private MergedAnnotation<?> findAutowiredAnnotation(AccessibleObject ao) {
MergedAnnotations annotations = MergedAnnotations.from(ao);
// 遍历支持的注入注解(默认支持Autowired、Value、Inject)
for (Class<? extends Annotation> type : this.autowiredAnnotationTypes) {
MergedAnnotation<?> annotation = annotations.get(type);
if (annotation.isPresent()) {
// 存在则立即使用
return annotation;
}
}
return null;
}
protected boolean determineRequiredStatus(MergedAnnotation<?> ann) {
return determineRequiredStatus(ann.<AnnotationAttributes> asMap(
mergedAnnotation -> new AnnotationAttributes(mergedAnnotation.getType())));
}
protected boolean determineRequiredStatus(AnnotationAttributes ann) {
// 如果required属性不存在,或者其属性为true,则返回true;否则返回false
// Autowired存在required属性,默认为true
// Value不存在required属性
// Inject不存在required属性
return (!ann.containsKey(this.requiredParameterName) ||
this.requiredParameterValue == ann.getBoolean(this.requiredParameterName));
}
配置方法
同字段,配置方法的解析在方法AutowiredAnnotationBeanPostProcessor.buildAutowiringMetadata
中,核心代码如下:
private InjectionMetadata buildAutowiringMetadata(Class<?> clazz) {
if (!AnnotationUtils.isCandidateClass(clazz, this.autowiredAnnotationTypes)) {
// 如果该类不支持注入注解,则直接返回
return InjectionMetadata.EMPTY;
}
List<InjectionMetadata.InjectedElement> elements = new ArrayList<>();
Class<?> targetClass = clazz;
do {
final List<InjectionMetadata.InjectedElement> currElements = new ArrayList<>();
// 字段的解析
...
// 配置方法的解析
// 遍历本类的所有方法,无论访问权限
ReflectionUtils.doWithLocalMethods(targetClass, method -> {
// 获取原始方法(桥接方法是编译器生成的,而不是类定义的)
Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(method);
if (!BridgeMethodResolver.isVisibilityBridgeMethodPair(method, bridgedMethod)) {
return;
}
// 查找方法上是否有注入注解(默认支持Autowired、Value、Inject)
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属性是否为true
boolean required = determineRequiredStatus(ann);
PropertyDescriptor pd = BeanUtils.findPropertyForMethod(bridgedMethod, clazz);
// 缓存该配置方法信息
currElements.add(new AutowiredMethodElement(method, required, pd));
}
});
elements.addAll(0, currElements);
// 继续搜索父类,直到父类不存在或者父类就是Object类
targetClass = targetClass.getSuperclass();
}
while (targetClass != null && targetClass != Object.class);
return InjectionMetadata.forElements(elements, clazz);
}
@Lookup方法
同构造方法,@Lookup
方法的解析是在AutowiredAnnotationBeanPostProcessor.determineCandidateConstructors
方法中,核心代码如下:
public Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, final String beanName)
throws BeanCreationException {
// @Lookup方法解析
// 此处实现了缓存,若已处理则可以跳过
if (!this.lookupMethodsChecked.contains(beanName)) {
// 如果该类不支持注入注解,则可以跳过
if (AnnotationUtils.isCandidateClass(beanClass, Lookup.class)) {
try {
Class<?> targetClass = beanClass;
do {
// 遍历本类的所有方法,无论访问权限
ReflectionUtils.doWithLocalMethods(targetClass, method -> {
// 查找方法上是否有Lookup注解
Lookup lookup = method.getAnnotation(Lookup.class);
if (lookup != null) {
Assert.state(this.beanFactory != null, "No BeanFactory available");
LookupOverride override = new LookupOverride(method, lookup.value());
try {
RootBeanDefinition mbd = (RootBeanDefinition)
this.beanFactory.getMergedBeanDefinition(beanName);
// 添加该LookupOverride
mbd.getMethodOverrides().addOverride(override);
}
catch (NoSuchBeanDefinitionException ex) {
throw new BeanCreationException(beanName,
"Cannot apply @Lookup to beans without corresponding bean definition");
}
}
});
// 继续搜索父类,直到父类不存在或者父类就是Object类
targetClass = targetClass.getSuperclass();
}
while (targetClass != null && targetClass != Object.class);
}
catch (IllegalStateException ex) {
throw new BeanCreationException(beanName, "Lookup method resolution failed", ex);
}
}
// 缓存该beanName,避免下次再处理
this.lookupMethodsChecked.add(beanName);
}
// 构造方法解析
...
}
注入时机
构造方法
AbstractAutowireCapableBeanFactory.createBeanInstance
方法中会调用determineConstructorsFromBeanPostProcessors
方法查找可以自动注入的候选构造方法,若存在,则调用autowireConstructor
完成Bean创建,核心代码如下:
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
...
// Candidate constructors for autowiring?
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
return autowireConstructor(beanName, mbd, ctors, args);
}
...
}
protected BeanWrapper autowireConstructor(
String beanName, RootBeanDefinition mbd, @Nullable Constructor<?>[] ctors, @Nullable Object[] explicitArgs) {
return new ConstructorResolver(this).autowireConstructor(beanName, mbd, ctors, explicitArgs);
}
ConstructorResolver.autowireConstructor
方法中会找到合适的构造方法并得到参数列表,然后执行instantiate
方法创建实例;
字段
字段的依赖注入发生在AbstractAutowireCapableBeanFactory.populateBean
方法中,该方法会遍历执行Spring容器中所有的InstantiationAwareBeanPostProcessor.postProcessProperties
方法,代码如下:
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
...
// Give any InstantiationAwareBeanPostProcessors the opportunity to modify the
// state of the bean before properties are set. This can be used, for example,
// to support styles of field injection.
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
if (!bp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
return;
}
}
}
...
}
此时容器中会存在AutowiredAnnotationBeanPostProcessor
(AutowiredAnnotationBeanPostProcessor
在AnnotationConfigUtil.registerAnnotationConfigProcessors
中注册),其postProcessProperties
方法代码如下:
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
// 获取InjectionMetadata
// 已经在postProcessMergedBeanDefinition方法中构建过,此时可以直接从缓存中获取
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;
}
InjectionMetadata.inject
方法代码如下:
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()) {
// 遍历所有的InjectedElement
// 1. AutowiredAnnotationBeanPostProcessor.AutowiredFieldElement
// 2. AutowiredAnnotationBeanPostProcessor.AutowiredMethodElement
for (InjectedElement element : elementsToIterate) {
element.inject(target, beanName, pvs);
}
}
}
字段的依赖注入由AutowiredAnnotationBeanPostProcessor.AutowiredFieldElement
实现,代码如下:
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 = resolvedCachedArgument(beanName, this.cachedFieldValue);
}
catch (NoSuchBeanDefinitionException ex) {
// 获取失败,则根据字段从Spring容器中获取字段值,并缓存,方便下次直接从缓存中获取
value = resolveFieldValue(field, bean, beanName);
}
}
else {
// 根据字段从Spring容器中获取字段值,并缓存,方便下次直接从缓存中获取
value = resolveFieldValue(field, bean, beanName);
}
if (value != null) {
// 存在字段值,则注入
ReflectionUtils.makeAccessible(field);
field.set(bean, value);
}
}
配置方法
同字段,配置方法的依赖注入由AutowiredAnnotationBeanPostProcessor.AutowiredMethodElement
实现,代码如下:
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);
}
catch (NoSuchBeanDefinitionException ex) {
// 根据方法从Spring容器中获取方法参数列表,并缓存,方便下次直接从缓存中获取
arguments = resolveMethodArguments(method, bean, beanName);
}
}
else {
// 根据方法从Spring容器中获取方法参数列表,并缓存,方便下次直接从缓存中获取
arguments = resolveMethodArguments(method, bean, beanName);
}
if (arguments != null) {
try {
// 存在方法参数,则执行方法完成依赖注入
ReflectionUtils.makeAccessible(method);
method.invoke(bean, arguments);
}
catch (InvocationTargetException ex) {
throw ex.getTargetException();
}
}
}
@Lookup方法
同构造方法;