首先,我们在3.1 spring5源码系列--循环依赖 之 手写代码模拟spring循环依赖 中手写了循环依赖的实现. 这个实现就是模拟的spring的循环依赖. 目的是为了更容易理解spring源码.
下面我们就进入正题, 看看spring的循环依赖源码.
一、getBean整体流程
目标很明确了, 就是要看看spring如何解决循环依赖的.
代码入口是refresh()#finishBeanFactoryInitialization(beanFactory);
二、拆解研究流程中的每一步
调用方法beanFactory.preInstantiateSingletons();实例化剩余的单例bean. 为什么是剩余的?很显然我们在上面已经实例化一部分了.比如配置类, postProcessor等.
2.1 入口
1 @Override
2 public void preInstantiateSingletons() throws BeansException {
3 if (logger.isTraceEnabled()) {
4 logger.trace("Pre-instantiating singletons in " + this);
5 }
6
7
8 // 获取容器中所有bean定义的名字
9 List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
10
11 // Trigger initialization of all non-lazy singleton beans...
12 /**
13 * 第一步: 循环bean定义的name
14 */
15 for (String beanName : beanNames) {
16 // 获取bean定义
17 RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
18 // 生产bean定义的条件: 不是抽象的, 是单例的, 不是懒加载的. 符合这个标准的, 最后才会调用getBean()生产bean
19 if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
20 // 这里判断是不是工厂bean, 这里和BeanFactory不是一个意思, 判断当前这个bean是否实现了beanFactory的接口
21 if (isFactoryBean(beanName)) {
22 Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
23 if (bean instanceof FactoryBean) {
24 final FactoryBean<?> factory = (FactoryBean<?>) bean;
25 boolean isEagerInit;
26 if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
27 isEagerInit = AccessController.doPrivileged((PrivilegedAction<Boolean>)
28 ((SmartFactoryBean<?>) factory)::isEagerInit,
29 getAccessControlContext());
30 }
31 else {
32 isEagerInit = (factory instanceof SmartFactoryBean &&
33 ((SmartFactoryBean<?>) factory).isEagerInit());
34 }
35 if (isEagerInit) {
36 // 获取bean
37 getBean(beanName);
38 }
39 }
40 }
41 else {
// 第二步: 调用bean定义
42 getBean(beanName);
43 }
44 }
45 }
46
47 // Trigger post-initialization callback for all applicable beans...
48 /**
49 * 循环bean定义的name
50 */
51 for (String beanName : beanNames) {
52 // 从缓存中得到实例instance
53 Object singletonInstance = getSingleton(beanName);
54 if (singletonInstance instanceof SmartInitializingSingleton) {
55 final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
56 if (System.getSecurityManager() != null) {
57 AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
58 smartSingleton.afterSingletonsInstantiated();
59 return null;
60 }, getAccessControlContext());
61 }
62 else {
63 smartSingleton.afterSingletonsInstantiated();
64 }
65 }
66 }
67 }
首先, 循环bean定义, 这和我们模拟spring循环的第一步是一样的.
第二步: 判断从BeanDefinitionMap中取出来的这个bean是否满足生产bean的条件
我们注意代码注释中, 生产bean定义的条件: 不是抽象的, 是单例的, 不是懒加载的. 符合这个标准的, 最后才会调用getBean()生产bean
然后:调用getBean()
到目前为止,我们完成了上图源码图的第一部分:
2.2 创建bean前的准备工作
接下来看看getBean().doGetBean()方法
1 protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
2 @Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
3
4 // 第一步: 转换bean name. 在这里传入进来的name可能是别名, 也有可能是工厂bean的name, 所以在这里进行一个转换
5 final String beanName = transformedBeanName(name);
6 Object bean;
7
8 // Eagerly check singleton cache for manually registered singletons.
9 // 第二步: 尝试去缓存中获取对象, 如果没有获取到就创建bean
10 Object sharedInstance = getSingleton(beanName);
11 if (sharedInstance != null && args == null) {
12 if (logger.isTraceEnabled()) {
13 //判断当前类是否是正在创建中
14 if (isSingletonCurrentlyInCreation(beanName)) {
15 logger.trace("Returning eagerly cached instance of singleton bean '" + beanName +
16 "' that is not fully initialized yet - a consequence of a circular reference");
17 }
18 else {
19 logger.trace("Returning cached instance of singleton bean '" + beanName + "'");
20 }
21 }
22 bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
23 }
24
25 else {
26 // Fail if we're already creating this bean instance:
27 // We're assumably within a circular reference.
28 /**
29 * 判断当前的bean是不是多例, 如果是这抛出异常
30 *
31 * 判断当前这个bean是不是多例bean. 如果配置了@Scope("prototype") 就表示这是一个多例的bean
32 * spring 只能解决单例对象的setter注入的循环依赖, 不能解决构造器注入
33 *
34 * 如果是多例的bean, 当前正在创建bean, 也会抛出异常---这也是循环依赖的问题
35 */
36 if (isPrototypeCurrentlyInCreation(beanName)) {
37 throw new BeanCurrentlyInCreationException(beanName);
38 }
39
40 /**
41 * 下面这段代码是关于子父容器的, 只有spring mvc继承自spring, 才会有子父容器的问题.
42 */
43 // Check if bean definition exists in this factory.
44 BeanFactory parentBeanFactory = getParentBeanFactory();
45 if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
46 // Not found -> check parent.
47 String nameToLookup = originalBeanName(name);
48 if (parentBeanFactory instanceof AbstractBeanFactory) {
49 return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
50 nameToLookup, requiredType, args, typeCheckOnly);
51 }
52 else if (args != null) {
53 // Delegation to parent with explicit args.
54 return (T) parentBeanFactory.getBean(nameToLookup, args);
55 }
56 else if (requiredType != null) {
57 // No args -> delegate to standard getBean method.
58 return parentBeanFactory.getBean(nameToLookup, requiredType);
59 }
60 else {
61 return (T) parentBeanFactory.getBean(nameToLookup);
62 }
63 }
64
65 /**
66 * 方法参数typeCheckOnly是用来判断#getBean()方法时, 表示是否为仅仅进行类型检查,
67 * 如果不仅仅做类型检查, 而是创建bean对象, 则需要调用#markBeanAsCreated(String name)
68 *
69 */
70 if (!typeCheckOnly) {
71 markBeanAsCreated(beanName);
72 }
73
74 try {
75 final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
76 checkMergedBeanDefinition(mbd, beanName, args);
77
78 // Guarantee initialization of beans that the current bean depends on.
79 /**
80 * 现在有两个bean1, bean2 , 加载的时候调用的是bean1, bean2. 但如果我们想要bean2优先加载, 就使用@DependOn注解
81 * 用来解析带有dependOn注解的类
82 */
83 String[] dependsOn = mbd.getDependsOn();
84 if (dependsOn != null) {
85 for (String dep : dependsOn) {
86 if (isDependent(beanName, dep)) {
87 throw new BeanCreationException(mbd.getResourceDescription(), beanName,
88 "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
89 }
90 registerDependentBean(dep, beanName);
91 try {
92 getBean(dep);
93 }
94 catch (NoSuchBeanDefinitionException ex) {
95 throw new BeanCreationException(mbd.getResourceDescription(), beanName,
96 "'" + beanName + "' depends on missing bean '" + dep + "'", ex);
97 }
98 }
99 }
100
101 // Create bean instance.
102 /**
103 * 第三步: 创建单例bean实例
104 */
105 if (mbd.isSingleton()) { // 处理单例bean
106 /**
107 * 这里getSingleton()和上面的getSigleton不一样, 上面的是从一级缓存中拿.
108 * 这个getSingleton()就办了一件事: 将bean设置为正在创建的状态. 这个状态很重要, 如果出现循环依赖, 发现bean正在创建, 就不会再创建了
109 */
110 sharedInstance = getSingleton(beanName, () -> {
111 try {
112 return createBean(beanName, mbd, args);
113 }
114 catch (BeansException ex) {
115 // Explicitly remove instance from singleton cache: It might have been put there
116 // eagerly by the creation process, to allow for circular reference resolution.
117 // Also remove any beans that received a temporary reference to the bean.
118 destroySingleton(beanName);
119 throw ex;
120 }
121 });
122 // 得到bean实例对象
123 bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
124 }
125
126 else if (mbd.isPrototype()) { // 处理多例bean
127 // It's a prototype -> create a new instance.
128 Object prototypeInstance = null;
129 try {
130 // 当前正在创建多例bean
131 beforePrototypeCreation(beanName);
132 // 执行创建bean
133 prototypeInstance = createBean(beanName, mbd, args);
134 }
135 finally {
136 afterPrototypeCreation(beanName);
137 }
138 // 获取bean实例对象
139 bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
140 }
141
142 else { // 处理其他类型的bean
143 String scopeName = mbd.getScope();
144 final Scope scope = this.scopes.get(scopeName);
145 if (scope == null) {
146 throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
147 }
148 try {
149 Object scopedInstance = scope.get(beanName, () -> {
150 beforePrototypeCreation(beanName);
151 try {
152 return createBean(beanName, mbd, args);
153 }
154 finally {
155 afterPrototypeCreation(beanName);
156 }
157 });
158 bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
159 }
160 catch (IllegalStateException ex) {
161 throw new BeanCreationException(beanName,
162 "Scope '" + scopeName + "' is not active for the current thread; consider " +
163 "defining a scoped proxy for this bean if you intend to refer to it from a singleton",
164 ex);
165 }
166 }
167 }
168 catch (BeansException ex) {
169 cleanupAfterBeanCreationFailure(beanName);
170 throw ex;
171 }
172 }
在这里, 首先从缓存中获取bean, 看缓存中是否已经存在了
Object sharedInstance = getSingleton(beanName);
然后, 如果缓存中已经存在了,那么久直接取出来. 代码如下:
if (sharedInstance != null && args == null) {
if (logger.isTraceEnabled()) {
//判断当前bean是否是正在创建中(单例bean)
if (isSingletonCurrentlyInCreation(beanName)) {
logger.trace("Returning eagerly cached instance of singleton bean '" + beanName +
"' that is not fully initialized yet - a consequence of a circular reference");
}
else {
logger.trace("Returning cached instance of singleton bean '" + beanName + "'");
}
}
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
如果是空, 就说明是第一次创建, 执行else的部分
首先, 判断是否是正在创建的多例bean, 如果是正在创建的多例bean, 就抛出异常,
已经是正在创建了, 说明这至少是第二次了, 这里处理的是单例bean的循环依赖, 不处理多例bean的循环依赖, 所以抛出异常
对应的代码是这一句
// Fail if we're already creating this bean instance:
27 // We're assumably within a circular reference.
28 /**
29 * 判断当前的bean是不是多例, 如果是这抛出异常
30 *
31 * 判断当前这个bean是不是多例bean. 如果配置了@Scope("prototype") 就表示这是一个多例的bean
32 * spring 只能解决单例对象的setter注入的循环依赖, 不能解决构造器注入
33 *
34 * 如果是多例的bean, 当前正在创建bean, 也会抛出异常---这也是循环依赖的问题
35 */
36 if (isPrototypeCurrentlyInCreation(beanName)) {
37 throw new BeanCurrentlyInCreationException(beanName);
38 }
那么, 接下来就是首次创建bean. 首次创建的bean有三种情况:
第一种, 这个bean是单例的.
第二种, 这个bean是多例的.
第三种. 其他类型
对应的代码就是这一块. 有行号, 可以和上面一一对应上
// Create bean instance.
102 /**
103 * 第三步: 创建单例bean实例
104 */
105 if (mbd.isSingleton()) { // 处理单例bean
106 /**
107 * 这里getSingleton()和上面的getSigleton不一样, 上面的是从一级缓存中拿.
108 * 这个getSingleton()就办了一件事: 将bean设置为正在创建的状态. 这个状态很重要, 如果出现循环依赖, 发现bean正在创建, 就不会再创建了
109 */
110 sharedInstance = getSingleton(beanName, () -> {
111 try {
112 return createBean(beanName, mbd, args);
113 }
114 catch (BeansException ex) {
115 // Explicitly remove instance from singleton cache: It might have been put there
116 // eagerly by the creation process, to allow for circular reference resolution.
117 // Also remove any beans that received a temporary reference to the bean.
118 destroySingleton(beanName);
119 throw ex;
120 }
121 });
122 // 得到bean实例对象
123 bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
124 }
125
126 else if (mbd.isPrototype()) { // 处理多例bean
127 // It's a prototype -> create a new instance.
128 Object prototypeInstance = null;
129 try {
130 // 当前正在创建多例bean
131 beforePrototypeCreation(beanName);
132 // 执行创建bean
133 prototypeInstance = createBean(beanName, mbd, args);
134 }
135 finally {
136 afterPrototypeCreation(beanName);
137 }
138 // 获取bean实例对象
139 bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
140 }
141
142 else { // 处理其他类型的bean
143 String scopeName = mbd.getScope();
144 final Scope scope = this.scopes.get(scopeName);
145 if (scope == null) {
146 throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
147 }
148 try {
149 Object scopedInstance = scope.get(beanName, () -> {
150 beforePrototypeCreation(beanName);
151 try {
152 return createBean(beanName, mbd, args);
153 }
154 finally {
155 afterPrototypeCreation(beanName);
156 }
157 });
158 bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
159 }
160 catch (IllegalStateException ex) {
161 throw new BeanCreationException(beanName,
162 "Scope '" + scopeName + "' is not active for the current thread; consider " +
163 "defining a scoped proxy for this bean if you intend to refer to it from a singleton",
164 ex);
165 }
166 }
我们的重点研究对象是单例bean. 所以,重点看单例bean的实现
105 if (mbd.isSingleton()) { // 处理单例bean
106 /**
107 * 这里getSingleton()和上面的getSigleton不一样, 上面的是从一级缓存中拿.
108 * 这个getSingleton()就办了一件事: 将bean设置为正在创建的状态. 这个状态很重要, 如果出现循环依赖, 发现bean正在创建, 就不会再创建了
109 */
110 sharedInstance = getSingleton(beanName, () -> {
111 try {
112 return createBean(beanName, mbd, args);
113 }
114 catch (BeansException ex) {
115 // Explicitly remove instance from singleton cache: It might have been put there
116 // eagerly by the creation process, to allow for circular reference resolution.
117 // Also remove any beans that received a temporary reference to the bean.
118 destroySingleton(beanName);
119 throw ex;
120 }
121 });
122 // 得到bean实例对象
123 bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
124 }
这里的重点是调用了getSingleton(beanName, FactoryObject); FactoryObject是一个接口. 定义了一个钩子方法getObject().
这个接口在这里这是进行了定义, 并不会执行. 什么时候执行呢? 后面调用的时候执行.
下面来看看getSingleton()方法, 钩子方法也是在这里被调用的.
1 public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
2 Assert.notNull(beanName, "Bean name must not be null");
3 synchronized (this.singletonObjects) {
4 // 第一步: 从一级缓存中获取单例对象
5 Object singletonObject = this.singletonObjects.get(beanName);
6 if (singletonObject == null) {
7 if (this.singletonsCurrentlyInDestruction) {
8 throw new BeanCreationNotAllowedException(beanName,
9 "Singleton bean creation not allowed while singletons of this factory are in destruction " +
10 "(Do not request a bean from a BeanFactory in a destroy method implementation!)");
11 }
12 if (logger.isDebugEnabled()) {
13 logger.debug("Creating shared instance of singleton bean '" + beanName + "'");
14 }
15 // 第二步: 将bean添加到singletonsCurrentlyInCreation中, 表示bean正在创建
16 beforeSingletonCreation(beanName);
17 boolean newSingleton = false;
18 boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
19 if (recordSuppressedExceptions) {
20 this.suppressedExceptions = new LinkedHashSet<>();
21 }
22 try {
23 // 第三步: 这里调用getObject()钩子方法, 就会回调匿名函数, 调用singletonFactory的createBean()
24 singletonObject = singletonFactory.getObject();
25 newSingleton = true;
26 }
27 catch (IllegalStateException ex) {
28 // Has the singleton object implicitly appeared in the meantime ->
29 // if yes, proceed with it since the exception indicates that state.
30 singletonObject = this.singletonObjects.get(beanName);
31 if (singletonObject == null) {
32 throw ex;
33 }
34 }
35 catch (BeanCreationException ex) {
36 if (recordSuppressedExceptions) {
37 for (Exception suppressedException : this.suppressedExceptions) {
38 ex.addRelatedCause(suppressedException);
39 }
40 }
41 throw ex;
42 }
43 finally {
44 if (recordSuppressedExceptions) {
45 this.suppressedExceptions = null;
46 }
47 afterSingletonCreation(beanName);
48 }
49 if (newSingleton) {
50 addSingleton(beanName, singletonObject);
51 }
52 }
53 return singletonObject;
54 }
55 }
这里是调用getBean().
第一步: 去一级缓存中取成熟的单例bean. 如果拿到了, 就直接返回. 如果没拿到. 那么执行创建.
第二步: 在创建之前, 先把这个bean放入到正在创建的单例bean集合中. 标记这个bean正在创建中
第三步: 就是调用钩子方法getObject()了. 这个方法的方法体是在上面定义的. 其内容是去创建实例
sharedInstance = getSingleton(beanName, () -> {
try {
// 这里定义了一个钩子函数. 此时只是定义, 并不执行. 在真正需要创建bean的地方才会执行
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
// Explicitly remove instance from singleton cache: It might have been put there
// eagerly by the creation process, to allow for circular reference resolution.
// Also remove any beans that received a temporary reference to the bean.
destroySingleton(beanName);
throw ex;
}
});
这里的代码逻辑是完成了创建之前的逻辑
2.3 创建bean
下面看看创建bean的过程
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
throws BeanCreationException { // Instantiate the bean.
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
/**
* 第一步: 实例化
* 这里面的调用链非常深, 后面再看
* bean实例化有两种方式
* 1. 使用反射: 使用反射也有两种方式,
* a. 通过无参构造函数 (默认的方式)
* 从beanDefinition中可以得到beanClass,
* ClassName = BeanDefinition.beanClass
* Class clazz = Class.forName(ClassName);
* clazz.newInstance();
* 这样就可以实例化bean了
*
* b. 通过有参函数.
* ClassName = BeanDefinition.beanClass
* Class clazz = Class.forName(ClassName);
* Constractor con = class.getConstractor(args....)
* con.newInstance();
*
* 2. 使用工厂
* 我们使用@Bean的方式, 就是使用的工厂模式, 自己控制实例化过程
*
*/
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
// 这里使用了装饰器的设计模式
final Object bean = instanceWrapper.getWrappedInstance();
Class<?> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {
mbd.resolvedTargetType = beanType;
} // Allow post-processors to modify the merged bean definition.
// 允许后置处理器修改已经合并的beanDefinition
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Post-processing of merged bean definition failed", ex);
}
mbd.postProcessed = true;
}
} /**
* 缓存单例bean到三级缓存中, 以防止循环依赖
* 判断是否是早期引用的bean, 如果是, 则允许提前暴露引用
*
* 判断是否能够早起暴露的条件
* 1. 是单例
* 2. 允许循环依赖
* 3. 正在创建的bean
*/
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
if (logger.isTraceEnabled()) {
logger.trace("Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references");
}
// 把我们的早期对象包装成一个singletonFactory对象, 该对象提供了getObject()方法, 把静态的bean放到三级缓存中去了.
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
} // Initialize the bean instance.
Object exposedObject = bean;
try {
// 第二步:填充属性, 给属性赋值(调用set方法) 这里也是调用的后置处理器
populateBean(beanName, mbd, instanceWrapper);
// 第三步: 初始化.
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
catch (Throwable ex) {
if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
throw (BeanCreationException) ex;
}
else {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
}
} /**
* 初始化完成以后, 判断是否是早期的对象
* 是循环依赖. 才会走进这里来
*/
if (earlySingletonExposure) {
// 去缓存中获取到我们的对象 由于传递的allowEarlyReference是false, 要求只能在一级二级缓存中取
// 正常的普通的bean(不存在循环依赖的bean) 创建的过程中, 不会把三级缓存提升到二级缓存中.
Object earlySingletonReference = getSingleton(beanName, false);
if (earlySingletonReference != null) {
if (exposedObject == bean) {
exposedObject = earlySingletonReference;
}
else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
String[] dependentBeans = getDependentBeans(beanName);
Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
for (String dependentBean : dependentBeans) {
if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
actualDependentBeans.add(dependentBean);
}
}
if (!actualDependentBeans.isEmpty()) {
throw new BeanCurrentlyInCreationException(beanName,
"Bean with name '" + beanName + "' has been injected into other beans [" +
StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
"] in its raw version as part of a circular reference, but has eventually been " +
"wrapped. This means that said other beans do not use the final version of the " +
"bean. This is often the result of over-eager type matching - consider using " +
"'getBeanNamesForType' with the 'allowEagerInit' flag turned off, for example.");
}
}
}
} // Register bean as disposable.
try {
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
} return exposedObject;
}
首先, 实例化bean, 实例化的方式有两种. 一种是通过反射, 另一种是通过动态代理
/**
* 第一步: 实例化
* 这里面的调用链非常深, 后面再看
* bean实例化有两种方式
* 1. 使用反射: 使用反射也有两种方式,
* a. 通过无参构造函数 (默认的方式)
* 从beanDefinition中可以得到beanClass,
* ClassName = BeanDefinition.beanClass
* Class clazz = Class.forName(ClassName);
* clazz.newInstance();
* 这样就可以实例化bean了
*
* b. 通过有参函数.
* ClassName = BeanDefinition.beanClass
* Class clazz = Class.forName(ClassName);
* Constractor con = class.getConstractor(args....)
* con.newInstance();
*
* 2. 使用工厂
* 我们使用@Bean的方式, 就是使用的工厂模式, 自己控制实例化过程
*
*/
instanceWrapper = createBeanInstance(beanName, mbd, args);
判断是否是早期暴露的bean. 满足早期暴露的bean的三个条件是
1. 是单例的
2. 允许循环依赖
3. bean已经是处在正在创建中的行列了.
/* 判断是否能够早起暴露的条件
* 1. 是单例
* 2. 允许循环依赖
* 3. 正在创建的bean
*/
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
创建bean的第二步: 属性赋值
// 第二步:填充属性, 给属性赋值(调用set方法) 这里也是调用的后置处理器
populateBean(beanName, mbd, instanceWrapper);
在这里会判断, 是否带有@Autowired的属性. 分为两种一种是Name,一种是Type
@SuppressWarnings("deprecation") // for postProcessPropertyValues
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
if (bw == null) {
if (mbd.hasPropertyValues()) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
}
else {
// Skip property population phase for null instance.
return;
}
} // Give any InstantiationAwareBeanPostProcessors the opportunity to modify the
// state of the bean before properties are set. This can be used, for example,
// to support styles of field injection.
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
return;
}
}
}
} PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null); // 判断属性是否有Autowired注解
int resolvedAutowireMode = mbd.getResolvedAutowireMode();
// Autowired是根据名字或者根据类型
if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
// Add property values based on autowire by name if applicable.
if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
autowireByName(beanName, mbd, bw, newPvs);
}
// Add property values based on autowire by type if applicable.
if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
autowireByType(beanName, mbd, bw, newPvs);
}
pvs = newPvs;
} ......
}
如果按照名字注入
protected void autowireByName(
String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) { String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
for (String propertyName : propertyNames) {
if (containsBean(propertyName)) {
// 调用getBean
Object bean = getBean(propertyName);
pvs.add(propertyName, bean);
registerDependentBean(propertyName, beanName);
if (logger.isTraceEnabled()) {
logger.trace("Added autowiring by name from bean name '" + beanName +
"' via property '" + propertyName + "' to bean named '" + propertyName + "'");
}
}
else {
if (logger.isTraceEnabled()) {
logger.trace("Not autowiring property '" + propertyName + "' of bean '" + beanName +
"' by name: no matching bean found");
}
}
}
}
会再次调用getBean方法. 构建bean. 这是就有可能出现循环依赖了.
按类型注入也是一样的.
只是解析bean的方式不同.
创建bean的第三步: 初始化
// 第三步: 初始化.
exposedObject = initializeBean(beanName, exposedObject, mbd);
在初始化bean的时候, 会调用很多的aware. 还会调用init-method方法. 以及bean的后置处理器.
第四步:删除实例化和静态方法在缓存中的数据
/**
* 初始化完成以后, 判断是否是早期的对象
* 是循环依赖. 才会走进这里来
*/
if (earlySingletonExposure) {
// 去缓存中获取到我们的对象 由于传递的allowEarlyReference是false, 要求只能在一级二级缓存中取
// 正常的普通的bean(不存在循环依赖的bean) 创建的过程中, 不会把三级缓存提升到二级缓存中.
Object earlySingletonReference = getSingleton(beanName, false);
if (earlySingletonReference != null) {
if (exposedObject == bean) {
exposedObject = earlySingletonReference;
}
else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
String[] dependentBeans = getDependentBeans(beanName);
Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
for (String dependentBean : dependentBeans) {
if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
actualDependentBeans.add(dependentBean);
}
}
if (!actualDependentBeans.isEmpty()) {
throw new BeanCurrentlyInCreationException(beanName,
"Bean with name '" + beanName + "' has been injected into other beans [" +
StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
"] in its raw version as part of a circular reference, but has eventually been " +
"wrapped. This means that said other beans do not use the final version of the " +
"bean. This is often the result of over-eager type matching - consider using " +
"'getBeanNamesForType' with the 'allowEagerInit' flag turned off, for example.");
}
}
}
}
removeSingletonIfCreatedForTypeCheckOnly调用方法, 删除缓存.
这既是getBean()整个的过程. 中间还有很多细节, 没有往里面深入的看, 因为spring代码非常的深, 看的太深就忘了我们的目标了. 结合之前手写的spring循环依赖的思想看, 还是可以看得懂的.
三. 接下来有几个问题
问题1: 为什么需要二级缓存和三级缓存?
二级缓存用来存放早期的bean, 也就是没有被属性赋值和初始化的bean
三级缓存的主要作用是用来解耦. 解耦后异步调用, 三级缓存中保存的是钩子方法,也就是一个接口。在使用的时候调用bean的后置处理器
问题2:有没有解决构造函数的循环依赖
答案是没有. 因为构造函数是在实例化的时候构建的. 这个时候bean都还没有创建, 所以没有办法处理循环依赖.如果出现构造函数的循环依赖, 是会直接报错的..
问题3:有没有解决多例下的循环依赖
也是没有的, 因为我们会判断, 如果是多例, 那么会抛出异常
1 /**
2 * 第二步: 判断当前bean是否是正在创建中的多例bean, 如果是就抛出异常
3 *
4 * 2. 判断当前这个bean是不是多例bean. 如果配置了@Scope("prototype") 就表示这是一个多例的bean
5 * spring 只能解决单例对象的setter注入的循环依赖, 不能解决构造器注入
6 *
7 * 如果是多例的bean, 当前正在创建bean, 也会抛出异常---这也是循环依赖的问题
8 */
9 if (isPrototypeCurrentlyInCreation(beanName)) {
10 throw new BeanCurrentlyInCreationException(beanName);
11 }