AbstractAutowireCapableBeanFactory#createBeanInstance
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
// 获取class
Class<?> beanClass = resolveBeanClass(mbd, beanName);
Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
if (instanceSupplier != null) {
return obtainFromSupplier(instanceSupplier, beanName);
}
//对于工厂方法的处理,其实就是 @Bean 的处理
if (mbd.getFactoryMethodName() != null) {
return instantiateUsingFactoryMethod(beanName, mbd, args);
}
// 表示是否已经推断过构造方法
boolean resolved = false;
boolean autowireNecessary = false;
if (args == null) {
synchronized (mbd.constructorArgumentLock) {
//如果bd已经存在构造方法,resolved设置为true,表示已经存在构造方法,不需要进行推断
//只有原型模式才会进来这里
if (mbd.resolvedConstructorOrFactoryMethod != null) {
resolved = true;
//在推断构造方法的时候,会设置 constructorArgumentsResolved = true
autowireNecessary = mbd.constructorArgumentsResolved;
}
}
}
//如果bd已经有构造方法了,也就是原型就会直接通过已有的构造方法进行反射
if (resolved) {
//表示使用 autowireConstructor 推断过构造方法
if (autowireNecessary) {
return autowireConstructor(beanName, mbd, null, null);
}
else {
//无参构造
return instantiateBean(beanName, mbd);
}
}
// 进行第一次构造推断
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
//1.第一次推断的构造方法不为空
//2.自动注入模式为构造注入
if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
//第二次推断构造
return autowireConstructor(beanName, mbd, ctors, args);
}
ctors = mbd.getPreferredConstructors();
if (ctors != null) {
return autowireConstructor(beanName, mbd, ctors, null);
}
//使用无参构造反射
return instantiateBean(beanName, mbd);
}
AutowiredAnnotationBeanPostProcessor#determineCandidateConstructors
public Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, final String beanName)
throws BeanCreationException {
//..... 忽略对 @Lookup 注解的解析
// candidateConstructors 缓存推断完的构造方法,但是感觉作用不大
//因为如果是单例的话,这个方法只会走一次,如果是原型模式,那也不会走这个
//原型模式会从 beandefinition 中获取构造方法
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 {
//获取所有的构造方法
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;
//这个正常是为null,可以不用管
Constructor<?> primaryConstructor = BeanUtils.findPrimaryConstructor(beanClass);
int nonSyntheticConstructors = 0;
//遍历所有的构造方法
for (Constructor<?> candidate : rawCandidates) {
//这种情况一般是内部类,正常情况不是内部类,所以不用管
if (!candidate.isSynthetic()) {
nonSyntheticConstructors++;
}
else if (primaryConstructor != null) {
continue;
}
//找到构造方法上面加的 @Atowired @alue
AnnotationAttributes ann = findAutowiredAnnotation(candidate);
if (ann == null) {
//如果没有加注解,会去对比 userClass跟 beanClass ,这个不知道啥场景
//会不想等,正常情况是相等的
Class<?> userClass = ClassUtils.getUserClass(beanClass);
if (userClass != beanClass) {
//.....
}
}
//有加注解的情况
if (ann != null) {
// 如果 requiredConstructor 已经有了,就会报错
//因为此时存在多个加注解的构造方法,这样spring就不知道要选哪个,只好报错
if (requiredConstructor != null) {
//.....
}
//获取 注解 的 required 属性
boolean required = determineRequiredStatus(ann);
//如果 required = true(表示必须要用这个构造
if (required) {
//候选的构造函数列表不为空,此时就会报错
if (!candidates.isEmpty()) {
//......报错
}
//设置注解构造为 当前构造方法
requiredConstructor = candidate;
}
//往候选构造列表添加当前构造方法
candidates.add(candidate);
}
//如果 没有构造方法没有添加注解,而且构造方法的入参个数=0,也就是无参方法
//设置默认构造方法为无参的构造方法
else if (candidate.getParameterCount() == 0) {
defaultConstructor = candidate;
}
}
//上面大体就是寻找加注解的构造方法,如果有加注解的构造方法,就添加到 candidates
//如果有加注解的构造方法而且是必须的,就设置到 requiredConstructor
//如果存在多个必须的注解构造方法就会报错
//有默认构造方法,就设置到 defaultConstructor
//如果有注解必须的同时有注解非必须的构造方法,也会报错
//如果候选的构造方法不为空
if (!candidates.isEmpty()) {
//如果 requiredConstructor 不为空,而且默认构造不为空
//就把默认构造放到 candidates 集合中,这种情况只有在注解require = false的情况
if (requiredConstructor == null) {
if (defaultConstructor != null) {
candidates.add(defaultConstructor);
}
}
candidateConstructors = candidates.toArray(new Constructor<?>[0]);
}
//如果候选构造为空,就是没有添加注解,rawCandidates 是所有的构造方法
//rawCandidates 只有一个构造方法,而且构造方法的参数大于一,那就是用这个构造方法
else if (rawCandidates.length == 1 && rawCandidates[0].getParameterCount() > 0) {
candidateConstructors = new Constructor<?>[] {rawCandidates[0]};
}
//这个不看 primaryConstructor 为空
else if (nonSyntheticConstructors == 2 && primaryConstructor != null &&
defaultConstructor != null && !primaryConstructor.equals(defaultConstructor)) {
candidateConstructors = new Constructor<?>[] {primaryConstructor, defaultConstructor};
}
//这个也不开 primaryConstructor 为空
else if (nonSyntheticConstructors == 1 && primaryConstructor != null) {
candidateConstructors = new Constructor<?>[] {primaryConstructor};
}
else {
//找不到合适的构造方法
candidateConstructors = new Constructor<?>[0];
}
//将推断出来的构造放到缓存中
this.candidateConstructorsCache.put(beanClass, candidateConstructors);
}
}
}
//如果推断的构造方法数量为空,那就返回 null
return (candidateConstructors.length > 0 ? candidateConstructors : null);
}
构造推断流程图:
最后结果
-
1.不加注解,只有一个默认构造:返回null
-
2.不加注解,多个构造,返回null
-
3.不加注解,只有一个构造,非无参构造,返回这个
-
4.加注解 required都为 false,返回这几个require = false的构造
-
5.加注解,多个required为 true 报错
-
6.加注解,一个requred=true,多个require=false,报错
-
7.加注解,一个require=ture,没有默认构造返回这个require=true
-
8.加注解,一个require=true,有默认构造的返回默认构造+require=ture
-
9.所以有返回值的情况是3,4,7,8。要么没有注解只有一个有参构造,要么加注解,加的注解要么一个requre=ture,要么都是require=false。