上篇文章說了,bean工廠後置處理器如何加載配置類
public static void loadBeanDefinitions() {
RootBeanDefinition rootBeanDefinitionA = new RootBeanDefinition(InstanceA.class);
RootBeanDefinition rootBeanDefinitionB = new RootBeanDefinition(InstanceB.class);
beanDefinitionMap.put("instanceA", rootBeanDefinitionA);
beanDefinitionMap.put("instanceB", rootBeanDefinitionB);
}
@Component
public class InstanceA {
@Autowired
private InstanceB instanceB;
public InstanceB getInstanceB() {
return instanceB;
}
public void setInstanceB(InstanceB instanceB) {
this.instanceB = instanceB;
}
public InstanceA(InstanceB instanceB) {
this.instanceB = instanceB;
}
public InstanceA() {
System.out.println("執行個體化A");
}
}
首先把bean放入beanDefinition,之後,循環bean定義,通過bean的key來擷取beanDefinition,
通過無參構造函數反射來擷取class,再指派屬性。
public static void main(String[] args) throws Exception {
// 加載到beanDefinition
loadBeanDefinitions();
for (String key : beanDefinitionMap.keySet()) {
// 先建立A
getBean(key);
}
InstanceA instanceA = (InstanceA)getBean("instanceA");
System.out.println(instanceA);
}
private static Map<String, Object> singletonObjects = new ConcurrentHashMap<>();
public static Object getBean(String beanName) throws Exception {
Object singleton = getSingleton(beanName);
if(singleton != null){
return singleton;
}
// 執行個體化
RootBeanDefinition rootBeanDefinition = (RootBeanDefinition) beanDefinitionMap.get(beanName);
Class<?> beanClass = rootBeanDefinition.getBeanClass();
// 通過class 無參構造函數 執行個體化
Object instanceBean = beanClass.newInstance();
singletonObjects.put(beanName, instanceBean);
// 屬性指派
Field[] declaredFields = beanClass.getDeclaredFields();
for (Field declaredField : declaredFields) {
Autowired annotation = declaredField.getAnnotation(Autowired.class);
// 說明bean有autowired
if (annotation != null) {
// 打開通路權限
declaredField.setAccessible(true);
// byName byType 拿到了 instanceB名字
String name = declaredField.getName();
// 拿到B的bean
Object fileObject = getBean(name);
declaredField.set(instanceBean, fileObject);
}
}
// 初始化
// 放入緩存
// singletonObjects.put(beanName, instanceBean);
return instanceBean;
}
private static Object getSingleton(String beanName) {
Object singleton = singletonObjects.get(beanName);
if (singleton != null) {
return singleton;
}
return null;
}
這樣寫完之後,就不會有死循環,但是沒有用到二級緩存,二級緩存可以用來放半成品的bean,解決多線程的情況下,多個線程同時建立bean,防止其他線程拿到不完整的bean,于是 加上二級緩存來寫。
private static Map<String, Object> singletonObjects = new ConcurrentHashMap<>();
private static Map<String, Object> earlySingletonObjects = new ConcurrentHashMap<>();
public static Object getBean(String beanName) throws Exception {
Object singleton = getSingleton(beanName);
if (singleton != null) {
return singleton;
}
// 執行個體化
RootBeanDefinition rootBeanDefinition = (RootBeanDefinition) beanDefinitionMap.get(beanName);
Class<?> beanClass = rootBeanDefinition.getBeanClass();
// 通過class 無參構造函數 執行個體化
Object instanceBean = beanClass.newInstance();
// 二級緩存
earlySingletonObjects.put(beanName, instanceBean);
// 屬性指派
Field[] declaredFields = beanClass.getDeclaredFields();
for (Field declaredField : declaredFields) {
Autowired annotation = declaredField.getAnnotation(Autowired.class);
// 說明bean有autowired
if (annotation != null) {
// 打開通路權限
declaredField.setAccessible(true);
// byName byType 拿到了 instanceB名字
String name = declaredField.getName();
// 拿到B的bean
Object fileObject = getBean(name);
declaredField.set(instanceBean, fileObject);
}
}
// 初始化
// 放入緩存
singletonObjects.put(beanName, instanceBean);
return instanceBean;
}
private static Object getSingleton(String beanName) {
Object singleton = singletonObjects.get(beanName);
if (singleton != null) {
return singleton;
}
Object earlySingleton = earlySingletonObjects.get(beanName);
if (earlySingleton != null) {
return earlySingleton;
}
return null;
}
用解耦的方式,beanPostProcessor來建立動态代理。
如果在最後調用動态代理,這時候循環依賴的bean就不是動态代理的bean,是以要在之前就建立動态代理。是以這裡有兩個地方調用動态代理,執行個體化之後和初始化之後調用。
隻在循環依賴的情況下在執行個體化之後建立動态代理,是以需要判斷目前是不是循環依賴。
private static Map<String, Object> singletonObjects = new ConcurrentHashMap<>();
private static Map<String, Object> earlySingletonObjects = new ConcurrentHashMap<>();
// 存放函數接口
private static Map<String, ObjectFactory> singletonFactories = new ConcurrentHashMap<>();
private static Set<String> singletonCurrennlyInCreation = new HashSet<>();
public static Object getBean(String beanName) throws Exception {
Object singleton = getSingleton(beanName);
if (singleton != null) {
return singleton;
}
// 正在建立
if (!singletonCurrennlyInCreation.contains(beanName)) {
singletonCurrennlyInCreation.add(beanName);
}
// 執行個體化
RootBeanDefinition rootBeanDefinition = (RootBeanDefinition) beanDefinitionMap.get(beanName);
Class<?> beanClass = rootBeanDefinition.getBeanClass();
// 通過class 無參構造函數 執行個體化
Object instanceBean = beanClass.newInstance();
// 建立動态代理
// 隻在循環依賴的情況下在執行個體化之後建立動态代理
//Object o = new JDKProxyBeanPostProcessor().getEarlyBeanReference(instanceBean,beanName);
/*singletonFactories.put(beanName, new ObjectFactory() {
@Override
public Object getObject() throws BeansException {
return new JDKProxyBeanPostProcessor().getEarlyBeanReference(instanceBean,beanName);
}
});*/
singletonFactories.put(beanName, () -> new JDKProxyBeanPostProcessor().getEarlyBeanReference(instanceBean, beanName));
// 二級緩存
//earlySingletonObjects.put(beanName, instanceBean);
// 屬性指派
Field[] declaredFields = beanClass.getDeclaredFields();
for (Field declaredField : declaredFields) {
Autowired annotation = declaredField.getAnnotation(Autowired.class);
// 說明bean有autowired
if (annotation != null) {
// 打開通路權限
declaredField.setAccessible(true);
// byName byType 拿到了 instanceB名字
String name = declaredField.getName();
// 拿到B的bean
Object fileObject = getBean(name);
declaredField.set(instanceBean, fileObject);
}
}
// 初始化
/*if(earlySingletonObjects.containsKey(beanName)){
instanceBean = earlySingletonObjects.get(beanName);
}*/
// 放入緩存
singletonObjects.put(beanName, instanceBean);
return instanceBean;
}
private static Object getSingleton(String beanName) {
/* Object singleton = singletonObjects.get(beanName);
if (singleton != null) {
return singleton;
}
Object earlySingleton = earlySingletonObjects.get(beanName);
if (earlySingleton != null) {
return earlySingleton;
}
return null;*/
Object bean = singletonObjects.get(beanName);
if (bean == null && singletonCurrennlyInCreation.contains(beanName)) {
// 是循環依賴
bean = earlySingletonObjects.get(beanName);
synchronized (singletonObjects){
if(bean == null){
ObjectFactory objectFactory = singletonFactories.get(beanName);
if (objectFactory != null) {
// 鈎子函數 去建立 aop代理
bean = objectFactory.getObject();
earlySingletonObjects.put(beanName, bean);
singletonFactories.remove(beanName);
}
return bean;
}
}
}
return bean;
}