1.doCreateBean方法:这一部分,用到createBeanInstance方法:
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
// 有可能在本Bean创建之前,就有其他Bean把当前Bean给创建出来了(比如依赖注入过程中)
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
// 创建Bean实例
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
2.createBeanInstance方法:
源码思路
1. AbstractAutowireCapableBeanFactory类中的createBeanInstance()方法会去创建一个Bean实例
2. 根据BeanDefinition加载类得到Class对象
3. 如果BeanDefinition绑定了一个Supplier,那就调用Supplier的get方法得到一个对象并直接返回
4. 如果BeanDefinition中存在factoryMethodName,那么就调用该工厂方法得到一个bean对象并返回
5. 如果BeanDefinition已经自动构造过了,那就调用autowireConstructor()自动构造一个对象
6. 调用SmartInstantiationAwareBeanPostProcessor的determineCandidateConstructors()方法得到哪些构造方法是可以用的
7. 如果存在可用得构造方法,或者当前BeanDefinition的autowired是AUTOWIRE_CONSTRUCTOR,或者BeanDefinition中指定了构造方法参数值,或者创建Bean的时候指定了构造方法参数值,那么就调用autowireConstructor()方法自动构造一个对象
8. 最后,如果不是上述情况,就根据无参的构造方法实例化一个对象
具体代码
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
// Make sure bean class is actually resolved at this point.
Class<?> beanClass = resolveBeanClass(mbd, beanName);
if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Bean class isn't public, and non-public access not allowed: " + beanClass.getName());
}
// BeanDefinition中添加了Supplier,则调用Supplier来得到对象
Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
if (instanceSupplier != null) {
return obtainFromSupplier(instanceSupplier, beanName);
}
// @Bean对应的BeanDefinition
if (mbd.getFactoryMethodName() != null) {
return instantiateUsingFactoryMethod(beanName, mbd, args);
}
// Shortcut when re-creating the same bean...
// 一个原型BeanDefinition,会多次来创建Bean,那么就可以把该BeanDefinition所要使用的构造方法缓存起来,避免每次都进行构造方法推断
boolean resolved = false;
boolean autowireNecessary = false;
if (args == null) {
synchronized (mbd.constructorArgumentLock) {
if (mbd.resolvedConstructorOrFactoryMethod != null) {
resolved = true;
// autowireNecessary表示有没有必要要进行注入,比如当前BeanDefinition用的是无参构造方法,那么autowireNecessary为false,否则为true,表示需要给构造方法参数注入值
autowireNecessary = mbd.constructorArgumentsResolved;
}
}
}
if (resolved) {
// 如果确定了当前BeanDefinition的构造方法,那么看是否需要进行对构造方法进行参数的依赖注入(构造方法注入)依赖注入的一种
if (autowireNecessary) {
// 方法内会拿到缓存好的构造方法的入参
return autowireConstructor(beanName, mbd, null, null);
}
else {
// 构造方法已经找到了,但是没有参数,那就表示是无参,直接进行实例化
return instantiateBean(beanName, mbd);
}
}
// 如果没有找过构造方法,那么就开始找了
// Candidate constructors for autowiring?
// 提供一个扩展点,可以利用SmartInstantiationAwareBeanPostProcessor来控制用beanClass中的哪些构造方法
// 比如AutowiredAnnotationBeanPostProcessor会把加了@Autowired注解的构造方法找出来,具体看代码实现会更复杂一点
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
// 如果推断出来了构造方法,则需要给构造方法赋值,也就是给构造方法参数赋值,也就是构造方法注入
// 如果没有推断出来构造方法,但是autowiremode为AUTOWIRE_CONSTRUCTOR,则也可能需要给构造方法赋值,因为不确定是用无参的还是有参的构造方法
// 如果通过BeanDefinition指定了构造方法参数值,那肯定就是要进行构造方法注入了
// 如果调用getBean的时候传入了构造方法参数值,那肯定就是要进行构造方法注入了
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);
}
2.1 这一段代码
// BeanDefinition中添加了Supplier,则调用Supplier来得到对象
Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
if (instanceSupplier != null) {
return obtainFromSupplier(instanceSupplier, beanName);
}
2.1.1
mbd.getInstanceSupplier方法:获取自定义的接口Supplier的实现类
一般与mbd.setInstanceSupplier方法一起,用Supplier接口创建对象。
2.1.1.1
mbd.setInstanceSupplier方法:
BeanDefinition.setInstanceSupplier() 方法是在 BeanDefinition 对象上调用的,
用于设置实例的供应商(Supplier),并允许用户通过编程方式提供自定义的实例化逻辑。
BeanDefinition.setInstanceSupplier() 方法允许您对实例化过程进行更细粒度的控制,并提供了编程式的方式来自定义实例化逻辑。
例如,您可能希望根据特定条件选择不同的构造函数或参数来实例化 Bean。通过使用 setInstanceSupplier() 方法,您可以编写自定义的 Supplier 实现,并在其中执行逻辑来创建 Bean 实例。
2.1.1.2 具体例子
用户可以在spring容器中定义supplier接口 实现
//spring容器
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
//一个beandefinition对象
GenericBeanDefinition definition = new GenericBeanDefinition();
//beandefinition对象的操作,自定义的 Supplier 实现
definition.setBeanClass(Test.class);
TestSupplier testSupplier = new TestSupplier();
definition.setInstanceSupplier(testSupplier::getuser);
//spring容器中注册,刷新
ctx.registerBeanDefinition("b", definition);
ctx.refresh();
Book b = ctx.getBean("b", Test.class);
System.out.println("b = " + b);
其中:testSupplier::getuser 是调用对象testSupplier的getuser 方法,getuser是创建user对象的方法
方法引用使用(::)符号来调用方法。假设我们有一个MyUtil类和一个静态方法getFavoriteBook(),那么我们可以用类名来调用它。
MyUtil::getFavoriteBook
如果我们有非静态方法,我们可以使用类的实例来调用这个方法。
假设myUtil是MyUtil类的实例,getAge()是一个非静态方法,那么我们使用实例来调用它,如下所示。
myUtil::getAge
2.1.3 .obtainFromSupplier方法:
在判断beandefinition的InstanceSupplier不为空的时候调用,用supplier接口的实现类来获取bean对象
private final NamedThreadLocal<String> currentlyCreatedBean = new NamedThreadLocal<>("Currently created bean");
protected BeanWrapper obtainFromSupplier(Supplier<?> instanceSupplier, String beanName) {
Object instance;
String outerBean = this.currentlyCreatedBean.get();
this.currentlyCreatedBean.set(beanName);
try {
instance = instanceSupplier.get();//这里就是调用的实现类的方法
}
finally {
if (outerBean != null) {
this.currentlyCreatedBean.set(outerBean);
}
else {
this.currentlyCreatedBean.remove();
}
}
if (instance == null) {
instance = new NullBean();
}
//把bean包装成BeanWrapper
BeanWrapper bw = new BeanWrapperImpl(instance);
initBeanWrapper(bw);
return bw;
}
2.2 这一段
// @Bean对应的BeanDefinition
if (mbd.getFactoryMethodName() != null) {
return instantiateUsingFactoryMethod(beanName, mbd, args);
}
应用的地方:
01.
在 xml配置中,可以使用 factory-bean 和 factory-method 两个标签可以指定一个类中的方法,Spring会将这个指定的方法的返回值作为bean返回(如果方法是静态方法,则可以不创建factorybean就直接调用,否则需要先将factorybean注入到Spring中)。
02.
对@Bean 注解的解析。在 ConfigurationClassPostProcessor 后处理器中,会对被 @Bean 注解修饰的方法进行解析,生成一个 ConfigurationClassBeanDefinition的 BeanDefinition。此时BeanDefinition 的 factoryMethodName 正是 @Bean修饰的方法本身。所以这里会调用 instantiateUsingFactoryMethod 方法。通过回调的方式调用 @Bean修饰的方法。并将返回结果注入到Spring容器中。
2.2.1mbd.getFactoryMethodName方法:
获取beandefinition的FactoryMethodName属性。
等于xml文件中的bean标签里面配置了factory-method属性。
有两种使用方式:
1.一种是另外一个类中的非静态方法(@Bean就是这种);另一种是配置了class的这个类中的静态方法(静态构造方法)。
2.方法上加了@Bean注解
2.2.1.1 factory-method属性
在下面例子中,我们看到在bean标签的配置中,id为jack的bean标签是没有配置class属性的,配置了factory-bean属性指向了factorybean,配置了factory-method属性指向了实际生成bean(jack)的方法。factory-bean属性的值会封装进BeanDefinition的factoryBeanName属性中,factory-method属性的值会封装进BeanDefinition的factoryMethodName属性中。这时,这个方法(getjack)必须是非静态的。
<bean id="factorybean" class="com.zhouyu.factorybean" />
<bean id="jack" factory-bean="factorybean" factory-method="getjack"/>
public class factorybean {
public Object getjack() {
return new jack();
}
}
在下面的例子中,我们看到在bean标签的配置中,id为jack的bean标签配置了class属性,并配置了factory-method属性指向了这个类中的factoryMethod方法(也就是静态构造方法)。这时,这个方法必须是静态的。
<bean id="jack" class="com.zhouyu.jack" factory-method="getjack1"/>
package com.zhouyu;
public class jack {
public static jack getjack1() {
return new jack();
}
}
2.2.2 instantiateUsingFactoryMethod方法:
protected BeanWrapper instantiateUsingFactoryMethod(
String beanName, RootBeanDefinition mbd, @Nullable Object[] explicitArgs) {
// 使用factoryBean来实例化对象
return new ConstructorResolver(this).instantiateUsingFactoryMethod(beanName, mbd, explicitArgs);
}
public BeanWrapper instantiateUsingFactoryMethod(
String beanName, RootBeanDefinition mbd, @Nullable Object[] explicitArgs) {
//建BeanWrapperImpl的对象,该类是对beanInstance的再一次包装
BeanWrapperImpl bw = new BeanWrapperImpl();
this.beanFactory.initBeanWrapper(bw);
Object factoryBean;
Class<?> factoryClass;
boolean isStatic;
//获取bean标签的factory-bean属性的值,也就是BeanDefinition的factoryBeanName的属性值
// 注意,这里拿到的是factoryBeanName,而不是factoryMethodName,比如AppConfig对象
String factoryBeanName = mbd.getFactoryBeanName();
if (factoryBeanName != null) {
//如果factoryBeanName不为空,表明factory-method会指向别的类
if (factoryBeanName.equals(beanName)) {
throw new BeanDefinitionStoreException(mbd.getResourceDescription(), beanName,
"factory-bean reference points back to the same bean definition");
}
factoryBean = this.beanFactory.getBean(factoryBeanName);
// 该单例已经创建好了?
if (mbd.isSingleton() && this.beanFactory.containsSingleton(beanName)) {
throw new ImplicitlyAppearedSingletonException();
}
//注册这个依赖关系
this.beanFactory.registerDependentBean(factoryBeanName, beanName);
//
factoryClass = factoryBean.getClass();
isStatic = false;
}
else {
//如果factoryBeanName为空,表明factory-method会执行本标签的class属性代表的类,获取本BeanDefiniton的factoryClass属性
// It's a static factory method on the bean class.
// static的@Bean方法
if (!mbd.hasBeanClass()) {
throw new BeanDefinitionStoreException(mbd.getResourceDescription(), beanName,
"bean definition declares neither a bean class nor a factory-bean reference");
}
factoryBean = null;
factoryClass = mbd.getBeanClass();
isStatic = true;
}
Method factoryMethodToUse = null;
ArgumentsHolder argsHolderToUse = null;
Object[] argsToUse = null;
if (explicitArgs != null) {
argsToUse = explicitArgs;
}
else {
Object[] argsToResolve = null;
synchronized (mbd.constructorArgumentLock) {
factoryMethodToUse = (Method) mbd.resolvedConstructorOrFactoryMethod;
if (factoryMethodToUse != null && mbd.constructorArgumentsResolved) {
// Found a cached factory method...
argsToUse = mbd.resolvedConstructorArguments;
if (argsToUse == null) {
argsToResolve = mbd.preparedConstructorArguments;
}
}
}
if (argsToResolve != null) {
argsToUse = resolvePreparedArguments(beanName, mbd, bw, factoryMethodToUse, argsToResolve);
}
}
if (factoryMethodToUse == null || argsToUse == null) {
// Need to determine the factory method...
// Try all methods with this name to see if they match the given arguments.
factoryClass = ClassUtils.getUserClass(factoryClass);
List<Method> candidates = null;
if (mbd.isFactoryMethodUnique) {
if (factoryMethodToUse == null) {
factoryMethodToUse = mbd.getResolvedFactoryMethod();
}
if (factoryMethodToUse != null) {
candidates = Collections.singletonList(factoryMethodToUse);
}
}
// 找到对应的@Bean方法,由于可能参数重载,所以有可能会有多个
if (candidates == null) {
candidates = new ArrayList<>();
Method[] rawCandidates = getCandidateMethods(factoryClass, mbd);
for (Method candidate : rawCandidates) {
if (Modifier.isStatic(candidate.getModifiers()) == isStatic && mbd.isFactoryMethod(candidate)) {
candidates.add(candidate);
}
}
}
if (candidates.size() == 1 && explicitArgs == null && !mbd.hasConstructorArgumentValues()) {
Method uniqueCandidate = candidates.get(0);
if (uniqueCandidate.getParameterCount() == 0) {
mbd.factoryMethodToIntrospect = uniqueCandidate;
synchronized (mbd.constructorArgumentLock) {
mbd.resolvedConstructorOrFactoryMethod = uniqueCandidate;
mbd.constructorArgumentsResolved = true;
mbd.resolvedConstructorArguments = EMPTY_ARGS;
}
bw.setBeanInstance(instantiate(beanName, mbd, factoryBean, uniqueCandidate, EMPTY_ARGS));
return bw;
}
}
if (candidates.size() > 1) { // explicitly skip immutable singletonList
candidates.sort(AutowireUtils.EXECUTABLE_COMPARATOR);
}
ConstructorArgumentValues resolvedValues = null;
boolean autowiring = (mbd.getResolvedAutowireMode() == AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR);
int minTypeDiffWeight = Integer.MAX_VALUE;
Set<Method> ambiguousFactoryMethods = null;
int minNrOfArgs;
if (explicitArgs != null) {
minNrOfArgs = explicitArgs.length;
}
else {
// We don't have arguments passed in programmatically, so we need to resolve the
// arguments specified in the constructor arguments held in the bean definition.
if (mbd.hasConstructorArgumentValues()) {
ConstructorArgumentValues cargs = mbd.getConstructorArgumentValues();
resolvedValues = new ConstructorArgumentValues();
minNrOfArgs = resolveConstructorArguments(beanName, mbd, bw, cargs, resolvedValues);
}
else {
minNrOfArgs = 0;
}
}
Deque<UnsatisfiedDependencyException> causes = null;
for (Method candidate : candidates) {
int parameterCount = candidate.getParameterCount();
if (parameterCount >= minNrOfArgs) {
ArgumentsHolder argsHolder;
Class<?>[] paramTypes = candidate.getParameterTypes();
if (explicitArgs != null) {
// Explicit arguments given -> arguments length must match exactly.
if (paramTypes.length != explicitArgs.length) {
continue;
}
argsHolder = new ArgumentsHolder(explicitArgs);
}
else {
// Resolved constructor arguments: type conversion and/or autowiring necessary.
try {
// 根据参数类型和参数名找Bean
String[] paramNames = null;
ParameterNameDiscoverer pnd = this.beanFactory.getParameterNameDiscoverer();
if (pnd != null) {
paramNames = pnd.getParameterNames(candidate);
}
argsHolder = createArgumentArray(beanName, mbd, resolvedValues, bw,
paramTypes, paramNames, candidate, autowiring, candidates.size() == 1);
}
catch (UnsatisfiedDependencyException ex) {
if (logger.isTraceEnabled()) {
logger.trace("Ignoring factory method [" + candidate + "] of bean '" + beanName + "': " + ex);
}
// Swallow and try next overloaded factory method.
if (causes == null) {
causes = new ArrayDeque<>(1);
}
causes.add(ex);
continue;
}
}
int typeDiffWeight = (mbd.isLenientConstructorResolution() ?
argsHolder.getTypeDifferenceWeight(paramTypes) : argsHolder.getAssignabilityWeight(paramTypes));
// Choose this factory method if it represents the closest match.
if (typeDiffWeight < minTypeDiffWeight) {
factoryMethodToUse = candidate;
argsHolderToUse = argsHolder;
argsToUse = argsHolder.arguments;
minTypeDiffWeight = typeDiffWeight;
ambiguousFactoryMethods = null;
}
// Find out about ambiguity: In case of the same type difference weight
// for methods with the same number of parameters, collect such candidates
// and eventually raise an ambiguity exception.
// However, only perform that check in non-lenient constructor resolution mode,
// and explicitly ignore overridden methods (with the same parameter signature).
else if (factoryMethodToUse != null && typeDiffWeight == minTypeDiffWeight &&
!mbd.isLenientConstructorResolution() &&
paramTypes.length == factoryMethodToUse.getParameterCount() &&
!Arrays.equals(paramTypes, factoryMethodToUse.getParameterTypes())) {
if (ambiguousFactoryMethods == null) {
ambiguousFactoryMethods = new LinkedHashSet<>();
ambiguousFactoryMethods.add(factoryMethodToUse);
}
ambiguousFactoryMethods.add(candidate);
}
}
}
if (factoryMethodToUse == null || argsToUse == null) {
if (causes != null) {
UnsatisfiedDependencyException ex = causes.removeLast();
for (Exception cause : causes) {
this.beanFactory.onSuppressedException(cause);
}
throw ex;
}
List<String> argTypes = new ArrayList<>(minNrOfArgs);
if (explicitArgs != null) {
for (Object arg : explicitArgs) {
argTypes.add(arg != null ? arg.getClass().getSimpleName() : "null");
}
}
else if (resolvedValues != null) {
Set<ValueHolder> valueHolders = new LinkedHashSet<>(resolvedValues.getArgumentCount());
valueHolders.addAll(resolvedValues.getIndexedArgumentValues().values());
valueHolders.addAll(resolvedValues.getGenericArgumentValues());
for (ValueHolder value : valueHolders) {
String argType = (value.getType() != null ? ClassUtils.getShortName(value.getType()) :
(value.getValue() != null ? value.getValue().getClass().getSimpleName() : "null"));
argTypes.add(argType);
}
}
String argDesc = StringUtils.collectionToCommaDelimitedString(argTypes);
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"No matching factory method found on class [" + factoryClass.getName() + "]: " +
(mbd.getFactoryBeanName() != null ?
"factory bean '" + mbd.getFactoryBeanName() + "'; " : "") +
"factory method '" + mbd.getFactoryMethodName() + "(" + argDesc + ")'. " +
"Check that a method with the specified name " +
(minNrOfArgs > 0 ? "and arguments " : "") +
"exists and that it is " +
(isStatic ? "static" : "non-static") + ".");
}
else if (void.class == factoryMethodToUse.getReturnType()) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Invalid factory method '" + mbd.getFactoryMethodName() + "' on class [" +
factoryClass.getName() + "]: needs to have a non-void return type!");
}
else if (ambiguousFactoryMethods != null) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Ambiguous factory method matches found on class [" + factoryClass.getName() + "] " +
"(hint: specify index/type/name arguments for simple parameters to avoid type ambiguities): " +
ambiguousFactoryMethods);
}
if (explicitArgs == null && argsHolderToUse != null) {
mbd.factoryMethodToIntrospect = factoryMethodToUse;
argsHolderToUse.storeCache(mbd, factoryMethodToUse);
}
}
bw.setBeanInstance(instantiate(beanName, mbd, factoryBean, factoryMethodToUse, argsToUse));
return bw;
}
2.2.2.1 instantiateUsingFactoryMethod方法的这一段:
//建BeanWrapperImpl的对象,该类是对beanInstance的再一次包装
BeanWrapperImpl bw = new BeanWrapperImpl();
this.beanFactory.initBeanWrapper(bw);
Object factoryBean;
Class<?> factoryClass;
boolean isStatic;
//获取bean标签的factory-bean属性的值,也就是BeanDefinition的factoryBeanName的属性值
// 注意,这里拿到的是factoryBeanName,而不是factoryMethodName,比如AppConfig对象
String factoryBeanName = mbd.getFactoryBeanName();
if (factoryBeanName != null) {
//如果factoryBeanName不为空,表明factory-method会指向别的类
if (factoryBeanName.equals(beanName)) {
throw new BeanDefinitionStoreException(mbd.getResourceDescription(), beanName,
"factory-bean reference points back to the same bean definition");
}
factoryBean = this.beanFactory.getBean(factoryBeanName);
// 该单例已经创建好了?
if (mbd.isSingleton() && this.beanFactory.containsSingleton(beanName)) {
throw new ImplicitlyAppearedSingletonException();
}
//注册这个依赖关系
this.beanFactory.registerDependentBean(factoryBeanName, beanName);
//
factoryClass = factoryBean.getClass();
isStatic = false;
}
else {
//如果factoryBeanName为空,表明factory-method会执行本标签的class属性代表的类,获取本BeanDefiniton的factoryClass属性
// It's a static factory method on the bean class.
// static的@Bean方法
if (!mbd.hasBeanClass()) {
throw new BeanDefinitionStoreException(mbd.getResourceDescription(), beanName,
"bean definition declares neither a bean class nor a factory-bean reference");
}
factoryBean = null;
factoryClass = mbd.getBeanClass();
isStatic = true;
}
获取factoryClass及isStatic的属性值
1、新建BeanWrapperImpl的对象,该类是对beanInstance的再一次包装;
2、获取bean标签的factory-bean属性的值,也就是BeanDefinition的factoryBeanName的属性值;
3、如果factoryBeanName不为空,表明factory-method会指向别的类,先去实例化这个类,并取到这个bean的class值赋值给factoryClass属性;并将isStatic赋值为false,表示factory-method指向的方法为非静态的。
4、如果factoryBeanName为空,表明factory-method会执行本标签的class属性代表的类,获取本BeanDefiniton的factoryClass属性;并将isStatic赋值为true,表示factory-method指向的方法为静态的。
2.2.2.2 这一段
/**用于缓存已解析的构造函数或工厂方法的包可见字段。. */
@Nullable
Executable resolvedConstructorOrFactoryMethod;
/** 标记构造函数参数为已解析的包可见字段. */
boolean constructorArgumentsResolved = false;
Method factoryMethodToUse = null;
// ArgumentsHolder 参数持有者
ArgumentsHolder argsHolderToUse = null;
Object[] argsToUse = null;
if (explicitArgs != null) {
argsToUse = explicitArgs;
}
else {
Object[] argsToResolve = null;
synchronized (mbd.constructorArgumentLock) {
factoryMethodToUse = (Method) mbd.resolvedConstructorOrFactoryMethod;
if (factoryMethodToUse != null && mbd.constructorArgumentsResolved) {
// Found a cached factory method...
argsToUse = mbd.resolvedConstructorArguments;
if (argsToUse == null) {
argsToResolve = mbd.preparedConstructorArguments;
}
}
}
if (argsToResolve != null) {
argsToUse = resolvePreparedArguments(beanName, mbd, bw, factoryMethodToUse, argsToResolve);
}
}
获取factoryMethodToUse和argsToUse:
1、新建一些使用的对象;
2、如果有配置了参数则获取参数;
3、没有配置参数的话就去mbd里面找找有没有已经处理过的结果值,第一次进来的实例化的时候显然是没有的。
2.2.2.3
1、如果BeanDefiniton的isFactoryMethodUnique有属性值,就走上面的逻辑,不常见。
2、否则,通过getCandidateMethods()方法获得该类下的所有方法,包括继承自Object的方法。通过反射工具类ReflectionUtils反射获取。
3、遍历这些rawCandidates,将静态情况符合条件的和factory-method名字符合条件的加入candidates集合中。
1、判断有几个候选的factory-method,只有一个的话就走下面的逻辑,我们上面举的例子就是走这一条分支。
2、给mbd的个属性赋值,下次进来的时候就可以直接获取,而不用再次解析。
3、实例化Instance
调用实例化方法进行实例化instance()
很显然,这个地方就是反射调用方法进行bean的实例化。
2.3 构造函数的缓存判断
到达这一步,Spring则打算通过bean的构造函数来创建bean。但是一个bean可能会存在多个构造函数,这时候Spring会根据参数列表的来判断使用哪个构造函数进行实例化。但是判断过程比较消耗性能,所以Spring将判断好的构造函数缓存到RootBeanDefinition 中,如果不存在缓存则进行构造函数的筛选并缓存解析结果。RootBeanDefinition 中具体的缓存属性有如下几个:
resolvedConstructorOrFactoryMethod : 用于缓存已解析的构造函数或工厂方法
constructorArgumentsResolved :这个字段有两层含义: 一,标记构造函数是否已经完成解析。二,标志这个bean的加载是否 需要通过构造注入(autowireConstructor) 的方式加载。因为只有在 autowireConstructor 方法中才会将其置为 true。
resolvedConstructorArguments : 缓存解析好的构造函数的入参
// 是否已经完成解析
boolean resolved = false;
// 标志构造函数参数是否解析完成
boolean autowireNecessary = false;
if (args == null) {
synchronized (mbd.constructorArgumentLock) {
if (mbd.resolvedConstructorOrFactoryMethod != null) {
resolved = true;
autowireNecessary = mbd.constructorArgumentsResolved;
}
}
}
if (resolved) {
if (autowireNecessary) {
// 需要自动注入
return autowireConstructor(beanName, mbd, null, null);
}
else {
// 使用其默认构造函数实例化给定的bean。
return instantiateBean(beanName, mbd);
}
}
// 如果 resolved = false 则会执行第六步
2.4 这一段:第一次会走这里 实例化带有@Autowired注解的有参构造函数。
1、通过BeanPostProcessor的方式获得带有@Autowired注解的构造函数集合
2、实例化beanInstance
// Candidate constructors for autowiring?
// 提供一个扩展点,可以利用SmartInstantiationAwareBeanPostProcessor来控制用beanClass中的哪些构造方法
// 比如AutowiredAnnotationBeanPostProcessor会把加了@Autowired注解的构造方法找出来,具体看代码实现会更复杂一点
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
// 如果推断出来了构造方法,则需要给构造方法赋值,也就是给构造方法参数赋值,也就是构造方法注入
// 如果没有推断出来构造方法,但是autowiremode为AUTOWIRE_CONSTRUCTOR,则也可能需要给构造方法赋值,因为不确定是用无参的还是有参的构造方法
// 如果通过BeanDefinition指定了构造方法参数值,那肯定就是要进行构造方法注入了
// 如果调用getBean的时候传入了构造方法参数值,那肯定就是要进行构造方法注入了
if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
return autowireConstructor(beanName, mbd, ctors, args);
}
2.4.1 什么是带有@Autowired注解的构造函数
举个栗子
第一种情况:有一个带有@Autowired注解的构造函数
结论:正常实例化
第二种情况:有多个带有@Autowired注解的构造函数
结论:报异常
怎么解决呢?
答案:在@Autowired注解中加required=false属性设置
2.4.2 determineConstructorsFromBeanPostProcessors方法:
推断确定使用的构造函数
@Nullable
protected Constructor<?>[] determineConstructorsFromBeanPostProcessors(@Nullable Class<?> beanClass, String beanName)
throws BeansException {
if (beanClass != null && hasInstantiationAwareBeanPostProcessors()) {
for (SmartInstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().smartInstantiationAware) {
Constructor<?>[] ctors = bp.determineCandidateConstructors(beanClass, beanName);
if (ctors != null) {
return ctors;
}
}
}
return null;
}
此时符合条件的BeanPostProcessor是AutowiredAnnotationBeanPostProcessor。
determineCandidateConstructors方法:
01.有且仅有一个@Autowired(required = true)注解标注的构造方法,不能出现其他有@Autowired注解标注的构造方法
02.有多个@Autowired(required = false)注解标注的构造方法,没有@Autowired(required = true)注解标注的构造方法(如果存在defaultConstructor,则将defaultConstructor也加入候选构造方法)
03.不存在@Autowired注解标注的构造方法,有唯一一个有参构造方法
@Override
@Nullable
public Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, final String beanName)
throws BeanCreationException {
// Let's check for lookup methods here...
if (!this.lookupMethodsChecked.contains(beanName)) {
// 判断beanClass是不是java.开头的类,比如String
if (AnnotationUtils.isCandidateClass(beanClass, Lookup.class)) {
try {
Class<?> targetClass = beanClass;
do {
// 遍历targetClass中的method,查看是否写了@Lookup方法
ReflectionUtils.doWithLocalMethods(targetClass, method -> {
Lookup lookup = method.getAnnotation(Lookup.class);
if (lookup != null) {
Assert.state(this.beanFactory != null, "No BeanFactory available");
// 将当前method封装成LookupOverride并设置到BeanDefinition的methodOverrides中
LookupOverride override = new LookupOverride(method, lookup.value());
try {
RootBeanDefinition mbd = (RootBeanDefinition)
this.beanFactory.getMergedBeanDefinition(beanName);
mbd.getMethodOverrides().addOverride(override);
}
catch (NoSuchBeanDefinitionException ex) {
throw new BeanCreationException(beanName,
"Cannot apply @Lookup to beans without corresponding bean definition");
}
}
});
targetClass = targetClass.getSuperclass();
}
while (targetClass != null && targetClass != Object.class);
}
catch (IllegalStateException ex) {
throw new BeanCreationException(beanName, "Lookup method resolution failed", ex);
}
}
this.lookupMethodsChecked.add(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 {
// 拿到所有的构造方法
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);
// 用来记录required为true的构造方法,一个类中只能有一个required为true的构造方法
Constructor<?> requiredConstructor = null;
// 用来记录默认无参的构造方法
Constructor<?> defaultConstructor = null;
// kotlin相关,不用管
Constructor<?> primaryConstructor = BeanUtils.findPrimaryConstructor(beanClass);
int nonSyntheticConstructors = 0;
// 遍历每个构造方法
for (Constructor<?> candidate : rawCandidates) {
if (!candidate.isSynthetic()) {
// 记录一下普通的构造方法
nonSyntheticConstructors++;
}
else if (primaryConstructor != null) {
continue;
}
// 当前遍历的构造方法是否写了@Autowired
MergedAnnotation<?> ann = findAutowiredAnnotation(candidate);
if (ann == null) {
// 如果beanClass是代理类,则得到被代理的类的类型
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...
}
}
}
// 当前构造方法上加了@Autowired
if (ann != null) {
// 整个类中如果有一个required为true的构造方法,那就不能有其他的加了@Autowired的构造方法
if (requiredConstructor != null) {
throw new BeanCreationException(beanName,
"Invalid autowire-marked constructor: " + candidate +
". Found constructor with 'required' Autowired annotation already: " +
requiredConstructor);
}
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的构造方法
requiredConstructor = candidate;
}
// 记录所有加了@Autowired的构造方法,不管required是true还是false
// 如果默认无参的构造方法上也加了@Autowired,那么也会加到candidates中
candidates.add(candidate);
// 从上面代码可以得到一个结论,在一个类中,要么只能有一个required为true的构造方法,要么只能有一个或多个required为false的方法
}
else if (candidate.getParameterCount() == 0) {
// 记录唯一一个无参的构造方法
defaultConstructor = candidate;
}
// 有可能存在有参、并且没有添加@Autowired的构造方法
}
if (!candidates.isEmpty()) {
// Add default constructor to list of optional constructors, as fallback.
// 如果不存在一个required为true的构造方法,则所有required为false的构造方法和无参构造方法都是合格的
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));
}
}
// 如果只存在一个required为true的构造方法,那就只有这一个是合格的
candidateConstructors = candidates.toArray(new Constructor<?>[0]);
}
// 没有添加了@Autowired注解的构造方法,并且类中只有一个构造方法,并且是有参的
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 {
// 如果有多个有参、并且没有添加@Autowired的构造方法,是会返回空的
candidateConstructors = new Constructor<?>[0];
}
this.candidateConstructorsCache.put(beanClass, candidateConstructors);
}
}
}
return (candidateConstructors.length > 0 ? candidateConstructors : null);
}
lookup方法:
构造方法:
01.先从缓存中取:
02.缓存中取不到就开始解析,我们看到跟获取factory-method的过程类似,先获取对应bean的所有的构造方法存储在rawCandidates,再根据条件获得candidates。还有两个属性:requiredConstructor和defaultConstructor,后面会用这两个属性参与一些判断:
03.循环
1、for循环中遍历处理rawCandidates(所有的构造函数)
2、获取该构造函数上的@Autowired的注解信息,有没有,以及各种属性信息
3、如果有,会判断requiredConstructor属性是否为null,不为null的话,会抛出异常,这个就是我们开始举例子中说到的有多个构造函数带有@Autowired注解会出错的原因。(初始化是null,经过一次循环后)
4、获得@Autowired注解上的属性required的值。如果不设置,默认为true。
5、如果值为true,将该构造函数赋值给requiredConstructor,回到第3步,若有多个构造函数带有@Autowired注解并且required属性为默认属性,那么第二个rawCandidate进来的时候就会报异常了。
6、将该构造函数加入candidates的列表中。
7、
04.
正常情况下,cadidates中会有所有有@Autowired注解的构造函数,这些都是@Autowired(required = false),转化为数组赋值给candidateConstructors,添加缓存,并返回。
@Override
@Nullable
public Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, final String beanName) throws BeanCreationException {
// 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 {
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相关的类 查找primaryConstructor
Constructor<?> primaryConstructor = BeanUtils.findPrimaryConstructor(beanClass);
// 记录有多少个非合成的构造方法,主要针对两种情况
// case1:只有1个非合成的构造方法(primaryConstructor)
// case2:存在2个非合成的构造方法(primaryConstructor + defaultConstructor)
int nonSyntheticConstructors = 0;
for (Constructor<?> candidate : rawCandidates) {
// 判断是不是非合成的构造方法,不是合成的构造方法参数nonSyntheticConstructors自增1
if (!candidate.isSynthetic()) {
nonSyntheticConstructors++;
}
// Kotlin是不是存在合成构造方法的概念?
// 如果存在,针对上面的case1已经可以找到候选的构造方法了,所以不倾向使用这些合成的构造方法
else if (primaryConstructor != null) {
continue;
}
// 查看构造器是否含有@Autowired注解
MergedAnnotation<?> ann = findAutowiredAnnotation(candidate);
if (ann == null) {
// 如果构造器没有@Autowired注解,则查看类名是否包含$$字符
// 如果存在此特殊字符,表明此类是cglib动态代理产生的子类
// 这时候需要从父类的构造器查看是否含有@Autowired注解
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...
}
}
}
// 能进入此条件表明查询到包含@Autowired注解的构造器
if (ann != null) {
// 1.如果存在一个@Autowired(required = true)注解标注的构造方法
// 则不能再出现@Autowired注解标注的构造方法(无论required等于true或false都报错)
// 2.可以有多个@Autowired(required = false)注解标注的构造方法
// 表明已经解析了一个@Autowired(required = true)注解标注的构造方法
// 不能再出现@Autowired注解标注的构造方法
// TODO 1
if (requiredConstructor != null) {
throw new BeanCreationException(beanName,
"Invalid autowire-marked constructor: " + candidate +
". Found constructor with 'required' Autowired annotation already: " +
requiredConstructor);
}
boolean required = determineRequiredStatus(ann);
if (required) {
// 如果条件成立,表明至少解析了一个@Autowired(required = false)注解标注的构造方法
// PS:如果同时存在@Autowired(required = true)注解标注的构造方法和@Autowired(required = false)注解标注的构造方法
// 如果先解析@Autowired(required = true)注解标注的构造方法,则在TODO 1处抛出异常
// 如果先解析@Autowired(required = false)注解标注的构造方法,则在TODO 2处抛出异常
// TODO 2
if (!candidates.isEmpty()) {
throw new BeanCreationException(beanName,
"Invalid autowire-marked constructors: " + candidates +
". Found constructor with 'required' Autowired annotation: " +
candidate);
}
// 表明是第一次解析@Autowired(required = true)注解标注的构造方法
requiredConstructor = candidate;
}
// 这个候选者可以是第一次解析@Autowired(required = true)注解标注的构造方法
// 或者前面解析了n个@Autowired(required = false)注解标注的构造方法,这次解析的同样是
// @Autowired(required = false)注解标注的构造方法
candidates.add(candidate);
}
// 如果没有@Autowired注解标注的构造方法,则将无参构造方法设为defaultConstructor
else if (candidate.getParameterCount() == 0) {
defaultConstructor = candidate;
}
}
// 第一优先级:存在候选构造方法
if (!candidates.isEmpty()) {
// Add default constructor to list of optional constructors, as fallback.
if (requiredConstructor == null) {
// 解析了n个@Autowired(required = false)注解标注的构造方法
// 并且将默认构造方法也当成候选构造方法返回
if (defaultConstructor != null) {
candidates.add(defaultConstructor);
}
// 这里可能存在两种情况:
// 第一种情况:只有一个无参构造方法,并且标记了@Autowired(required = false)注解
// 第二种情况:只有一个有参构造方法,并且标记了@Autowired(required = false)注解
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));
}
}
candidateConstructors = candidates.toArray(new Constructor<?>[0]);
}
// 第二优先级:只有一个构造方法 且参数大于0
// PS:不存在@Autowired注解标注的构造方法,不存在无参构造方法
else if (rawCandidates.length == 1 && rawCandidates[0].getParameterCount() > 0) {
candidateConstructors = new Constructor<?>[]{rawCandidates[0]};
}
// 第三优先级:如果有两个非合成的构造方法,且一个对应primaryConstructor 一个对应defaultConstructor
// 主要针对Kotlin相关的类
else if (nonSyntheticConstructors == 2 && primaryConstructor != null &&
defaultConstructor != null && !primaryConstructor.equals(defaultConstructor)) {
candidateConstructors = new Constructor<?>[]{primaryConstructor, defaultConstructor};
}
// 第四优先级:有且只有一个非合成的构造方法,且对应primaryConstructor
// 主要针对Kotlin相关的类
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);
}
2.5
autowireConstructor方法:就是根据传入的参数列表,来匹配到合适的构造函数进行bean 的创建。
// chosenCtors : 候选构造函数列表, 没有则为null
// explicitArgs : 通过getBean方法以编程方式传递的参数值,
public BeanWrapper autowireConstructor(String beanName, RootBeanDefinition mbd,
@Nullable Constructor<?>[] chosenCtors, @Nullable Object[] explicitArgs) {
BeanWrapperImpl bw = new BeanWrapperImpl();
this.beanFactory.initBeanWrapper(bw);
// 候选的构造函数列表
Constructor<?> constructorToUse = null;
ArgumentsHolder argsHolderToUse = null;
// 构造函数最后确定使用的参数
Object[] argsToUse = null;
// 1. 解析构造函数参数
// explicitArgs 参数是通过 getBean 方法传入
// 如果 getBean在调用时传入了参数,那么直接使用即可。getBean 调用的传参,不用从缓存中获取构造函数,需要进行筛选匹配(个人理解,getBean 方法的入参可能并不相同,缓存的构造函数可能并不适用)
if (explicitArgs != null) {
argsToUse = explicitArgs;
}
else {
// 否则 尝试从 BeanDefinition 中加载缓存的bean构造时需要的参数
Object[] argsToResolve = null;
// 加锁
synchronized (mbd.constructorArgumentLock) {
// 从缓存中获取要使用的构造函数。没有缓存则为null
constructorToUse = (Constructor<?>) mbd.resolvedConstructorOrFactoryMethod;
// 如果构造函数不为空 && 构造函数参数已经解析
if (constructorToUse != null && mbd.constructorArgumentsResolved) {
// Found a cached constructor...
// 从缓存中获取。这里如果不能获取到完全解析好的参数,则获取尚未解析的参数,进行解析后再赋值给 argsToUse
// resolvedConstructorArguments 是完全解析好的构造函数参数
argsToUse = mbd.resolvedConstructorArguments;
if (argsToUse == null) {
// 配置构造函数参数
// preparedConstructorArguments 是尚未完全解析的构造函数参数
argsToResolve = mbd.preparedConstructorArguments;
}
}
}
// 如果缓存中存在 尚未完全解析的参数列表,则进行进一步的解析
if (argsToResolve != null) {
// 解析参数类型,如给定的参数列表为(int,int),这时就会将配置中的("1", "1") 转化为 (1,1)
// 缓存中的值可能是最终值,也可能是原始值,因为不一定需要类型转换
argsToUse = resolvePreparedArguments(beanName, mbd, bw, constructorToUse, argsToResolve, true);
}
}
// 如果构造函数 和 构造函数入参都不为空,则可以直接生成bean。否则的话,需要通过一定的规则进行筛选
if (constructorToUse == null || argsToUse == null) {
// Take specified constructors, if any.
// chosenCtors 是候选的构造函数,如果存在候选的构造函数,则跳过这里,否则通过反射获取bean的构造函数集合
// 2. 获取候选的构造参数列表
Constructor<?>[] candidates = chosenCtors;
if (candidates == null) {
Class<?> beanClass = mbd.getBeanClass();
try {
// 反射获取bean的构造函数集合
candidates = (mbd.isNonPublicAccessAllowed() ?
beanClass.getDeclaredConstructors() : beanClass.getConstructors());
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Resolution of declared constructors on bean Class [" + beanClass.getName() +
"] from ClassLoader [" + beanClass.getClassLoader() + "] failed", ex);
}
}
// 如果构造函数只有一个 && getBean 没有传参 && 构造参数无参
// 满足上述三个条件,则无需继续筛选构造函数,直接使用唯一一个构造函数创建 BeanWrapper 并返回即可。
if (candidates.length == 1 && explicitArgs == null && !mbd.hasConstructorArgumentValues()) {
Constructor<?> uniqueCandidate = candidates[0];
// 确定该构造函数无参
if (uniqueCandidate.getParameterCount() == 0) {
synchronized (mbd.constructorArgumentLock) {
// 将解析结束的信息缓存到 mdb中
// 缓存解析出来的唯一构造函数
mbd.resolvedConstructorOrFactoryMethod = uniqueCandidate;
// 标记构造函数已经完全解析
mbd.constructorArgumentsResolved = true;
// 缓存解析好的构造函数参数。这里是空数组 (Object[] EMPTY_ARGS = new Object[0];)
mbd.resolvedConstructorArguments = EMPTY_ARGS;
}
// 调用 instantiate 方法创建对象实例并保存到 bw中
bw.setBeanInstance(instantiate(beanName, mbd, uniqueCandidate, EMPTY_ARGS));
return bw;
}
}
// Need to resolve the constructor.
// 待选构造函数列表不为null || 需要构造注入,则需要解析。
// mbd.getResolvedAutowireMode() 是针对 xml 注入的
boolean autowiring = (chosenCtors != null ||
mbd.getResolvedAutowireMode() == AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR);
ConstructorArgumentValues resolvedValues = null;
// 3. 解析出来的构造函数的个数
int minNrOfArgs;
// 如果explicitArgs 不为空,直接使用它作为参数,毕竟是传入的参数,没必要再从进一步解析。
if (explicitArgs != null) {
minNrOfArgs = explicitArgs.length;
}
else {
// 获取xml配置文件中的配置的构造函数参数
ConstructorArgumentValues cargs = mbd.getConstructorArgumentValues();
// 用于承载解析后的构造函数参数的值
resolvedValues = new ConstructorArgumentValues();
// 确定解析到的构造函数参数个数并进行类型转换匹配。在下面有详细解读
minNrOfArgs = resolveConstructorArguments(beanName, mbd, bw, cargs, resolvedValues);
}
// 4. 寻找最匹配的构造函数
// 对构造函数列表进行排序: public 构造函数优先参数数量降序,非public构造函数参数数量降序
AutowireUtils.sortConstructors(candidates);
int minTypeDiffWeight = Integer.MAX_VALUE;
Set<Constructor<?>> ambiguousConstructors = null;
LinkedList<UnsatisfiedDependencyException> causes = null;
// 遍历构造函数,寻找合适的构造函数
for (Constructor<?> candidate : candidates) {
// 获取当前构造函数参数个数
int parameterCount = candidate.getParameterCount();
// 如果已经找到选用的构造函数 (argstoUse != null) 或者 需要的构造函数的参数个数 小于 当前构造函数参数个数 则终止
// constructorToUse != null 说明找到了构造函数
// argsToUse != null 说明参数已经赋值
// argsToUse.length > parameterCount
// 即已经找到适配的构造函数(可能不是最终的,但参数数量一定相同), 预选构造函数的参数数量 大于 当前构造函数的数量,可以直接break,因为按照参数数量降序排序,这里如果小于就没有必要继续比较下去
if (constructorToUse != null && argsToUse != null && argsToUse.length > parameterCount) {
// Already found greedy constructor that can be satisfied ->
// do not look any further, there are only less greedy constructors left.
break;
}
if (parameterCount < minNrOfArgs) {
// 参数数量不相等,跳过
continue;
}
// 到这里说明尚未找到构造函数,且目前的构造函数和需要的构造函数参数个数相同,下面要对类型进行比较。
ArgumentsHolder argsHolder;
Class<?>[] paramTypes = candidate.getParameterTypes();
// 如果构造函数存在参数,resolvedValues 是上面解析后的构造函数,有参则根据 值 构造对应参数类型的参数
if (resolvedValues != null) {
try {
// 获取参数名称
// 从 @ConstructorProperties 注解上获取参数名称
String[] paramNames = ConstructorPropertiesChecker.evaluate(candidate, parameterCount);
// 为null则说明没有使用注解
if (paramNames == null) {
// 获取参数名称探索器
ParameterNameDiscoverer pnd = this.beanFactory.getParameterNameDiscoverer();
if (pnd != null) {
// 获取指定的构造函数的参数名称
paramNames = pnd.getParameterNames(candidate);
}
}
// 根据类型和数据类型创建 参数持有者
// 这里会调用 DefaultListableBeanFactory#resolveDependency 方法来解析依赖关系
argsHolder = createArgumentArray(beanName, mbd, resolvedValues, bw, paramTypes, paramNames,
getUserDeclaredConstructor(candidate), autowiring, candidates.length == 1);
}
catch (UnsatisfiedDependencyException ex) {
if (logger.isTraceEnabled()) {
logger.trace("Ignoring constructor [" + candidate + "] of bean '" + beanName + "': " + ex);
}
// Swallow and try next constructor.
if (causes == null) {
causes = new LinkedList<>();
}
causes.add(ex);
continue;
}
}
else {
// 如果构造函数为默认构造函数,没有参数,如果参数不完全一致则跳过
// Explicit arguments given -> arguments length must match exactly.
if (parameterCount != explicitArgs.length) {
continue;
}
// 构造函数没有参数的情况
argsHolder = new ArgumentsHolder(explicitArgs);
}
// 探测是否有不确定性的构造函数存在,例如不同构造函数的参数为父子关系
int typeDiffWeight = (mbd.isLenientConstructorResolution() ?
argsHolder.getTypeDifferenceWeight(paramTypes) : argsHolder.getAssignabilityWeight(paramTypes));
// Choose this constructor if it represents the closest match.
// 如果他是当前最接近匹配则选择作为构造函数,因为可能有多个构造函数都同时满足,比如构造函数参数类型全是 Object,选择最合适的(typeDiffWeight 最小的)作为最终构造函数
if (typeDiffWeight < minTypeDiffWeight) {
// 找到最匹配的构造函数赋值保存
constructorToUse = candidate;
argsHolderToUse = argsHolder;
argsToUse = argsHolder.arguments;
minTypeDiffWeight = typeDiffWeight;
ambiguousConstructors = null;
}
else if (constructorToUse != null && typeDiffWeight == minTypeDiffWeight) {
// 如果 已经找到候选构造函数,且当前这个构造函数也有相同的类似度则保存到 ambiguousConstructors 中。后面用于抛出异常
if (ambiguousConstructors == null) {
ambiguousConstructors = new LinkedHashSet<>();
ambiguousConstructors.add(constructorToUse);
}
ambiguousConstructors.add(candidate);
}
}
// 如果 constructorToUse 构造函数为 null,则查找构造函数失败,抛出异常
if (constructorToUse == null) {
if (causes != null) {
UnsatisfiedDependencyException ex = causes.removeLast();
for (Exception cause : causes) {
this.beanFactory.onSuppressedException(cause);
}
throw ex;
}
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Could not resolve matching constructor " +
"(hint: specify index/type/name arguments for simple parameters to avoid type ambiguities)");
}
// 如果ambiguousConstructors 不为空说明有多个构造函数可适配,并且 如果不允许多个存在,则抛出异常
else if (ambiguousConstructors != null && !mbd.isLenientConstructorResolution()) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Ambiguous constructor matches found in bean '" + beanName + "' " +
"(hint: specify index/type/name arguments for simple parameters to avoid type ambiguities): " +
ambiguousConstructors);
}
// 将解析的构造函数加入缓存
if (explicitArgs == null && argsHolderToUse != null) {
argsHolderToUse.storeCache(mbd, constructorToUse);
}
}
Assert.state(argsToUse != null, "Unresolved constructor arguments");
// 将构建的实例加入BeanWrapper 中
bw.setBeanInstance(instantiate(beanName, mbd, constructorToUse, argsToUse));
return bw;
}
01.根据候选构造函数数组进行实例化:
02.与使用factory-method方法实例化过程类似,先新建一个BeanWrapperImpl的实例,在从mbd中判断是否已经处理过,第一次进来肯定没处理过,第一次处理过后各种属性值就会赋值给mbd的各种属性,后面再进来这段代码就生效了。
resolvedConstructorOrFactoryMethod : 用于缓存已解析的构造函数或工厂方法
constructorArgumentsResolved :这个字段有两层含义: 一,标记构造函数是否已经完成解析。二,标志这个bean的加载是否 需要通过构造注入(autowireConstructor) 的方式加载。因为只有在 autowireConstructor 方法中才会将其置为 true。
resolvedConstructorArguments : 缓存解析好的构造函数的入参
03.
接下来就根据传进来的candidates进行处理了。
如果传进来的是null,就会走默认方法。
如果传进来的数组只有一个候选值,并且无参(就是无参构造方法),就直接走instantiate()方法进行实例化,跟进去就会发现也是使用反射的方式进行的实例化。有参数的话就需要对参数进行处理:
对所有的候选构造参数进行排序,排序的依据是各个构造函数的参数的个数。
在循环中依次处理candidates;
这里面有两个短路方法,一个是如果之前已经找到了合适的构造函数,下一个candidate进来的时候就直接break,另一个是如果参数个数不符合要求,直接下一个。
最后根据找到的合适的构造函数进行实例化并返回。都是反射。
实例化没有@Autowired注解的有参构造函数。
举个栗子
第一种情况:只有一个无注解有参数的构造函数
结果:正常使用该构造函数初始化
第二种情况:有多个无注解有参数的构造函数
结果:发生异常 No default constructor found; nested exception is java.lang.NoSuchMethodException
怎么解决:添加一个无参数的构造函数
只有一个无注解有参数的构造函数
这种情况的入口跟带注解的构造函数的入口是一样的,走的也是determineConstructorsFromBeanPostProcessors()
但是返回的时候跟有@Autowired注解走的路径是不一样的。
如下图所示,如果没有有@Autowired注解的构造函数,就会走到标箭头的这个if中,看if的条件我们可以知道是只有一个构造函数并且该构造函数的参数个数大于0;
返回之后就和有@Autowired注解的构造函数实例化是一样的。
实例化有多个无注解有参数的构造函数
还是看上面那张图,有多个无注解有参数的构造函数在寻找candidateConstructors的时候会走到最后的else中,实例化candidateConstructors这个数组,但是里面什么都没有。看return语句我们发现如果这个数组里面没东西,会直接返回null。
返回null之后就不会再走有参构造函数的实例化过程,而是进行无参构造函数的实例化。
如果没有实现无参构造函数的话,就会抛出上述的异常。
实例化无参构造函数
有两种情况:
1、一个类中没有自定义的构造函数,那么Java会默认带一个无参构造函数;
2、用户自己新建了无参构造函数。如果用户自定义了有参构造函数,不手动创建无参构造函数的话,Java也不会创建无参构造函数。
入口:instantiateBean(beanName,mbd)
与上面有点区别的是,这块的实例化的逻辑是先实例化beanInstance,再封装进BeanWrapperImpl中。
进入初始化方法,可以看到会根据类获取构造函数,如果获取不到,就会抛出异常。前面所说的有多个有参构造函数但没有手动创建无参构造函数的异常就是这里抛出去的。