spring三级缓存和循环依赖

什么是循环依赖?#

当有两个bean,分别用set方法依赖对方。就会造成循环依赖,如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
@Data
@Component
public class A {
private B b;
}


@Data
@Component
public class B {
private A a;
}

// main方法中去获取A对象
AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext("com.sam");
A aaa = ac.getBean(A.class);
System.out.println(aaa.getClass());

背景----三级缓存快速入门#

看一个对象DefaultSingletonBeanRegistry,他是DefaultListableBeanFactory的父类,里面有三级缓存:

1
2
3
4
5
6
7
8
9
10
11
12
// 一级缓存,存放实例化并初始化完毕的bean
/** Cache of singleton objects: bean name to bean instance. */
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);

// 二级缓存,存放实例化但是还未初始化的bean
/** Cache of early singleton objects: bean name to bean instance. */
private final Map<String, Object> earlySingletonObjects = new HashMap<>(16);

// 三级缓存,存放还未初始化的ObjectFactory,是一个函数式接口。使用getObject进行初始化
/** Cache of singleton factories: bean name to ObjectFactory. */
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);

实例化过程#

背景,默认BeanPostProcessor#

先来混个脸熟悉,下面过程中会看到他们

历史已有BPP:4个#

  • org.springframework.context.support.ApplicationContextAwareProcessor------------给我们注入AC对象、BF、env等各种aware
  • org.springframework.boot.web.servlet.context.WebApplicationContextServletContextAwareProcessor---------web环境注入Web的AC对象的
  • org.springframework.context.support.PostProcessorRegistrationDelegate$BeanPostProcessorChecker----------
  • org.springframework.context.annotation.ConfigurationClassPostProcessor$ImportAwareBeanPostProcessor
    • 用于给注解完成配置,如
      @EnableRedisHttpSession(redisNamespace = “web:session”),可以

依次注册:#

@PriorityOrdered:

  • org.springframework.boot.context.properties.ConfigurationPropertiesBindingPostProcessor

@Ordered

  • org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator
    • AOP代理生成
  • org.springframework.boot.web.server.WebServerFactoryCustomizerBeanPostProcessor
  • org.springframework.boot.web.server.ErrorPageRegistrarBeanPostProcessor
  • org.springframework.context.annotation.CommonAnnotationBeanPostProcessor
    • 完成Javax的@Resource等通用注解的metaFata解析,并链式依赖注入
  • org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor
    • 完成@Autowired等注解的MetaData 解析,并链式注入
  • org.springframework.context.support.ApplicationListenerDetector

Bean创建过程#

  • 我们的abstractContext里面的refresh方法经过一系列的扫描解析,把BeanDefinition获取到BeanFactory中去。同时执行一大堆BeanDefinitionRegistryPostProcessor,和BeanFactoryPostProcessor去控制我们的BeanDifinition的生成行为。在refresh的registerBeanPostProcessors方法中注册了一堆BeanPostProcessor,然后会来调用此处的beanFactory.preInstantiateSingletons()
  • BF的preInstantiateSingletons方法循环所有的beanName(比如有a,b,c三个bean):
    • 拿出MergedRootBeanDefinition去getBean:
    • FactoryBean去创建doGetBean(&beanName)、普通bean去doGetBean(beanName):
      • 先去执行一次第一个getSingleton(beanName);看看有没有之前被放进去过(比如被循环依赖,或者被@DependsOn创建过),正常会返回null
      • 拿到beanFactory,在set标记为正在创建中,开始继续创建
      • 拿到beanDefinition,判断里面的@DependsOn,如果有,先getBean递归创建依赖的对象
      • 调用下面第二个getSingleton(beanName, () -> {return createBean(beanName, mbd, args);}),传入一个createBean的lambda参数的匿名内部类。:
        • 下面第二个getSingleton里面的逻辑:对一级缓存加锁,尝试去拿一下。
        • 拿不到就先beforeSingletonCreation(beanName);调用一个回调,由子类BF实现
        • singletonFactory.getObject()调用匿名类的lambda表达式里面的createBean方法去创建对象
          • createBean方法先从bd解析出class
          • 调用BeanPostProcessor,来看看有没有谁能返回一个对象Object bean = resolveBeforeInstantiation(beanName, mbdToUse);,如果某个BPP返回了对象,就直接丢回去。(此处明显是创建一个代理对象,AOP在此实现
          • 如果上一步没有哪个BPP返回代理对象,调用doCreateBean(beanName, mbdToUse, args);创建并返回一个bean:
            • doCraeteBean里面就使用createBeanInstance方法去反射创建对象(FactoryBean是getObject和普通Bean不一样,同时BPP可以决定构造方法),创建的对象是空的,没有设值。-----------------刚刚实例化,还没放到BF中
            • 然后applyMergedBeanDefinitionPostProcessors执行了MergedBeanDefinitionPostProcessor,比如CommonAnnotationBeanPostProcessor去检测@Resource这种Java.injection的注解生成metadata、AutowiredAnnotationBeanPostProcessor去检测了@Auowired这种Spring的注解,生成他们的metadata,可以去改一次bd的信息。
            • boolean earlySingletonExposure解决循环依赖第一步:
              • 如果true,然后调用了addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));,把getEarlyBeanReference这个ObjectFactory函数式接口放到三级缓存{k:a, v:匿名类},并把二级缓存删掉(有的话)---------此时bean算是实例化完毕并放到三级缓存中,接下来是初始化过程
            • 调用populateBean(beanName, mbd, instanceWrapper)填充bean
              • 执行InstantiationAwareBeanPostProcessor#postProcessAfterInstantiation回调,允许spring填充前改变bean的属性。默认都是null。
              • 循环依赖,根据注入类型,执行autowireByName(beanName, mbd, bw, newPvs);或者autowireByType(beanName, mbd, bw, newPvs);进行注入,拿到propertyValue
              • 遍历BPP(此时都是InstantiationAwareBeanPostProcessor),执行postProcessAfterInstantiation
                • CommonAnnotationBeanPostProcessorpostProcessProperties去解析之前@Resource属性的metadata,调用InjectMedadata.inject、使用doResolveDependency去getBean拿到PropertyValues递归注入
                • AutowiredAnnotationBeanPostProcessorpostProcessProperties去解析之前@Auowired属性的metadata,doResolveDependency去getBean拿到PropertyValues递归注入
                • xml的setter是拿到propertyValue去注入,和上面类似。
                • 假设A里面是@Autowired B B里面也是@Autowired A,的循环依赖此时正在解析A的时候发现了B,会再去getBean(B) (此时三级a):
                  • B创建完毕放到三级缓存。此时(三级a,b:获取对象的一个匿名内部类)
                  • B来populateBean的时候到达这里就会需要注入A,到达这里就会再getBean(A):
                    • 调用地一个getSingleton方法,会拿到A的匿名类的三级缓存getEarlyBeanReference(beanName, mbd, bean),从三级缓存里面拿出来实例化还未初始化的A对象a,并把它转移到二级缓存中。(此时二级a,三级b)
                    • 然后给B对象的a属性赋值a的早期对象
                    • 然后B创建完毕放到三级缓存,返回并注册(此时一级b:完全状态实例化和初始化都结束,二级a:创建中,实例化未初始化状态)
                • A设置b,返回注册(此时一级a,b,都是完全状态)
              • 执行afterSingletonCreation(beanName);方法,留给子类BF拓展
              • addSingleton(beanName, singletonObject);
            • 初始化initializeBeanexposedObject = initializeBean(beanName, exposedObject, mbd);得到一个可以暴露的对象:-----------------AOP
              • 如果class是Aware,给他塞BF、ClassLoader:
              • 1.applyBeanPostProcessorsBeforeInitialization:执行所有BPP的BeforeInit方法:
                • 如果实现了Aware,invokeAwareMethods方法ApplicationContextAwareProcessor里面塞各种Aware,如contextenv
                • ImportAwareBeanPostProcessorpostProcessBeforeInitialization给我们的Bean塞进去注解上metadata
              • 2.invokeInitMethods
                • 执行@afterPropertiesSet这个init方法
              • 3.applyBeanPostProcessorsAfterInitialization--------AOP在此实现
                • postProcessAfterInitialization执行,其中ApplicationListenerDetector去检查这个类是否是一个监听器,是的话加入到applicationContext里面
                • AbstractAutoProxyCreatorpostProcessAfterInitialization方法调用了wrapIfNecessary去创建代理:
                  • 拿到这个类的切面,有才继续调用createProxy方法创建代理:
                    • 给bd的origianlTargetClass塞进去代理前的类名,new 一个 ProxyFactory
                    • 拿到这个类的接口,遍历每一个,只要找到一个非InitializingBeanCloseableAware`等无需代理的接口、就继续
                    • 有接口就加到proxyFactory中,没有的话就设置代理class标识为true(后面判断jdk还是cglib)
                    • buildAdvisors构建切面拦截的列表,添加到proxyFactory
                    • 提供一个扩展点customizeProxyFactory(proxyFactory);
                    • createAopProxy().getProxy(clazzLoader)就创建代理:
                      • 调用DefaultAopProxyFactory#createAopProxy(AdvisedSupport config)创建动态代理:
                        • 如果有接口new JdkDynamicAopProxy(config),创建JDK动态代理,InvocationHandler,拦截invoke方法
                        • 没有接口new ObjenesisCglibAopProxy(config),创建CGlib动态代理,enhancer增强器塞接口/属性/类、设置callback、method intercepter
            • 调用第一个getSingleton(name,false),只从1、2拿,是null,然后registerDisposableBeanIfNecessary是个空
            • 结束doCreateBean,得到一个BeanWarper包装类
          • 结束CreateBean,getBean一次去从三级getSingleton缓存拿出来
          • 发现是新的bean,addSingleton(name,bean),注册到一级缓存,清除二级三级缓存。
          • afterSingletonCreation(String beanName)留给子类BF实现拓展
        • 结束getSingleton
      • 结束doGetBean
    • 结束getBean
  • 继续循环创建下一个对象

核心方法摘录说明#

doGetBean方法#

AbstractBeanFactoryDefaultSingletonBeanRegistry的一个子类,中有一个doGetBean方法承接了外面的各种getBean的调用,是每一个单例对象创建的具体实现方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
// 真正创建一个Bean
protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
// beanName生成,一般和FactoryBean的&有关
final String beanName = transformedBeanName(name);
Object bean;

// 上来先去赶紧检查有没有手动注册上去他(或者在被别的bean依赖的时候已经初始化了,如例子中的B对象),否则会返回null
// Eagerly check singleton cache for manually registered singletons.
Object sharedInstance = getSingleton(beanName); // 没有被注册过,或则被其他bean以来的时候创建过,这里会返回null
if (sharedInstance != null && args == null) {
if (logger.isTraceEnabled()) {
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 {
// Fail if we're already creating this bean instance:
// We're assumably within a circular reference.
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}

// 父容器,不用管
// Check if bean definition exists in this factory.
BeanFactory parentBeanFactory = getParentBeanFactory();
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
// Not found -> check parent.
String nameToLookup = originalBeanName(name);
if (parentBeanFactory instanceof AbstractBeanFactory) {
return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
nameToLookup, requiredType, args, typeCheckOnly);
}
else if (args != null) {
// Delegation to parent with explicit args.
return (T) parentBeanFactory.getBean(nameToLookup, args);
}
else if (requiredType != null) {
// No args -> delegate to standard getBean method.
return parentBeanFactory.getBean(nameToLookup, requiredType);
}
else {
return (T) parentBeanFactory.getBean(nameToLookup);
}
}

// 打个标记,放到alreadyCreated中
if (!typeCheckOnly) {
markBeanAsCreated(beanName);
}

// 拿到parent BeanDefinition和child BeanDefinition的组合
try {
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
checkMergedBeanDefinition(mbd, beanName, args);

// 拿到当前dependsOn的Bean,去getBean处理dependsOn的类列表
// Guarantee initialization of beans that the current bean depends on.
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
for (String dep : dependsOn) {
if (isDependent(beanName, dep)) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
}
registerDependentBean(dep, beanName);
try {
getBean(dep); // 递归获取dependsOn的对象
}
catch (NoSuchBeanDefinitionException ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
}
}
}

//----------------------开始创建对象-----------------------
// Create bean instance.
if (mbd.isSingleton()) {
// 调用下面第二个getSingleton,见其描述,传进去一个lambda表达式,继续往下看,暂时还没执行这个lambda
sharedInstance = getSingleton(beanName, () -> {
try {
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;
}
});
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}

else if (mbd.isPrototype()) {
// It's a prototype -> create a new instance.
Object prototypeInstance = null;
try {
beforePrototypeCreation(beanName);
prototypeInstance = createBean(beanName, mbd, args);
}
finally {
afterPrototypeCreation(beanName);
}
bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
}

else {
String scopeName = mbd.getScope();
final Scope scope = this.scopes.get(scopeName);
if (scope == null) {
throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
}
try {
Object scopedInstance = scope.get(beanName, () -> {
beforePrototypeCreation(beanName);
try {
return createBean(beanName, mbd, args);
}
finally {
afterPrototypeCreation(beanName);
}
});
bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
}
catch (IllegalStateException ex) {
throw new BeanCreationException(beanName,
"Scope '" + scopeName + "' is not active for the current thread; consider " +
"defining a scoped proxy for this bean if you intend to refer to it from a singleton",
ex);
}
}
}
catch (BeansException ex) {
cleanupAfterBeanCreationFailure(beanName);
throw ex;
}
}

// Check if required type matches the type of the actual bean instance.
if (requiredType != null && !requiredType.isInstance(bean)) {
try {
T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);
if (convertedBean == null) {
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
return convertedBean;
}
catch (TypeMismatchException ex) {
if (logger.isTraceEnabled()) {
logger.trace("Failed to convert bean '" + name + "' to required type '" +
ClassUtils.getQualifiedName(requiredType) + "'", ex);
}
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
}
return (T) bean;
}

createBean 上面lambda表达式来创建自己的核心方法#

这个方法非常简单:

  • 从beanDefinition拿出Class
  • 可以允许BeanPostProcessor创建代理对象resolveBeforeInstantiation(beanName, mbdToUse)方法如果返回对象,就丢回去。
    • 其实就是拿到所有的InstantiationAwareBeanPostProcessor子类,最主要的AOP类AbstractAutoProxyCreator#postProcessBeforeInstantiation里面进行createProxy方法找到ProxyFactory类,调用AopProxy#createAopProxy方法,有两个实现
  • 否则继续后面的doCreateBean去使用lambda表达式真正创建
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
// 一堆检查,拿出class,别的都不重要
if (logger.isTraceEnabled()) {
logger.trace("Creating instance of bean '" + beanName + "'");
}
RootBeanDefinition mbdToUse = mbd;

// Make sure bean class is actually resolved at this point, and
// clone the bean definition in case of a dynamically resolved Class
// which cannot be stored in the shared merged bean definition.
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}

// Prepare method overrides.
try {
mbdToUse.prepareMethodOverrides();
}
catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
beanName, "Validation of method overrides failed", ex);
}
// 注意这里,是使用BeanPostProcessor来创建代理,如果创建了就返回代理,否则下面采取真正调用doCreateBean创建真正的对象
try {
// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {
return bean;
}
}
catch (Throwable ex) {
throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
"BeanPostProcessor before instantiation of bean failed", ex);
}

// 调用doCreateBean创建真正的对象
try {
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isTraceEnabled()) {
logger.trace("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
}
catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
// A previously detected exception with proper bean creation context already,
// or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry.
throw ex;
}
catch (Throwable ex) {
throw new BeanCreationException(
mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
}
}

doCreateBean#

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
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) {
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.
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;
}
}

// Eagerly cache singletons to be able to resolve circular references
// even when triggered by lifecycle interfaces like BeanFactoryAware.
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");
}
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}

// Initialize the bean instance.
Object exposedObject = bean;
try {
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) {
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 " +
"'getBeanNamesOfType' 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;
}

addSingleton 添加一级缓存#

清空二级三级缓存

1
2
3
4
5
6
7
8
protected void addSingleton(String beanName, Object singletonObject) {
synchronized (this.singletonObjects) {
this.singletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
this.earlySingletonObjects.remove(beanName);
this.registeredSingletons.add(beanName);
}
}

addSingletonFactory添加三级缓存#

1
2
3
4
5
6
7
8
9
10
11
12
protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {
Assert.notNull(singletonFactory, "Singleton factory must not be null");
// 锁定一级缓存
synchronized (this.singletonObjects) {
// 一级缓存里面没有,把ObjectFactory放到三级缓存,并把二级缓存删掉
if (!this.singletonObjects.containsKey(beanName)) {
this.singletonFactories.put(beanName, singletonFactory);
this.earlySingletonObjects.remove(beanName);
this.registeredSingletons.add(beanName);
}
}
}

addSingleton添加一级缓存#

1
2
3
4
5
6
7
8
9
protected void addSingleton(String beanName, Object singletonObject) {
synchronized (this.singletonObjects) {
// 锁定一级缓存,放入一级缓存,清理三级、二级缓存,注册对象
this.singletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
this.earlySingletonObjects.remove(beanName);
this.registeredSingletons.add(beanName);
}
}

各个重载的getSingleton#

第一个getSingleton(beanName, boolean allowEarlyReference) ,依次从一级、二级、三级拿。三级的ObjectFactory.getObject升级到二级。#

初次过来这里会返回null,各级缓存都没有,没有则返回。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
// 返回初始化好的bean,或者实例化还未初始化的二级缓存。同时从三级缓存remove
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
// 一级缓存中去获取
Object singletonObject = this.singletonObjects.get(beanName);
// 如果没有的话,检查是否在创建中(一个set中有没有标识)
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
// 创建中的bean,就加锁
synchronized (this.singletonObjects) {
// 从二级缓存里面获取
singletonObject = this.earlySingletonObjects.get(beanName);
// 如果二级缓存为空,但是允许返回提前引用
if (singletonObject == null && allowEarlyReference) {
// 就从三级缓存里面拿
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
// 三级缓存不为空,就调用ObjectFactory函数式接口的 getObject方法创建一个二级缓存
singletonObject = singletonFactory.getObject();
// 然后吧这个早期的对象放入到二级缓存中暴露
this.earlySingletonObjects.put(beanName, singletonObject);
// 从三级缓存移除
this.singletonFactories.remove(beanName);
}
}
}
}
return singletonObject;
}

第二个getSingleton(beanName, ObjectFactory<?> singletonFactory) ,传入ObjectFactory这个lambda表达式#

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
/**
* Return the (raw) singleton object registered under the given name,
* creating and registering a new one if none registered yet.
* @param beanName the name of the bean
* @param singletonFactory the ObjectFactory to lazily create the singleton
* with, if necessary
* @return the registered singleton object
*/
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
Assert.notNull(beanName, "Bean name must not be null");
synchronized (this.singletonObjects) {
// 锁定一级缓存,获取一下
Object singletonObject = this.singletonObjects.get(beanName);
//
if (singletonObject == null) {
if (this.singletonsCurrentlyInDestruction) {
throw new BeanCreationNotAllowedException(beanName,
"Singleton bean creation not allowed while singletons of this factory are in destruction " +
"(Do not request a bean from a BeanFactory in a destroy method implementation!)");
}
if (logger.isDebugEnabled()) {
logger.debug("Creating shared instance of singleton bean '" + beanName + "'");
}
// 一个给子BeanFactory的拓展点,此处为空
beforeSingletonCreation(beanName);
boolean newSingleton = false;
boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
if (recordSuppressedExceptions) {
this.suppressedExceptions = new LinkedHashSet<>();
}
try {
// 开始调用lambda函数接口,使用createBean方法真正创建一个对象》》》》》》》》》》》》》》》》》
singletonObject = singletonFactory.getObject();
newSingleton = true;
}
catch (IllegalStateException ex) {
// Has the singleton object implicitly appeared in the meantime ->
// if yes, proceed with it since the exception indicates that state.
singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
throw ex;
}
}
catch (BeanCreationException ex) {
if (recordSuppressedExceptions) {
for (Exception suppressedException : this.suppressedExceptions) {
ex.addRelatedCause(suppressedException);
}
}
throw ex;
}
finally {
if (recordSuppressedExceptions) {
this.suppressedExceptions = null;
}
afterSingletonCreation(beanName);
}
if (newSingleton) {
addSingleton(beanName, singletonObject);
}
}
return singletonObject;
}
}

getEarlyBeanReference 获取三级缓存早期对象#

如getBean( A) --populate–>getBean( B)–populate—>getBean( A)的时候,去到getSingleton(A)发生循环引用,从三级缓存里面调用过来:

// getEarlyBeanReference(“a”, bd, a@123对象)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/**
* Obtain a reference for early access to the specified bean,
* typically for the purpose of resolving a circular reference.
* @param beanName the name of the bean (for error handling purposes)
* @param mbd the merged bean definition for the bean
* @param bean the raw bean instance
* @return the object to expose as bean reference
*/
// getEarlyBeanReference("a", bd, a@123对象)
protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {
Object exposedObject = bean; // 已经创建还未初始化的a对象
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
// 给BPP进行操作,默认都没有实现,此时可以AOP!!!!!!!!!!!!!!
// AbstractAutoProxyCreator#getEarlyBeanReference,里面wrapIfNecessary进行createProxy创建代理
SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName);
}
}
}
return exposedObject;
}

AOP实现#

  • 我们的@EnableAspectJAutoProxy注解的Config类是一个@Configuration会在refresh的invokeBeanFactoryPostProcessors中被ConfigurationClassPostProcessor识别到。使用import技术扫描加载@Import(AspectJAutoProxyRegistrar.class)。(见spring启动流程文章)

  • 使用AspectJAutoProxyRegistrar里面的ImportBeanDefinitionRegistrar实现去拿到beanDifinitionReigistry(其实就是BF),注入了一个AnnotationAwareAspectJAutoProxyCreator这个BeanPostProcessor

  • 然后在refresh的实例化bean方法finishBeanFactoryInitialization(beanFactory);中的doCreateBean中先反射创建对象,然后的initBean里面初始化:

    • 执行BPP的beforePostProcessor方法
    • 执行init方法(@PostConstruct)
    • 执行后置处理器去调用上面这个BPP的postProcessorAfterBeanInit完成代理。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware {

// 里面有各个BeanPostProcesser的方法实现, 核心就是下面这个在实例化之前调用来决定是否创建代理,创建何种代理的方法
@Override
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) {
Object cacheKey = getCacheKey(beanClass, beanName);

if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) {
if (this.advisedBeans.containsKey(cacheKey)) {
return null;
}
if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return null;
}
}

// Create proxy here if we have a custom TargetSource.
// Suppresses unnecessary default instantiation of the target bean:
// The TargetSource will handle target instances in a custom fashion.
TargetSource targetSource = getCustomTargetSource(beanClass, beanName);
if (targetSource != null) {
if (StringUtils.hasLength(beanName)) {
this.targetSourcedBeans.add(beanName);
}
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
}

return null;
}

// ...



@Override
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
if (bean != null) {
Object cacheKey = getCacheKey(bean.getClass(), beanName);
if (this.earlyProxyReferences.remove(cacheKey) != bean) {
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}


/**
* Wrap the given bean if necessary, i.e. if it is eligible for being proxied.
* @param bean the raw bean instance
* @param beanName the name of the bean
* @param cacheKey the cache key for metadata access
* @return a proxy wrapping the bean, or the raw bean instance as-is
*/
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
return bean;
}
if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
return bean;
}
if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}

// Create proxy if we have advice.
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
if (specificInterceptors != DO_NOT_PROXY) {
this.advisedBeans.put(cacheKey, Boolean.TRUE);
Object proxy = createProxy(
bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
}

this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}




protected Object createProxy(Class<?> beanClass, @Nullable String beanName,
@Nullable Object[] specificInterceptors, TargetSource targetSource) {

if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);
}

ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.copyFrom(this);

if (!proxyFactory.isProxyTargetClass()) {
if (shouldProxyTargetClass(beanClass, beanName)) {
proxyFactory.setProxyTargetClass(true);
}
else {
evaluateProxyInterfaces(beanClass, proxyFactory);
}
}

Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
proxyFactory.addAdvisors(advisors);
proxyFactory.setTargetSource(targetSource);
customizeProxyFactory(proxyFactory);

proxyFactory.setFrozen(this.freezeProxy);
if (advisorsPreFiltered()) {
proxyFactory.setPreFiltered(true);
}

return proxyFactory.getProxy(getProxyClassLoader());
}
}

DefaultAopProxyFactory的createAopProxy(AdvisedSupport config) 真正创建代理#

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public class DefaultAopProxyFactory implements AopProxyFactory, Serializable {

// AOP创建代理的实现,没有接口使用CGlib,有接口使用JDK动态代理
@Override
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
Class<?> targetClass = config.getTargetClass();
if (targetClass == null) {
throw new AopConfigException("TargetSource cannot determine target class: " +
"Either an interface or a target is required for proxy creation.");
}
if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
return new JdkDynamicAopProxy(config);
}
return new ObjenesisCglibAopProxy(config); // 创建cglib动态代理,enhancer塞接口、类、callback、method intercepter
}
else {
return new JdkDynamicAopProxy(config); // 创建JDK动态代理,丢一个InvocationHandler对象,每次执行调用invoke方法拦截处理
}
}

// ....
}

QA#

  • 一级缓存能解决么?
    • 不行,因为如果只有一级缓存,创建中(实例化还没初始化)的对象和创建结束的对象都在一个map中,可能导致正在创建中的对象被用户提前获取属性为空,导致空指针。此时可以加一个二级缓存来存放还没初始化完毕的对象。
  • 为什么一定要三级缓存?二级不就行了么?
    • 三级里面放的是一个匿名内部类,包装了一个刚刚实例化的对象。getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) ,调用了BPP去进行判断,我们的对象是简单对象还是需要进行代理的。
    • 三级缓存的主要意义:代理。比如 AbstractAutoProxyCreator#getEarlyBeanReference,里面wrapIfNecessary进行createProxy创建代理,我们的对象在向三级缓存放置之后,可以在读取的时候通过pambda表达式去执行BPP的方法,给BPP一个机会来判断是否需要进行代理,选择代理方式进行代理。
    • 生成代理之后我们用户使用都应该是代理对象,如果不放到三级缓存,可能代理之前被获取到原始对象,导致代理失败。放了三级缓存之后,只要有人去拿就会判断是否代理,不会造成代理目标逃逸,代理失败的情况。也就是保证了不管什么时候获取的对象都是代理过的。