先贴一下自己写的代码
public class Person1 {
private int id;
private String name;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public Person1() {
}
public Person1(int id, String name) {
this.id = id;
this.name = name;
}
public Person1(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="com.mashibing"></context:component-scan>
<bean id="person" class="com.mashibing.Person" >
<property name="id" value="1"></property>
<property name="name" value="zhangsan"></property>
<!-- <constructor-arg name="id" value="1"></constructor-arg>-->
<!-- <constructor-arg name="name" value="lisi"></constructor-arg>-->
</bean>
</beans>
ApplicationContext ac = new ClassPathXmlApplicationContext("person.xml");
Person bean = ac.getBean(Person.class);
Person bean2 = ac.getBean(Person.class);
接下来我们看一下源码里面是怎么走的,断点打到createBean-->doCreateBean-->createBeanInstance
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
// Make sure bean class is actually resolved at this point.
// 确认需要创建的bean实例的类可以实例化
Class<?> beanClass = resolveBeanClass(mbd, beanName);
// 确保class不为空,并且访问权限是public
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中是否包含实例供应器,此处相当于一个回调方法,利用回调方法来创建bean
Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
if (instanceSupplier != null) {
return obtainFromSupplier(instanceSupplier, beanName);
}
// 如果工厂方法不为空则使用工厂方法初始化策略
if (mbd.getFactoryMethodName() != null) {
return instantiateUsingFactoryMethod(beanName, mbd, args);
}
// 一个类可能有多个构造器,所以Spring得根据参数个数、类型确定需要调用的构造器
// 在使用构造器创建实例后,Spring会将解析过后确定下来的构造器或工厂方法保存在缓存中,避免再次创建相同bean时再次解析
// Shortcut when re-creating the same bean...
// 标记下,防止重复创建同一个bean
boolean resolved = false;
// 是否需要自动装配
boolean autowireNecessary = false;
// 如果没有参数
if (args == null) {
synchronized (mbd.constructorArgumentLock) {
// 因为一个类可能由多个构造函数,所以需要根据配置文件中配置的参数或传入的参数来确定最终调用的构造函数。
// 因为判断过程会比较,所以spring会将解析、确定好的构造函数缓存到BeanDefinition中的resolvedConstructorOrFactoryMethod字段中。
// 在下次创建相同时直接从RootBeanDefinition中的属性resolvedConstructorOrFactoryMethod缓存的值获取,避免再次解析
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);
}
}
// Candidate constructors for autowiring?
// 从bean后置处理器中为自动装配寻找构造方法, 有且仅有一个有参构造或者有且仅有@Autowired注解构造
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
// 以下情况符合其一即可进入
// 1、存在可选构造方法
// 2、自动装配模型为构造函数自动装配
// 3、给BeanDefinition中设置了构造参数值
// 4、有参与构造函数参数列表的参数
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.
// 使用默认无参构造函数创建对象,如果没有无参构造且存在多个有参构造且没有@AutoWired注解构造,会报错
return instantiateBean(beanName, mbd);
}
之前我们了解了supplier方法和factoryMethod方法创建实例,下面解释用反射的方法创建实例
①无参创建对象
申明两个变量,因为resolvedConstructorOrFactoryMethod还没赋值,默认为空,所以没有进入,resolve为false,也没进去,直接走到下面代码
determineConstructorsFromBeanPostProcessors从名字可以看出从beanPostProcessor决定使用哪个构造器,点进去
@Nullable
protected Constructor<?>[] determineConstructorsFromBeanPostProcessors(@Nullable Class<?> beanClass, String beanName)
throws BeansException {
if (beanClass != null && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
// 从SmartInstantiationAwareBeanPostProcessor判断
SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
Constructor<?>[] ctors = ibp.determineCandidateConstructors(beanClass, beanName);
if (ctors != null) {
return ctors;
}
}
}
}
return null;
}
执行一下判断条件
所以不进入,直接返回为空。
下面的判断条件也为false,不进入
mbd.getPreferredConstructors();从名字可以看出是获取权重比较高的构造器,点进去
@Nullable
public Constructor<?>[] getPreferredConstructors() {
return null;
}
这边没有对构造器进行权重的设置,返回都是null,继续往后面走,使用默认构造器实例化对象。点进去
protected BeanWrapper instantiateBean(String beanName, RootBeanDefinition mbd) {
try {
Object beanInstance;
if (System.getSecurityManager() != null) {
beanInstance = AccessController.doPrivileged(
(PrivilegedAction<Object>) () -> getInstantiationStrategy().instantiate(mbd, beanName, this),
getAccessControlContext());
}
else {
// 获取实例化策略并且进行实例化操作
beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, this);
}
// 包装成BeanWrapper
BeanWrapper bw = new BeanWrapperImpl(beanInstance);
initBeanWrapper(bw);
return bw;
}
catch (Throwable ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);
}
}
没有安全管理器,进入else中,获取实例化策略进行实例化对象,点进instantiate方法
@Override
public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) {
// Don't override the class with CGLIB if no overrides.
// bd对象定义中,是否包含MethodOverride列表,spring中有两个标签参数会产生MethodOverrides,分别是lookup-method,replaced-method
// 没有MethodOverrides对象,可以直接实例化
if (!bd.hasMethodOverrides()) {
// 实例化对象的构造方法
Constructor<?> constructorToUse;
// 锁定对象,使获得实例化构造方法线程安全
synchronized (bd.constructorArgumentLock) {
// 查看bd对象里使用否含有构造方法
constructorToUse = (Constructor<?>) bd.resolvedConstructorOrFactoryMethod;
// 如果没有
if (constructorToUse == null) {
// 从bd中获取beanClass
final Class<?> clazz = bd.getBeanClass();
// 如果要实例化的beanDefinition是一个接口,则直接抛出异常
if (clazz.isInterface()) {
throw new BeanInstantiationException(clazz, "Specified class is an interface");
}
try {
// 获取系统安全管理器
if (System.getSecurityManager() != null) {
constructorToUse = AccessController.doPrivileged(
(PrivilegedExceptionAction<Constructor<?>>) clazz::getDeclaredConstructor);
}
else {
// 获取默认的无参构造器
constructorToUse = clazz.getDeclaredConstructor();
}
// 获取到构造器之后将构造器赋值给bd中的属性
bd.resolvedConstructorOrFactoryMethod = constructorToUse;
}
catch (Throwable ex) {
throw new BeanInstantiationException(clazz, "No default constructor found", ex);
}
}
}
// 通过反射生成具体的实例化对象
return BeanUtils.instantiateClass(constructorToUse);
}
else {
// Must generate CGLIB subclass.
// 必须生成cglib子类
return instantiateWithMethodInjection(bd, beanName, owner);
}
}
false取反为true,所以往里走,创建普通对象
在前面的时候取resolvedConstructorOrFactoryMethod的值为null,并且没有做为其赋值的操作,所以这里获取到的constructorToUse也为空
获取这个Bean的Class,判断他是不是接口,是借口直接抛出异常
没有安全管理器,所以尝试获取默认的无参构造器clazz.getDeclaredConstructor()。
取到构造器,复制给resolvedConstructorOrFactoryMethod
构造器获取到了,进行实例化instantiateBean(beanName, mbd)。点进去
public static <T> T instantiateClass(Constructor<T> ctor, Object... args) throws BeanInstantiationException {
Assert.notNull(ctor, "Constructor must not be null");
try {
ReflectionUtils.makeAccessible(ctor);
if (KotlinDetector.isKotlinReflectPresent() && KotlinDetector.isKotlinType(ctor.getDeclaringClass())) {
return KotlinDelegate.instantiateClass(ctor, args);
}
else {
Class<?>[] parameterTypes = ctor.getParameterTypes();
Assert.isTrue(args.length <= parameterTypes.length, "Can't specify more arguments than constructor parameters");
Object[] argsWithDefaultValues = new Object[args.length];
//获得参数
for (int i = 0 ; i < args.length; i++) {
if (args[i] == null) {
Class<?> parameterType = parameterTypes[i];
argsWithDefaultValues[i] = (parameterType.isPrimitive() ? DEFAULT_TYPE_VALUES.get(parameterType) : null);
}
else {
argsWithDefaultValues[i] = args[i];
}
}
return ctor.newInstance(argsWithDefaultValues);
}
}
catch (InstantiationException ex) {
throw new BeanInstantiationException(ctor, "Is it an abstract class?", ex);
}
catch (IllegalAccessException ex) {
throw new BeanInstantiationException(ctor, "Is the constructor accessible?", ex);
}
catch (IllegalArgumentException ex) {
throw new BeanInstantiationException(ctor, "Illegal arguments for constructor", ex);
}
catch (InvocationTargetException ex) {
throw new BeanInstantiationException(ctor, "Constructor threw exception", ex.getTargetException());
}
}
ctor.newInstance(argsWithDefaultValues);通过反射的方式创建对象并返回.这是获取第一个Person对象的源码执行流程,接下来看一下在对象是原型的情况下,获取第二个Person对象时,源码时怎么走的
前面的步骤都省略,直接看到这里
这里mbd.resolvedConstructorOrFactoryMethod的取值在第一次创建Person对象的时候已经赋值过了,所以这里是可以取到值的。继续往里面走,设置resolved=true,并对autowireNecessary进行赋值操作。这里看一下constructorArgumentsResolved字段的含义:将构造函数参数标记为已解析的包可见字段。
继续往下走,因为之前设置过resolved=true,所以进去,autowireNecessary字段之前设置为false,所以进入else,点进instantiateBean
点进instantiate
因为第一次创建Person是为resolvedConstructorOrFactoryMethod设置过值了,这里的
constructorToUse就不为空,所以没有进入if,往下走
实例化对象并返回
可以看到获取到两个不同的Person对象。
②有参创建对象
前面的步骤都一样,这里省略,走到下面如图所示
继续往下走
点进determineConstructorsFromBeanPostProcessors,从名字可以看出这个方法是根据BeanPostProcessors来决定构造函数,看一下这个方法是怎么走的
@Nullable
protected Constructor<?>[] determineConstructorsFromBeanPostProcessors(@Nullable Class<?> beanClass, String beanName)
throws BeansException {
if (beanClass != null && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
// 从SmartInstantiationAwareBeanPostProcessor判断
SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
Constructor<?>[] ctors = ibp.determineCandidateConstructors(beanClass, beanName);
if (ctors != null) {
return ctors;
}
}
}
}
return null;
}
继续往里走,执行一下判断条件,可以看到一个和Person有关的
InstantiationAwareBeanPostProcessor,执行到这个
PersonInstantiationAwareBeanPostProcessor看代码怎么走
执行一下判断条件
所以没能执行里面的代码,返回null.
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
// 以下情况符合其一即可进入
// 1、存在可选构造方法
// 2、自动装配模型为构造函数自动装配
// 3、给BeanDefinition中设置了构造参数值
// 4、有参与构造函数参数列表的参数
if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
return autowireConstructor(beanName, mbd, ctors, args);
}
mbd.hasConstructorArgumentValues(),从名字可以看出来功能是判断构造器有没有参数值,执行一下为true,所以这里执行到autowireConstructor,点进入
protected BeanWrapper autowireConstructor(
String beanName, RootBeanDefinition mbd, @Nullable Constructor<?>[] ctors, @Nullable Object[] explicitArgs) {
return new ConstructorResolver(this).autowireConstructor(beanName, mbd, ctors, explicitArgs);
}
点进autowireConstructor
因为这里的constructorToUse==null,所以if进去
之前只申明了argsToResolve,并没有为其赋值,所以这里也进不去。
constructorToUse==null和argsToResolve==null,说明这之前没有创建该对象,需要我们取解析要使用的构造函数和对应的参数。
调用到beanClass.getDeclaredConstructors()获取到所有的构造方法
接着往下走
执行一下判断条件
所以这里进不去,往下走
点进getConstructorArgumentValues
@Override
public ConstructorArgumentValues getConstructorArgumentValues() {
if (this.constructorArgumentValues == null) {
this.constructorArgumentValues = new ConstructorArgumentValues();
}
return this.constructorArgumentValues;
}
因为不为空,所以返回配置文件中构造函数的参数
申明一个resolvedValues,用来承载解析后的构造函数参数的值。resolveConstructorArguments解析构造器参数个数。继续往下走
sortConstructors对构造函数进行排序,排序规则先根据访问权限,再根据参数个数。这里的访问权限都是public,排序效果如下。
排序前
排序后
排好序后,对每个构造函数进行遍历,往下走
获取到参数的类型
参数的名称不为空,如下图
所以仅需往里走
点进evaluate
@Nullable
public static String[] evaluate(Constructor<?> candidate, int paramCount) {
// 获取candidate中的ConstructorProperties注解
ConstructorProperties cp = candidate.getAnnotation(ConstructorProperties.class);
// 如果cp不为null
if (cp != null) {
// 获取cp指定的getter方法的属性名
String[] names = cp.value();
// 如果names长度于paramCount不相等
if (names.length != paramCount) {
throw new IllegalStateException("Constructor annotated with @ConstructorProperties but not " +
"corresponding to actual number of parameters (" + paramCount + "): " + candidate);
}
// 将name返回出去
return names;
}
else {
// 如果没有配置ConstructorProperties注解,则返回null
return null;
}
}
可以看到该方法就是判断传进来的构造函数的参数个数是否与传进来的数字相等,相等则把参数名称返回出去
然后createArgumentArray方法根据名称和数据类型创建参数持有者
// 计算差异量,根据要参与构造函数的参数列表和本构造函数的参数列表进行计算
int typeDiffWeight = (mbd.isLenientConstructorResolution() ?
argsHolder.getTypeDifferenceWeight(paramTypes) : argsHolder.getAssignabilityWeight(paramTypes));
// Choose this constructor if it represents the closest match.
// 本次的构造函数差异值小于上一个构造函数,则进行构造函数更换
if (typeDiffWeight < minTypeDiffWeight) {
// 将确定使用的构造函数设置为本构造
constructorToUse = candidate;
// 更换使用的构造函数参数封装类
argsHolderToUse = argsHolder;
// 更换参与构造函数实例化的参数
argsToUse = argsHolder.arguments;
// 差异值更换
minTypeDiffWeight = typeDiffWeight;
// 不明确的构造函数列表清空为null
ambiguousConstructors = null;
}
// 差异值相等,则表明构造函数不正常,放入异常集合
else if (constructorToUse != null && typeDiffWeight == minTypeDiffWeight) {
//如果ambiguousFactoryMethods为null
if (ambiguousConstructors == null) {
//初始化ambiguousFactoryMethods为LinkedHashSet实例
ambiguousConstructors = new LinkedHashSet<>();
//将constructorToUse添加到ambiguousFactoryMethods中
ambiguousConstructors.add(constructorToUse);
}
//将candidate添加到ambiguousFactoryMethods中
ambiguousConstructors.add(candidate);
}
}
然后根据要参与的构造函数的参数列表和遍历到的构造函数计算差异量,这个差异量越小越好,如果小的话就进行一些值的替换。这个构造函数就走到这,走完接着看下一个构造函数
因为这里1<2,所以排在最后的无参构造器直接不遍历。
走到这可以看到选出来的构造函数是
继续往下面走
可以看到图中都没有走进去,继续往下走
可以点进storeCache
public void storeCache(RootBeanDefinition mbd, Executable constructorOrFactoryMethod) {
// 使用mbd的构造函数通用锁【{@link RootBeanDefinition#constructorArgumentLock}】加锁以保证线程安全
synchronized (mbd.constructorArgumentLock) {
// 让mbd的已解析的构造函数或工厂方法【{@link RootBeanDefinition#resolvedConstructorOrFactoryMethod}】引用constructorOrFactoryMethod
mbd.resolvedConstructorOrFactoryMethod = constructorOrFactoryMethod;
// 将mdb的构造函数参数已解析标记【{@link RootBeanDefinition#constructorArgumentsResolved}】设置为true
mbd.constructorArgumentsResolved = true;
// 如果resolveNecessary为true,表示参数还需要进一步解析
if (this.resolveNecessary) {
// 让mbd的缓存部分准备好的构造函数参数值属性【{@link RootBeanDefinition#preparedConstructorArguments}】引用preparedArguments
mbd.preparedConstructorArguments = this.preparedArguments;
}
else {
// 让mbd的缓存完全解析的构造函数参数属性【{@link RootBeanDefinition#resolvedConstructorArguments}】引用arguments
mbd.resolvedConstructorArguments = this.arguments;
}
}
}
可以看到构造函数被赋值给resolvedConstructorOrFactoryMethod,构造函数部分解析好的参数赋值给preparedConstructorArguments,并做了构造函数以解析的标记。
接着就是实例化并加入BeanWarrper中。
补充,仔细看一下determineConstructorsFromBeanPostProcessors是怎么走的
@Nullable
protected Constructor<?>[] determineConstructorsFromBeanPostProcessors(@Nullable Class<?> beanClass, String beanName)
throws BeansException {
if (beanClass != null && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
// 从SmartInstantiationAwareBeanPostProcessor判断
SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
Constructor<?>[] ctors = ibp.determineCandidateConstructors(beanClass, beanName);
if (ctors != null) {
return ctors;
}
}
}
}
return null;
}
点进SmartInstantiationAwareBeanPostProcessor接口
public interface SmartInstantiationAwareBeanPostProcessor extends InstantiationAwareBeanPostProcessor {
/**
* 预测bean的类型,主要是在bean还没有创建前我们需要获取bean的类型
*/
@Nullable
default Class<?> predictBeanType(Class<?> beanClass, String beanName) throws BeansException {
return null;
}
/**
* 完成对构造函数的解析和推断
*/
@Nullable
default Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, String beanName)
throws BeansException {
return null;
}
/**
* 解决循环依赖问题,通过此方法提前暴露一个合格的对象
*/
default Object getEarlyBeanReference(Object bean, String beanName) throws BeansException {
return bean;
}
}
看到与构造函数有关的determineCandidateConstructors方法,从名字可以看出他是决定候选的构造方法,可能存在的情况分别是下面接种
获取构造器集合
如果有多个Autowired,required为true,不管有没有默认构造方法,会报异常
如果只有一个Autowired,required为false,没有默认构造方法,会报警告
如果没有Autowired注解,定义了两个及以上有参数的构造方法,没有无参构造方法,就会报错
其他情况都可以,但是以有Autowired的构造方法优先,然后才是默认构造方法
①如果有多个Autowired,required为true,不管有没有默认构造方法,会报异常
Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'person': Invalid autowire-marked constructor: public com.mashibing.Person1(int,java.lang.String). Found constructor with 'required' Autowired annotation already: public com.mashibing.Person1(int)
spring源码中对@Autowired注解的处理器Annotation Processor的名称是AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME对应的类是"org.springframework.context.annotation.internalAutowiredAnnotationProcessor"
②如果只有一个Autowired,required为false,没有默认构造方法,会报警告
可以看到有一个警告信息
多种情况说明有且只有一个有参构造,或者有且只有一个@Autowired注解构造的时候才会走determineCandidateConstructors方法。
具体反射流程:
千米那的流程省略,直接把断点打到getInstantiationStrategy.instantiate(mbd, beanName, this)
,先获取实例化策略,点进getInstantiationStrategy
protected InstantiationStrategy getInstantiationStrategy() {
return this.instantiationStrategy;
}
对应的是cglib
private InstantiationStrategy instantiationStrategy = new CglibSubclassingInstantiationStrategy();
点进这个类
点进SimpleInstantiationStrategy
点进InstantiationStrategy
public interface InstantiationStrategy {
/**
* 使用默认构造方法进行实例化
*/
Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner)
throws BeansException;
/**
* 通过指定构造器来进行实例化
*/
Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner,
Constructor<?> ctor, Object... args) throws BeansException;
/**
* 通过指定工厂方法来进行实例化
*/
Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner,
@Nullable Object factoryBean, Method factoryMethod, Object... args)
throws BeansException;
}
点开他的实现子类SimpleInstantiationStrategy,里面有创建对象的三种基本实现
public class SimpleInstantiationStrategy implements InstantiationStrategy {
...
@Override
public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) {...}
@Override
public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner,final Constructor<?> ctor, Object... args) {...}
@Override
public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner,@Nullable Object factoryBean, final Method factoryMethod, Object... args) {...}
再点开子类实现CglibSubclassingInstantiationStrategy,里面多了两个动态代理的有参构造和无参构造的实现
public class CglibSubclassingInstantiationStrategy extends SimpleInstantiationStrategy {
@Override
protected Object instantiateWithMethodInjection(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) {
return instantiateWithMethodInjection(bd, beanName, owner, null);
}
@Override
protected Object instantiateWithMethodInjection(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner,
@Nullable Constructor<?> ctor, Object... args) {
// Must generate CGLIB subclass...
// 必须生成一个cglib的子类
return new CglibSubclassCreator(bd, owner).instantiate(ctor, args);
}
从上图可以看到无参构造和有参构造调用同一个方法instantiateWithMethodInjection进行实例化,instantiateWithMethodInjection内部调用instantiate,点进去
可以看到Cglib实现子类中还是有非动态代理创建对象的实现(无参构造) 。几种创建对象的方式如下图所示:
到此对象创建就完成了,但是这个时候只是针对该对象在堆中开辟一块中间,对象中并没有实际的数据,如图所示
继续往下走
会将刚才实例化的bean实例 包装成Beanwrapper.这里要创建一个包装类,而不是直接进行赋值的原因,可以看一下初始化initBeanWrapper里面做的操作
protected void initBeanWrapper(BeanWrapper bw) {
// 使用该工厂的ConversionService来作为bw的ConversionService,用于转换属性值,以替换JavaBeans PropertyEditor
bw.setConversionService(getConversionService());
// 将工厂中所有PropertyEditor注册到bw中
registerCustomEditors(bw);
}
可以看到,在这里面做了设置转换服务注册值处理器。在这里做这些操作的原因是:我们在配置文件中设置的值都是string类型的,但这个值不一定是string类型的,所以对设置的值需要进行类型转换等处理操作。所以在创建包装类的时候将这两个服务设置进包装类,以便进行后续的值处理从操作。
创建好包装类以后,从注释可以看出下面用BeanPostProcessor开始修改定义好的BeanDefinition
点进applyMergedBeanDefinitionPostProcessors
这里调用了MergedBeanDefinitionPostProcessor.postProcessMergedBeanDefinition,我么点进
MergedBeanDefinitionPostProcessor看看这个方法的实现
public interface MergedBeanDefinitionPostProcessor extends BeanPostProcessor {
/**
*spring通过此方法找出所有需要注入的字段,同时做缓存
*/
void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName);
/**
* 用于在BeanDefinition被修改后,清除容器的缓存
*/
default void resetBeanDefinition(String beanName) {
}
}
点开postProcessMergedBeanDefinition在子类中的实现
@Override
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
// 处理@PostConstruct和@PreDestroy注解
super.postProcessMergedBeanDefinition(beanDefinition, beanType, beanName);
//找出beanType所有被@Resource标记的字段和方法封装到InjectionMetadata中
InjectionMetadata metadata = findResourceMetadata(beanName, beanType, null);
metadata.checkConfigMembers(beanDefinition);
}
继续调用父类
@Override
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
// 调用方法获取生命周期元数据并保存
LifecycleMetadata metadata = findLifecycleMetadata(beanType);
// 验证相关方法
metadata.checkConfigMembers(beanDefinition);
}
可以看到这个方法中做了获取生命周期元数据的相关数据保存的操作并验证了相关的方法,我们点进findLifecycleMetadata方法
private LifecycleMetadata findLifecycleMetadata(Class<?> clazz) {
if (this.lifecycleMetadataCache == null) {
// Happens after deserialization, during destruction...
// 在bean销毁过程中,反序列化后调用
return buildLifecycleMetadata(clazz);
}
// Quick check on the concurrent map first, with minimal locking.
// 首先尝试从缓存中获取元数据
LifecycleMetadata metadata = this.lifecycleMetadataCache.get(clazz);
// 如果从缓存中获取失败则尝试加锁创建元数据
if (metadata == null) {
synchronized (this.lifecycleMetadataCache) {
// 加锁后再次尝试获取元数据,防止多线程重复执行
metadata = this.lifecycleMetadataCache.get(clazz);
if (metadata == null) {
// 构建生命周期元数据
metadata = buildLifecycleMetadata(clazz);
// 将构建好的元数据放入缓存中
this.lifecycleMetadataCache.put(clazz, metadata);
}
return metadata;
}
}
return metadata;
}
点进buildLifecycleMetadata,可以看到代码主要是写在不同情况下创建buildLifecycleMetadata,可以点进buildLifecycleMetadata看看做了什么
- 检查候选类
- 这段代码使用
AnnotationUtils.isCandidateClass
方法检查该类是否包含指定的生命周期注解(如@PostConstruct
和@PreDestroy
)。 - 如果该类不是候选类,则直接返回一个空的
LifecycleMetadata
对象。
- 这段代码使用
- 初始化方法列表
- 初始化两个列表
initMethods
和destroyMethods
,用于存储找到的初始化和销毁方法。 targetClass
用于跟踪当前处理的类。
- 初始化两个列表
- 循环处理类及其父类
- 使用
ReflectionUtils.doWithLocalMethods
方法遍历当前类的所有本地方法(不包括继承的方法)。 - 对每个方法,检查其是否包含初始化注解(如
@PostConstruct
)或销毁注解(如@PreDestroy
),如果包含,则将其封装为LifecycleElement
对象,并添加到相应的列表中。 - 将当前类的初始化方法添加到
initMethods
的前面,销毁方法添加到destroyMethods
的后面。 - 更新
targetClass
为其父类,继续处理父类,直到处理到Object
类为止。
- 使用
- 构建并返回
LifecycleMetadata
对象- 检查
initMethods
和destroyMethods
列表是否为空,如果都为空,则返回一个空的LifecycleMetadata
对象。 - 否则,创建并返回一个包含找到的方法的
LifecycleMetadata
对象。
- 检查
private LifecycleMetadata buildLifecycleMetadata(final Class<?> clazz) {
if (!AnnotationUtils.isCandidateClass(clazz, Arrays.asList(this.initAnnotationType, this.destroyAnnotationType))) {
return this.emptyLifecycleMetadata;
}
// 实例化后的回调方法(@PostConstruct)
List<LifecycleElement> initMethods = new ArrayList<>();
// 销毁前的回调方法(@PreDestroy)
List<LifecycleElement> destroyMethods = new ArrayList<>();
// 获取正在处理的目标类
Class<?> targetClass = clazz;
do {
// 保存每一轮循环搜索到的相关方法
final List<LifecycleElement> currInitMethods = new ArrayList<>();
final List<LifecycleElement> currDestroyMethods = new ArrayList<>();
// 反射获取当前类中的所有方法并依次对其调用第二个参数的lambda表达式
ReflectionUtils.doWithLocalMethods(targetClass, method -> {
// 当前方法的注解中包含initAnnotationType注解时(@PostConstruct)
if (this.initAnnotationType != null && method.isAnnotationPresent(this.initAnnotationType)) {
// 如果有,把它封装成LifecycleElement对象,存储起来
LifecycleElement element = new LifecycleElement(method);
// 将创建好的元素添加到集合中
currInitMethods.add(element);
if (logger.isTraceEnabled()) {
logger.trace("Found init method on class [" + clazz.getName() + "]: " + method);
}
}
// 当前方法的注解中包含destroyAnnotationType注解(PreDestroy)
if (this.destroyAnnotationType != null && method.isAnnotationPresent(this.destroyAnnotationType)) {
// 如果有,把它封装成LifecycleElement对象,存储起来
currDestroyMethods.add(new LifecycleElement(method));
if (logger.isTraceEnabled()) {
logger.trace("Found destroy method on class [" + clazz.getName() + "]: " + method);
}
}
});
// 将本次循环中获取到的对应方法集合保存到总集合中
initMethods.addAll(0, currInitMethods);
// 销毁方法父类晚于子类
destroyMethods.addAll(currDestroyMethods);
// 获取当前类的父类
targetClass = targetClass.getSuperclass();
}
// 如果当前类存在父类且父类不为object基类则循环对父类进行处理
while (targetClass != null && targetClass != Object.class);
// 有一个不为空就封装一个LifecycleMetadata对象,否则就返回空的emptyLifecycleMetadata
return (initMethods.isEmpty() && destroyMethods.isEmpty() ? this.emptyLifecycleMetadata :
new LifecycleMetadata(clazz, initMethods, destroyMethods));
}
从代码中可以看到将类定义的初始化和销毁的方法添加到对应的list中。(包括其父类的)
注意BeanPostProrcessor是对Bean定义信息的修改。这里获取到的类的初始化和销毁的定义信息将要通过PostProcessor设置到Bean对象中,继续往后面看metaData.checkConfigMembers(beanDefinition)做了什么
从上图中可以看出init和destroy方法被注册到bean的定义信息中去了。
我们再帖一下这个方法
@Override
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
// 处理@PostConstruct和@PreDestroy注解
super.postProcessMergedBeanDefinition(beanDefinition, beanType, beanName);
//找出beanType所有被@Resource标记的字段和方法封装到InjectionMetadata中
InjectionMetadata metadata = findResourceMetadata(beanName, beanType, null);
metadata.checkConfigMembers(beanDefinition);
}
上面我们已经看完调用postProcessMergedBeanDefinition方法,接着我们继续往下走,调用findResourceMetadata,其实这个方法和findLifecycleMetadata方法类似,只是处理的对象不一样,上面是针对Lifecycle,接下来是针对Resource的。
这里是在实例化之后再添加对对象的描述信息,与之前出现的再实例化之前冰冻对象的定义信息似乎有矛盾。这里主要是因为在实例化完成之后再添加一些描述信息方便之后的结果调用。
我们再看一个类似的
同样走到postProcessMergedBeanDefinition
@Override
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
// 解析注解并缓存
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
buildAutowiringMetadata方法的思路大概分为这几个方向:
- 使用
ReflectionUtils.doWithLocalFields
方法遍历当前类的所有字段,对每个字段,检查其是否包含指定的自动注入注解(如@Autowired
),如果包含,则将其封装为AutowiredFieldElement
对象,并添加到currElements
列表中。 - 使用
ReflectionUtils.doWithLocalMethods
方法遍历当前类的所有方法,对每个方法,检查其是否包含指定的自动注入注解(如@Autowired
),如果包含,则将其封装为AutowiredMethodElement
对象,并添加到currElements
列表中。 - 将当前类的注入元素添加到
elements
列表的前面,以确保父类的注入元素在前,子类的注入元素在后。 - 更新
targetClass
为其父类,继续处理父类,直到处理到Object
类为止。
private InjectionMetadata buildAutowiringMetadata(final Class<?> clazz) {
// 如果clazz是JDK中的类,直接忽略,因为不可能标注有这些标注
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<>();
// 遍历类中的每个属性,判断属性是否包含指定的属性(通过 findAutowiredAnnotation 方法)
// 如果存在则保存,这里注意,属性保存的类型是 AutowiredFieldElement
ReflectionUtils.doWithLocalFields(targetClass, field -> {
MergedAnnotation<?> ann = findAutowiredAnnotation(field);
if (ann != null) {
//Autowired注解不支持静态方法
if (Modifier.isStatic(field.getModifiers())) {
if (logger.isInfoEnabled()) {
logger.info("Autowired annotation is not supported on static fields: " + field);
}
return;
}
//查看是否是required的
boolean required = determineRequiredStatus(ann);
currElements.add(new AutowiredFieldElement(field, required));
}
});
// 遍历类中的每个方法,判断属性是否包含指定的属性(通过 findAutowiredAnnotation 方法)
// 如果存在则保存,这里注意,方法保存的类型是 AutowiredMethodElement
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))) {
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);
// AutowiredMethodElement里封装了一个PropertyDescriptor(比字段多了一个参数)
currElements.add(new AutowiredMethodElement(method, required, pd));
}
});
// 父类的都放在第一位,所以父类是最先完成依赖注入的
elements.addAll(0, currElements);
targetClass = targetClass.getSuperclass();
}
while (targetClass != null && targetClass != Object.class);
// InjectionMetadata就是对clazz和elements的一个包装而已
return InjectionMetadata.forElements(elements, clazz);
}
点进findAutowiredAnnotation,就是查找其注解
@Nullable
private MergedAnnotation<?> findAutowiredAnnotation(AccessibleObject ao) {
MergedAnnotations annotations = MergedAnnotations.from(ao);
for (Class<? extends Annotation> type : this.autowiredAnnotationTypes) {
MergedAnnotation<?> annotation = annotations.get(type);
if (annotation.isPresent()) {
return annotation;
}
}
return null;
}
匹配类型对应的字段如下
private final Set<Class<? extends Annotation>> autowiredAnnotationTypes = new LinkedHashSet<>(4);
这个字段在那里被赋值,在看一下这个类的构造器,在构造器里面被赋值
public AutowiredAnnotationBeanPostProcessor() {
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.
}
}
由此,可以看到某个值有Autowired和Value属性时,返回这个值。
点进doWithLocalFields
public static void doWithLocalFields(Class<?> clazz, FieldCallback fc) {
// 遍历clazz中所有声明的属性
for (Field field : getDeclaredFields(clazz)) {
try {
// 对field进行fc的回调操作
fc.doWith(field);
}
catch (IllegalAccessException ex) {
throw new IllegalStateException("Not allowed to access field '" + field.getName() + "': " + ex);
}
}
}
遍历所有的属性,调用lamda表达式里面的代码:找到被Autowired标注的属性。并添加。对于doWithLocalMethods做了同样的处理。
由于 AutowiredAnnotationBeanPostProcessor
的构造函数将 @Autowired
和 @Value
注解类型添加到了 autowiredAnnotationTypes
列表中,在 buildAutowiringMetadata
方法中,通过 findAutowiredAnnotation
方法检查字段或方法上是否存在这些注解,如果发现字段或方法上有 @Autowired
或 @Value
注解,则认为该字段或方法需要进行自动注入。这表明,字段或方法上只要有 @Autowired
或 @Value
注解,Spring 就会将其视为需要进行自动注入的目标。
到这里只是做了对属性的注册,并没有注入。我们看一下属性和方法的注入类中都有方法inject
点进去看一下
- 缓存处理:首先检查是否已缓存注入信息。如果已缓存,从缓存中获取注入值。
- 解析依赖:如果未缓存,使用
DependencyDescriptor
描述字段的依赖,调用beanFactory.resolveDependency
解析依赖项,获取注入值。 - 缓存依赖:将解析得到的依赖信息缓存,以便后续注入时快速访问。
- 字段注入:使用反射将解析得到的依赖值注入到目标 bean 的字段中。
@Override
protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
Field field = (Field) this.member;
Object value;
// 如果缓存,从缓存中获取
if (this.cached) {
// 如果 cachedFieldValue instanceof DependencyDescriptor。则调用 resolveDependency 方法重新加载。
value = resolvedCachedArgument(beanName, this.cachedFieldValue);
}
else {
// 否则调用了 resolveDependency 方法。这个在前篇讲过,在 populateBean 方法中按照类型注入的时候就是通过此方法,
// 也就是说明了 @Autowired 和 @Inject默认是 按照类型注入的
DependencyDescriptor desc = new DependencyDescriptor(field, this.required);
desc.setContainingClass(bean.getClass());
Set<String> autowiredBeanNames = new LinkedHashSet<>(1);
Assert.state(beanFactory != null, "No BeanFactory available");
// 转换器使用的bean工厂的转换器
TypeConverter typeConverter = beanFactory.getTypeConverter();
try {
// 获取依赖的value值的工作 最终还是委托给beanFactory.resolveDependency()去完成的
// 这个接口方法由AutowireCapableBeanFactory提供,它提供了从bean工厂里获取依赖值的能力
value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);
}
catch (BeansException ex) {
throw new UnsatisfiedDependencyException(null, beanName, new InjectionPoint(field), ex);
}
// 把缓存值缓存起来
synchronized (this) {
// 如果没有缓存,则开始缓存
if (!this.cached) {
// 可以看到value!=null并且required=true才会进行缓存的处理
if (value != null || this.required) {
// 这里先缓存一下 desc,如果下面 utowiredBeanNames.size() > 1。则在上面从缓存中获取的时候会重新获取。
this.cachedFieldValue = desc;
// 注册依赖bean
registerDependentBeans(beanName, autowiredBeanNames);
// autowiredBeanNames里可能会有别名的名称,所以size可能大于1
if (autowiredBeanNames.size() == 1) {
// beanFactory.isTypeMatch挺重要的,因为@Autowired是按照类型注入的
String autowiredBeanName = autowiredBeanNames.iterator().next();
if (beanFactory.containsBean(autowiredBeanName) &&
beanFactory.isTypeMatch(autowiredBeanName, field.getType())) {
this.cachedFieldValue = new ShortcutDependencyDescriptor(
desc, autowiredBeanName, field.getType());
}
}
}
else {
this.cachedFieldValue = null;
}
this.cached = true;
}
}
}
if (value != null) {
// 通过反射,给属性赋值
ReflectionUtils.makeAccessible(field);
field.set(bean, value);
}
}
}
具体看一下方法的实现
Field field = (Field) this.member;
Object value;
field
:表示需要注入的字段。value
:表示将要注入到字段中的值。
if (this.cached) {
value = resolvedCachedArgument(beanName, this.cachedFieldValue);
}
如果 cached
为 true
,表示此前已经处理过该字段的注入,可以直接从缓存中获取注入值。
else {
DependencyDescriptor desc = new DependencyDescriptor(field, this.required);
desc.setContainingClass(bean.getClass());
Set<String> autowiredBeanNames = new LinkedHashSet<>(1);
Assert.state(beanFactory != null, "No BeanFactory available");
TypeConverter typeConverter = beanFactory.getTypeConverter();
try {
value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);
}
catch (BeansException ex) {
throw new UnsatisfiedDependencyException(null, beanName, new InjectionPoint(field), ex);
}
}
- 创建一个
DependencyDescriptor
对象desc
,用于描述依赖项。 beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter)
:解析依赖项,获取注入值。
synchronized (this) {
if (!this.cached) {
if (value != null || this.required) {
this.cachedFieldValue = desc;
registerDependentBeans(beanName, autowiredBeanNames);
if (autowiredBeanNames.size() == 1) {
String autowiredBeanName = autowiredBeanNames.iterator().next();
if (beanFactory.containsBean(autowiredBeanName) &&
beanFactory.isTypeMatch(autowiredBeanName, field.getType())) {
this.cachedFieldValue = new ShortcutDependencyDescriptor(
desc, autowiredBeanName, field.getType());
}
}
}
else {
this.cachedFieldValue = null;
}
this.cached = true;
}
}
- 如果
value
不为空或者required
为true
,则将desc
缓存到cachedFieldValue
。 - 注册依赖的 bean。
- 如果自动注入的 bean 名称列表中只有一个元素,并且该元素的类型匹配字段类型,则使用
ShortcutDependencyDescriptor
缓存描述符。 - 标记为已缓存。
if (value != null) {
ReflectionUtils.makeAccessible(field);
field.set(bean, value);
}
使用反射将 value
注入到目标 bean
的 field
中。
但是比如在Controller里面要注入某个Service,但是这个Service为空,anemic就要完成对这个Service的处理再注入。往上翻 ,可以看到beanFactory.resolveDependency方法就是对不存在的依赖做出的处理。
@Override
@Nullable
public Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName,
@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {
// 获取工厂的参数名发现器,设置到descriptor中。使得descriptor初始化基础方法参数的参数名发现。此时,该方法实际上
// 并没有尝试检索参数名称;它仅允许发现再应用程序调用getDependencyName时发生
descriptor.initParameterNameDiscovery(getParameterNameDiscoverer());
// 如果descriptor的依赖类型为Optional类
if (Optional.class == descriptor.getDependencyType()) {
//创建Optional类型的符合descriptor要求的候选Bean对象
return createOptionalDependency(descriptor, requestingBeanName);
}
// 是对象工厂类型或者对象提供者
else if (ObjectFactory.class == descriptor.getDependencyType() ||
ObjectProvider.class == descriptor.getDependencyType()) {
// DependencyObjectProvider:依赖对象提供者,用于延迟解析依赖项
// 新建一个DependencyObjectProvider的实例
return new DependencyObjectProvider(descriptor, requestingBeanName);
}
// javaxInjectProviderClass有可能导致空指针,不过一般情况下,我们引用Spirng包的时候都有引入该类以防止空旨在
// 如果依赖类型是javax.inject.Provider类。
else if (javaxInjectProviderClass == descriptor.getDependencyType()) {
// Jse330Provider:javax.inject.Provider实现类.与DependencyObjectProvoid作用一样,也是用于延迟解析依赖
// 项,但它是使用javax.inject.Provider作为依赖 对象,以减少与Springd耦合
// 新建一个专门用于构建javax.inject.Provider对象的工厂来构建创建Jse330Provider对象
return new Jsr330Factory().createDependencyProvider(descriptor, requestingBeanName);
}
else {
// 尝试获取延迟加载代理对象
Object result = getAutowireCandidateResolver().getLazyResolutionProxyIfNecessary(
descriptor, requestingBeanName);
// 如果result为null,即表示现在需要得到候选Bean对象
if (result == null) {
// 解析出与descriptor所包装的对象匹配的候选Bean对象
result = doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter);
}
// 将与descriptor所包装的对象匹配的候选Bean对象【result】返回出去
return result;
}
}
自动装配的几种方式:
byName
byType
construct
default
no