From 7ed4940180588b47afdadd5a55b58fabcba3e247 Mon Sep 17 00:00:00 2001 From: m1a2st Date: Wed, 26 Jul 2023 21:19:38 +0800 Subject: [PATCH] [Advance][Circular dependency][fix] resolve circular use second third cache --- .../DefaultAdvisorAutoProxyCreator.java | 17 ++++++++++ .../m1a2st/beans/factory/ObjectFactory.java | 13 ++++++++ .../InstantiationAwareBeanPostProcessor.java | 12 +++++++ .../AbstractAutowireCapableBeanFactory.java | 26 +++++++++++++-- .../support/DefaultSingletonBeanRegistry.java | 33 ++++++++++++++++--- 5 files changed, 93 insertions(+), 8 deletions(-) create mode 100644 src/main/java/org/m1a2st/beans/factory/ObjectFactory.java diff --git a/src/main/java/org/m1a2st/aop/autoproxy/DefaultAdvisorAutoProxyCreator.java b/src/main/java/org/m1a2st/aop/autoproxy/DefaultAdvisorAutoProxyCreator.java index 0d113f0..1508916 100644 --- a/src/main/java/org/m1a2st/aop/autoproxy/DefaultAdvisorAutoProxyCreator.java +++ b/src/main/java/org/m1a2st/aop/autoproxy/DefaultAdvisorAutoProxyCreator.java @@ -13,6 +13,8 @@ import org.m1a2st.beans.factory.support.DefaultListableBeanFactory; import java.util.Collection; +import java.util.HashSet; +import java.util.Set; /** * @Author m1a2st @@ -23,6 +25,8 @@ public class DefaultAdvisorAutoProxyCreator implements InstantiationAwareBeanPos private DefaultListableBeanFactory beanFactory; + private final Set earlyProxyReferences = new HashSet<>(); + @Override public void setBeanFactory(BeanFactory beanFactory) throws BeansException { this.beanFactory = (DefaultListableBeanFactory) beanFactory; @@ -38,8 +42,21 @@ public boolean postProcessAfterInstantiation(Object bean, String beanName) throw return true; } + @Override + public Object getEarlyBeanReference(Object bean, String beanName) throws BeansException { + earlyProxyReferences.add(beanName); + return wrapIfNecessary(bean, beanName); + } + @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { + if (!earlyProxyReferences.contains(beanName)) { + return wrapIfNecessary(bean, beanName); + } + return bean; + } + + protected Object wrapIfNecessary(Object bean, String beanName) { // 避免死循環 if (isInfrastructureClass(bean.getClass())) { return null; diff --git a/src/main/java/org/m1a2st/beans/factory/ObjectFactory.java b/src/main/java/org/m1a2st/beans/factory/ObjectFactory.java new file mode 100644 index 0000000..3795439 --- /dev/null +++ b/src/main/java/org/m1a2st/beans/factory/ObjectFactory.java @@ -0,0 +1,13 @@ +package org.m1a2st.beans.factory; + +import org.m1a2st.beans.BeansException; + +/** + * @Author m1a2st + * @Date 2023/7/26 + * @Version v1.0 + */ +public interface ObjectFactory { + + T getObject() throws BeansException; +} diff --git a/src/main/java/org/m1a2st/beans/factory/config/InstantiationAwareBeanPostProcessor.java b/src/main/java/org/m1a2st/beans/factory/config/InstantiationAwareBeanPostProcessor.java index 86cc302..dcfab24 100644 --- a/src/main/java/org/m1a2st/beans/factory/config/InstantiationAwareBeanPostProcessor.java +++ b/src/main/java/org/m1a2st/beans/factory/config/InstantiationAwareBeanPostProcessor.java @@ -40,4 +40,16 @@ public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor { * @throws BeansException bean處理異常 */ PropertyValues postProcessPropertyValues(PropertyValues pvs, Object bean, String beanName) throws BeansException; + + /** + * 提前曝露 bean + * + * @param bean bean實例 + * @param beanName bean的名稱 + * @return bean實例 + * @throws BeansException bean處理異常 + */ + default Object getEarlyBeanReference(Object bean, String beanName) throws BeansException { + return bean; + } } diff --git a/src/main/java/org/m1a2st/beans/factory/support/AbstractAutowireCapableBeanFactory.java b/src/main/java/org/m1a2st/beans/factory/support/AbstractAutowireCapableBeanFactory.java index 85ce9d0..05ac359 100644 --- a/src/main/java/org/m1a2st/beans/factory/support/AbstractAutowireCapableBeanFactory.java +++ b/src/main/java/org/m1a2st/beans/factory/support/AbstractAutowireCapableBeanFactory.java @@ -75,7 +75,10 @@ protected Object doCreateBean(String beanName, BeanDefinition beanDefinition) th // 創造Bean 實體 bean = createBeanInstance(beanDefinition); // 為解決循環依賴,將實例化的Bean放入緩存提前暴露 - earlySingletonObjects.put(beanName, bean); + if (beanDefinition.isSingleton()) { + Object finalBean = bean; + addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, beanDefinition, finalBean)); + } // bean 實例化後進行 if (!applyBeanPostProcessorsAfterInstantiation(beanName, bean)) { return bean; @@ -91,10 +94,27 @@ protected Object doCreateBean(String beanName, BeanDefinition beanDefinition) th } // 註冊有銷毀方法的Bean registerDisposableBeanIfNecessary(beanName, bean, beanDefinition); + + Object exposeObject = bean; if (beanDefinition.isSingleton()) { - addSingleton(beanName, bean); + // 如果有代理對象,此處獲取代理對象 + exposeObject = getSingleton(beanName); + addSingleton(beanName, exposeObject); } - return bean; + return exposeObject; + } + + protected Object getEarlyBeanReference(String beanName, BeanDefinition beanDefinition, Object bean) { + Object exposedObject = bean; + for (BeanPostProcessor bp : getBeanPostProcessors()) { + if (bp instanceof InstantiationAwareBeanPostProcessor) { + exposedObject = ((InstantiationAwareBeanPostProcessor) bp).getEarlyBeanReference(exposedObject, beanName); + if (exposedObject == null) { + return null; + } + } + } + return exposedObject; } /** diff --git a/src/main/java/org/m1a2st/beans/factory/support/DefaultSingletonBeanRegistry.java b/src/main/java/org/m1a2st/beans/factory/support/DefaultSingletonBeanRegistry.java index ad2227e..7e7aa03 100644 --- a/src/main/java/org/m1a2st/beans/factory/support/DefaultSingletonBeanRegistry.java +++ b/src/main/java/org/m1a2st/beans/factory/support/DefaultSingletonBeanRegistry.java @@ -2,6 +2,7 @@ import org.m1a2st.beans.BeansException; import org.m1a2st.beans.factory.DisposableBean; +import org.m1a2st.beans.factory.ObjectFactory; import org.m1a2st.beans.factory.config.SingletonBeanRegistry; import java.util.ArrayList; @@ -20,22 +21,44 @@ */ public class DefaultSingletonBeanRegistry implements SingletonBeanRegistry { + // 二級緩存 + protected final Map earlySingletonObjects = new ConcurrentHashMap<>(); + // 一級緩存 private final Map singletonObjects = new ConcurrentHashMap<>(); + // 三級緩存 + private final Map> singletonFactories = new ConcurrentHashMap<>(); + private final Map disposableBeans = new ConcurrentHashMap<>(); - protected final Map earlySingletonObjects = new ConcurrentHashMap<>(); @Override public Object getSingleton(String beanName) { - Object bean = singletonObjects.get(beanName); - if (bean == null) { - bean = earlySingletonObjects.get(beanName); + Object singletonObject = singletonObjects.get(beanName); + if (singletonObject == null) { + singletonObject = earlySingletonObjects.get(beanName); + if (singletonObject == null) { + ObjectFactory singletonFactory = singletonFactories.get(beanName); + if (singletonFactory != null) { + // 這裡的singletonObject是一個ObjectFactory,而不是bean實例 + singletonObject = singletonFactory.getObject(); + // 從三級緩存放進二級緩存 + earlySingletonObjects.put(beanName, singletonObject); + // 從三級緩存移除 + singletonFactories.remove(beanName); + } + } } - return bean; + return singletonObject; + } + + protected void addSingletonFactory(String beanName, ObjectFactory singletonFactory) { + singletonFactories.put(beanName, singletonFactory); } @Override public void addSingleton(String beanName, Object singletonObject) { singletonObjects.put(beanName, singletonObject); + earlySingletonObjects.remove(beanName); + singletonFactories.remove(beanName); } public void registerDisposableBean(String beanName, DisposableBean bean) {