上一篇Spring5源码-BeanPostProcessor接口分析分析了BeanPostProcessor的注册与调用时机,本文就来看看Spring是怎么运用BeanPostProcessor来实现依赖注入功能的。
AutowiredAnnotationBeanPostProcessor用来处理@Autowired和@Value注解,以实现依赖注入和值注入。它实现了BeanPostProcessor接口:
- 实现了SmartInstantiationAwareBeanPostProcessor接口的determineCandidateConstructors方法
- 实现了MergedBeanDefinitionPostProcessor接口的postProcessMergedBeanDefinition方法
- 实现了InstantiationAwareBeanPostProcessor接口的postProcessProperties方法
1、调用SmartInstantiationAwareBeanPostProcessor的determineCandidateConstructors()决定使用哪个构造函数。
public class AutowiredAnnotationBeanPostProcessor implements SmartInstantiationAwareBeanPostProcessor,
MergedBeanDefinitionPostProcessor, PriorityOrdered, BeanFactoryAware {
......
@Override
@Nullable
public Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, final String beanName){
......
// Quick check on the concurrent map first, with minimal locking.
Constructor<?>[] candidateConstructors = this.candidateConstructorsCache.get(beanClass);
if (candidateConstructors == null) {
// Fully synchronized resolution now...
synchronized (this.candidateConstructorsCache) {
candidateConstructors = this.candidateConstructorsCache.get(beanClass);
if (candidateConstructors == null) {
Constructor<?>[] rawCandidates;
try {
//拿到某个Bean的所有构造函数
rawCandidates = beanClass.getDeclaredConstructors();
}
catch (Throwable ex) {
......
}
List<Constructor<?>> candidates = new ArrayList<>(rawCandidates.length);
Constructor<?> requiredConstructor = null;
Constructor<?> defaultConstructor = null;
Constructor<?> primaryConstructor = BeanUtils.findPrimaryConstructor(beanClass);
int nonSyntheticConstructors = 0;
for (Constructor<?> candidate : rawCandidates) {
if (!candidate.isSynthetic()) {
nonSyntheticConstructors++;
}
else if (primaryConstructor != null) {
continue;
}
//变量所有的构造函数,判断是否有Autowired或者Value注解
MergedAnnotation<?> ann = findAutowiredAnnotation(candidate);
if (ann == null) {
//没找到则获取目标类而非其代理类后再次查找
Class<?> userClass = ClassUtils.getUserClass(beanClass);
if (userClass != beanClass) {
try {
Constructor<?> superCtor =
userClass.getDeclaredConstructor(candidate.getParameterTypes());
ann = findAutowiredAnnotation(superCtor);
}
catch (NoSuchMethodException ex) {
// Simply proceed, no equivalent superclass constructor found...
}
}
}
if (ann != null) {
if (requiredConstructor != null) {
throw new BeanCreationException(beanName,
"Invalid autowire-marked constructor: " + candidate +
". Found constructor with 'required' Autowired annotation already: " +
requiredConstructor);
}
//获取@Autowired中的"required" 判断该依赖是否是必须的
boolean required = determineRequiredStatus(ann);
if (required) {
//找到多个@Autowired标注的构造函数则报错
if (!candidates.isEmpty()) {
throw new BeanCreationException(beanName,
"Invalid autowire-marked constructors: " + candidates +
". Found constructor with 'required' Autowired annotation: " +
candidate);
}
requiredConstructor = candidate;
}
candidates.add(candidate);
}
else if (candidate.getParameterCount() == 0) {
defaultConstructor = candidate;
}
}
if (!candidates.isEmpty()) {
// Add default constructor to list of optional constructors, as fallback.
if (requiredConstructor == null) {
if (defaultConstructor != null) {
candidates.add(defaultConstructor);
}
else if (candidates.size() == 1 && logger.isInfoEnabled()) {
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));
}
}
//只有1个构造函数被@Autowired标注时
candidateConstructors = candidates.toArray(new Constructor<?>[0]);
}
else if (rawCandidates.length == 1 && rawCandidates[0].getParameterCount() > 0) { //只有1个构造函数且该构造函数有参数时
candidateConstructors = new Constructor<?>[] {rawCandidates[0]};
}
//这里不会进, 因为 primaryConstructor = null
else if (nonSyntheticConstructors == 2 && primaryConstructor != null &&
defaultConstructor != null && !primaryConstructor.equals(defaultConstructor)) {
candidateConstructors = new Constructor<?>[] {primaryConstructor, defaultConstructor};
}
//这里不会进, 因为 primaryConstructor = null
else if (nonSyntheticConstructors == 1 && primaryConstructor != null) {
candidateConstructors = new Constructor<?>[] {primaryConstructor};
}
else {
//无构造函数注入,就用默认的构造
//类定义了多个构造方法, 且没有 @Autowired,或者只定义了一个无参构造,则会进这里
candidateConstructors = new Constructor<?>[0];
}
this.candidateConstructorsCache.put(beanClass, candidateConstructors);
}
}
}
return (candidateConstructors.length > 0 ? candidateConstructors : null);
}
......
}
从上代码可以看出:
① 只定义一个有参构造,不需要@Autowired标注也能自动注入
② 定义多个构造函数,如果无@Autowired标注,则用默认无参构造,如果有多个被@Autowired 标注会报错。
2、选定构造函数过后,接下来就是进行依赖注入
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);
}
// Preferred constructors for default construction?
ctors = mbd.getPreferredConstructors();
if (ctors != null) {
return autowireConstructor(beanName, mbd, ctors, null);
}
// No special handling: simply use no-arg constructor.
return instantiateBean(beanName, mbd);
}
protected BeanWrapper autowireConstructor(
String beanName, RootBeanDefinition mbd, @Nullable Constructor<?>[] ctors, @Nullable Object[] explicitArgs) {
return new ConstructorResolver(this).autowireConstructor(beanName, mbd, ctors, explicitArgs);
}
比如有以下示例代码,解析到一个参数的构造函数,发现依赖C,然后去创建Bean C,最终通过ctor.newInstance(argsWithDefaultValues)完成实例化。此时c注入完成。
@ComponentScan
public class Application {
public static void main(String[] args) {
ApplicationContext context = new AnnotationConfigApplicationContext(Application.class);
System.out.println(String.join("\n",context.getBeanDefinitionNames()));
}
}
@Component
class A {
@Autowired
private B b;
private C c;
private D d;
@Autowired
public A(C c){
System.out.println("A(C c)");
this.c=c;
}
@Autowired
public void setD(D d){
System.out.println("setD(D d)方法执行了");
this.d=d;
}
}
@Component
class B {}
@Component
class C {}
@Component
class D {}
2、接下来调用MergedBeanDefinitionPostProcessor接口的postProcessMergedBeanDefinition方法完成对@Autowired标注的字段或方法进行解析,并保存到injectionMetadataCache的Map中。
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);
}
// 循环获取类上的字段和方法,如果字段上有@Value和@Autowired包装成AutowiredFieldElement放入结果集
//如果方法上有@Value和@Autowired包装成AutowiredMethodElement放入结果集
metadata = buildAutowiringMetadata(clazz);
this.injectionMetadataCache.put(cacheKey, metadata);
}
}
}
return metadata;
}
执行完该方法后,只是解析完了元数据(如下图),并未实现注入,接下来执行属性填充。此时内部会调用InstantiationAwareBeanPostProcessor接口的postProcessProperties方法完成依赖注入。
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
......
PropertyDescriptor[] filteredPds = null;
if (hasInstAwareBpps) {
if (pvs == null) {
pvs = mbd.getPropertyValues();
}
for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
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;
}
}
if (needsDepCheck) {
if (filteredPds == null) {
filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
checkDependencies(beanName, mbd, filteredPds, pvs);
}
if (pvs != null) {
applyPropertyValues(beanName, mbd, bw, pvs);
}
}
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
//获取InjectionMetadata ,上一步已经解析完成存到缓存中,这里直接取出来即可
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;
}
//字段依赖注入实现
protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
Field field = (Field) this.member;
Object value;
if (this.cached) {
try {
//解析字段,比如这里是Bean B,则先完成Bean B的创建,然后通过反射设置到b中
value = resolvedCachedArgument(beanName, this.cachedFieldValue);
}
catch (NoSuchBeanDefinitionException ex) {
// Unexpected removal of target bean for cached argument -> re-resolve
value = resolveFieldValue(field, bean, beanName);
}
}
else {
value = resolveFieldValue(field, bean, beanName);
}
if (value != null) {
ReflectionUtils.makeAccessible(field);
field.set(bean, value);
}
}
//方法注入,会先解析参数,然后遇到需要注入的Bean就先完成创建,然后通过反射调用方法
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) {
// Unexpected removal of target bean for cached argument -> re-resolve
arguments = resolveMethodArguments(method, bean, beanName);
}
}
else {
arguments = resolveMethodArguments(method, bean, beanName);
}
if (arguments != null) {
try {
ReflectionUtils.makeAccessible(method);
method.invoke(bean, arguments);
}
catch (InvocationTargetException ex) {
throw ex.getTargetException();
}
}
}
到这里,依赖注入就分析完了。