Skip to content

Commit 7ed4940

Browse files
committed
[Advance][Circular dependency][fix] resolve circular use second third cache
1 parent 822a461 commit 7ed4940

5 files changed

+93
-8
lines changed

src/main/java/org/m1a2st/aop/autoproxy/DefaultAdvisorAutoProxyCreator.java

+17
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
import org.m1a2st.beans.factory.support.DefaultListableBeanFactory;
1414

1515
import java.util.Collection;
16+
import java.util.HashSet;
17+
import java.util.Set;
1618

1719
/**
1820
* @Author m1a2st
@@ -23,6 +25,8 @@ public class DefaultAdvisorAutoProxyCreator implements InstantiationAwareBeanPos
2325

2426
private DefaultListableBeanFactory beanFactory;
2527

28+
private final Set<Object> earlyProxyReferences = new HashSet<>();
29+
2630
@Override
2731
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
2832
this.beanFactory = (DefaultListableBeanFactory) beanFactory;
@@ -38,8 +42,21 @@ public boolean postProcessAfterInstantiation(Object bean, String beanName) throw
3842
return true;
3943
}
4044

45+
@Override
46+
public Object getEarlyBeanReference(Object bean, String beanName) throws BeansException {
47+
earlyProxyReferences.add(beanName);
48+
return wrapIfNecessary(bean, beanName);
49+
}
50+
4151
@Override
4252
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
53+
if (!earlyProxyReferences.contains(beanName)) {
54+
return wrapIfNecessary(bean, beanName);
55+
}
56+
return bean;
57+
}
58+
59+
protected Object wrapIfNecessary(Object bean, String beanName) {
4360
// 避免死循環
4461
if (isInfrastructureClass(bean.getClass())) {
4562
return null;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package org.m1a2st.beans.factory;
2+
3+
import org.m1a2st.beans.BeansException;
4+
5+
/**
6+
* @Author m1a2st
7+
* @Date 2023/7/26
8+
* @Version v1.0
9+
*/
10+
public interface ObjectFactory<T> {
11+
12+
T getObject() throws BeansException;
13+
}

src/main/java/org/m1a2st/beans/factory/config/InstantiationAwareBeanPostProcessor.java

+12
Original file line numberDiff line numberDiff line change
@@ -40,4 +40,16 @@ public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor {
4040
* @throws BeansException bean處理異常
4141
*/
4242
PropertyValues postProcessPropertyValues(PropertyValues pvs, Object bean, String beanName) throws BeansException;
43+
44+
/**
45+
* 提前曝露 bean
46+
*
47+
* @param bean bean實例
48+
* @param beanName bean的名稱
49+
* @return bean實例
50+
* @throws BeansException bean處理異常
51+
*/
52+
default Object getEarlyBeanReference(Object bean, String beanName) throws BeansException {
53+
return bean;
54+
}
4355
}

src/main/java/org/m1a2st/beans/factory/support/AbstractAutowireCapableBeanFactory.java

+23-3
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,10 @@ protected Object doCreateBean(String beanName, BeanDefinition beanDefinition) th
7575
// 創造Bean 實體
7676
bean = createBeanInstance(beanDefinition);
7777
// 為解決循環依賴,將實例化的Bean放入緩存提前暴露
78-
earlySingletonObjects.put(beanName, bean);
78+
if (beanDefinition.isSingleton()) {
79+
Object finalBean = bean;
80+
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, beanDefinition, finalBean));
81+
}
7982
// bean 實例化後進行
8083
if (!applyBeanPostProcessorsAfterInstantiation(beanName, bean)) {
8184
return bean;
@@ -91,10 +94,27 @@ protected Object doCreateBean(String beanName, BeanDefinition beanDefinition) th
9194
}
9295
// 註冊有銷毀方法的Bean
9396
registerDisposableBeanIfNecessary(beanName, bean, beanDefinition);
97+
98+
Object exposeObject = bean;
9499
if (beanDefinition.isSingleton()) {
95-
addSingleton(beanName, bean);
100+
// 如果有代理對象,此處獲取代理對象
101+
exposeObject = getSingleton(beanName);
102+
addSingleton(beanName, exposeObject);
96103
}
97-
return bean;
104+
return exposeObject;
105+
}
106+
107+
protected Object getEarlyBeanReference(String beanName, BeanDefinition beanDefinition, Object bean) {
108+
Object exposedObject = bean;
109+
for (BeanPostProcessor bp : getBeanPostProcessors()) {
110+
if (bp instanceof InstantiationAwareBeanPostProcessor) {
111+
exposedObject = ((InstantiationAwareBeanPostProcessor) bp).getEarlyBeanReference(exposedObject, beanName);
112+
if (exposedObject == null) {
113+
return null;
114+
}
115+
}
116+
}
117+
return exposedObject;
98118
}
99119

100120
/**

src/main/java/org/m1a2st/beans/factory/support/DefaultSingletonBeanRegistry.java

+28-5
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import org.m1a2st.beans.BeansException;
44
import org.m1a2st.beans.factory.DisposableBean;
5+
import org.m1a2st.beans.factory.ObjectFactory;
56
import org.m1a2st.beans.factory.config.SingletonBeanRegistry;
67

78
import java.util.ArrayList;
@@ -20,22 +21,44 @@
2021
*/
2122
public class DefaultSingletonBeanRegistry implements SingletonBeanRegistry {
2223

24+
// 二級緩存
25+
protected final Map<String, Object> earlySingletonObjects = new ConcurrentHashMap<>();
26+
// 一級緩存
2327
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>();
28+
// 三級緩存
29+
private final Map<String, ObjectFactory<?>> singletonFactories = new ConcurrentHashMap<>();
30+
2431
private final Map<String, DisposableBean> disposableBeans = new ConcurrentHashMap<>();
25-
protected final Map<String, Object> earlySingletonObjects = new ConcurrentHashMap<>();
2632

2733
@Override
2834
public Object getSingleton(String beanName) {
29-
Object bean = singletonObjects.get(beanName);
30-
if (bean == null) {
31-
bean = earlySingletonObjects.get(beanName);
35+
Object singletonObject = singletonObjects.get(beanName);
36+
if (singletonObject == null) {
37+
singletonObject = earlySingletonObjects.get(beanName);
38+
if (singletonObject == null) {
39+
ObjectFactory<?> singletonFactory = singletonFactories.get(beanName);
40+
if (singletonFactory != null) {
41+
// 這裡的singletonObject是一個ObjectFactory,而不是bean實例
42+
singletonObject = singletonFactory.getObject();
43+
// 從三級緩存放進二級緩存
44+
earlySingletonObjects.put(beanName, singletonObject);
45+
// 從三級緩存移除
46+
singletonFactories.remove(beanName);
47+
}
48+
}
3249
}
33-
return bean;
50+
return singletonObject;
51+
}
52+
53+
protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {
54+
singletonFactories.put(beanName, singletonFactory);
3455
}
3556

3657
@Override
3758
public void addSingleton(String beanName, Object singletonObject) {
3859
singletonObjects.put(beanName, singletonObject);
60+
earlySingletonObjects.remove(beanName);
61+
singletonFactories.remove(beanName);
3962
}
4063

4164
public void registerDisposableBean(String beanName, DisposableBean bean) {

0 commit comments

Comments
 (0)