概述
看了好久spring源码,有些地方理解的不深刻,决定手写一下BeanFactory
来加深理解
规范
spring中最主要的bean工厂实现就是DefaultListableBeanFactory
,看一下它实现的接口
public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory
implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable
主要实现两个接口ConfigurableListableBeanFactory
和BeanDefinitionRegistry
,下面分别整理下这两个接口要实现的方法
BeanDefinitionRegistry
这个简单,从字面理解就是一个bean定义的注册器,那自然可以填加,也可以获取bean定义
重点方法:
-
void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
这就是注册bean定义 -
BeanDefinition getBeanDefinition(String beanName)
获取bean定义
总结就是,作为一个bean定义注册器,需要实现可以注册,完事也可以获取,一句话概括就是一个bean定义存储的容器
ConfigurableListableBeanFactory
这个相对复杂,字面理解是一个可配置可列出的bean工厂
重点方法(包含了父接口):
-
Object getBean(String name)
获取bean,最主要的方法,bean工厂吗,当然主要的任务就是能获取bean(当然没有则创建) -
void preInstantiateSingletons()
预初始化所有单例bean(当然是根据注册的bean定义来初始化)
SingletonBeanRegistry
这个倒不是bean工厂的接口,而是DefaultListableBeanFactory
的子类DefaultSingletonBeanRegistry
实现的接口
看名字就知道这是一个存储单例bean的容器,著名的三级缓存就在这里
-
void registerSingleton(String beanName, Object singletonObject)
注册单例对象 -
Object getSingleton(String beanName)
获取单例对象
也就是他是一个对象存储的容器,就像一个hashmap
总结
也就是说DefaultListableBeanFactory
是一个bean工厂,可以获取bean,可以提前初始化所有bean,同时它也是一个bean定义的容器。
而他的bean实际存储就是交给他的子类DefaultSingletonBeanRegistry
处理的
实现
之所以研究DefaultSingletonBeanRegistry
的骨架,是为了模仿,因为手写模仿最好得跟它保持相同的规范和设计思路,要不回头看源码还是看不懂
所以我的实现思路也是首先要实现两个接口,然后按照他的bean存储方式,也写个singletonBeanRegistry
用来继承
注:以下所有代码由于继承了spring的接口,所有要有很多实现方法,只贴了重点实现的方法,其它方法全默认
一.简单的bean工厂
先考虑最简单的实现方式,两个容器两个hashMap完全可以实现,那就试一下
原来的spring的bean定义有点复杂,不在本届的讨论范围,所以自己实现了个简单的bean定义(只存储类的信息)
public class MyBeanDefinition implements BeanDefinition {
// 存储class
private Class> beanClass;
// 简单的bean定义,只存储class信息
public MyBeanDefinition(Class> beanClass) {
this.beanClass = beanClass;
}
public Class> getBeanClass() {
return beanClass;
}
一个简单的bean定义实现了,下面实现bean工厂,首先实现一个bean的容器
public class MySingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry {
/** bean容器,一级缓存 **/
private final Map singletonObjects = new ConcurrentHashMap<>(256);
/** 添加bean **/
@Override
public void registerSingleton(String beanName, Object singletonObject) throws IllegalStateException {
this.singletonObjects.put(beanName, singletonObject);
}
/** 获取bean **/
@Override
public Object getSingleton(String beanName) {
return this.singletonObjects.get(beanName);
}
其实就是一个HashMap包装成一个类
实现BeanFactory
public class MyBeanFactory extends MySingletonBeanRegistry implements ConfigurableListableBeanFactory, BeanDefinitionRegistry {
/** bean定义容器 **/
private final Map beanDefinitionMap = new ConcurrentHashMap<>(256);
/**
* 注册bean定义
*/
@Override
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) throws BeanDefinitionStoreException {
beanDefinitionMap.put(beanName, beanDefinition);
}
/**
* 获取bean定义
*/
@Override
public BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException {
return this.beanDefinitionMap.get(beanName);
}
/**
* 提前初始化所有bean
* @throws BeansException
*/
@Override
public void preInstantiateSingletons() throws BeansException {
// 循环所有bean定义
for (Map.Entry entry : beanDefinitionMap.entrySet()) {
// 生产bean
getBean(entry.getKey());
}
}
/**
* 获取bean
*/
@Override
public Object getBean(String name) throws BeansException {
try {
// 先去容器里拿
Object singleton = getSingleton(name);
// 如果没有就创建
if (singleton==null) {
// 获取bean定义
MyBeanDefinition beanDefinition = (MyBeanDefinition) getBeanDefinition(name);
// 实例化bean
singleton = beanDefinition.getBeanClass().newInstance();
// 注册到容器
registerSingleton(name, singleton);
}
return singleton;
} catch (InstantiationException e) {
return null;
} catch (IllegalAccessException e) {
return null;
}
}
就这么简单实现了,bean定义容器也是一个map,getBean就拿到class放射成实例就行了,测试一下
新建两个测试对象
public class BeanA {
public String aName = "A";
}
public class BeanB {
public String bName = "B";
}
测试:
System.out.println("===factory1===");
MyBeanFactory1 myBeanFactory1 = new MyBeanFactory1();
myBeanFactory1.registerBeanDefinition("BeanA", new MyBeanDefinition(BeanA.class));
myBeanFactory1.preInstantiateSingletons();
Object a1 = myBeanFactory1.getBean("BeanA");
System.out.println(a1);
输出
===factory===
{"A":{"aName":"A"}}
完全没问题
依赖注入
很显然,一中的实现最简单,但如果需要依赖注入,它就做不到了,那么如何实现依赖注入?
spring依赖注入需要一个注解@Autowired
,我们也写一个注解MyAutowired
@Target({ElementType.CONSTRUCTOR, ElementType.METHOD, ElementType.PARAMETER, ElementType.FIELD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface MyAutowired {
}
这时,两个对象修改这样
public class BeanA {
public String aName = "A";
// 想通过依赖注入进beanB
@MyAutowired
public BeanB beanB;
@Override
@AopToString
public String toString() {
return "{\"A\":{"
+ "\"aName\":\""
+ aName + '\"'
+ ",\"b\":"
+ (null==beanB?"null":beanB.bName)
+ "}}";
}
}
public class BeanB {
public String bName = "B";
@Override
@AopToString
public String toString() {
return "{\"B\":{"
+ "\"bName\":\""
+ bName + "}}";
}
}
实现起来也不难,思路如下:
实例化对象后,循环所有属性,发现@MyAutowired,调用getBean("属性名")获取另一个bean,再给属性赋值,只需修改getBean
方法即可
/**
* 获取bean
*/
@Override
public Object getBean(String name) throws BeansException {
try {
// 先去容器里拿
Object singleton = getSingleton(name);
// 如果没有就创建
if (singleton==null) {
// 获取bean定义
MyBeanDefinition beanDefinition = (MyBeanDefinition) getBeanDefinition(name);
// 实例化bean
singleton = beanDefinition.getBeanClass().newInstance();
// 填充属性(新增)
popular(singleton, beanDefinition.getBeanClass());
// 注册到容器
registerSingleton(name, singleton);
}
return singleton;
} catch (InstantiationException e) {
return null;
} catch (IllegalAccessException e) {
return null;
}
}
实例化完,新增了个填充属性popular
方法
实现如下
private void popular(Object singleton, Class> clazz) {
// 循环属性
for (Field declaredField : clazz.getDeclaredFields()) {
// 看看是否有MyAutowired注解
MyAutowired annotation = declaredField.getAnnotation(MyAutowired.class);
if (annotation!=null) {
declaredField.setAccessible(true);
try {
// 属性赋值
declaredField.set(singleton, getBean(declaredField.getType().getSimpleName()));
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
}
流程是这样的
1.实例化A
2.循环A属性
3.发现需要B
4.实例化B
5.将实例化的B赋值给A对象的属性
总之就是A要等B创建完,A才能创建完
测试一下原测试方法,输出
===factory===
{"A":{"aName":"A","b":B}}
可以看到实现了,依赖注入
循环依赖
上文解决了依赖注入,但没有办法解决循环依赖,比如
public class BeanA {
public String aName = "A";
// 想通过依赖注入进beanB
@MyAutowired
public BeanB beanB;
@Override
@AopToString
public String toString() {
return "{\"A\":{"
+ "\"aName\":\""
+ aName + '\"'
+ ",\"b\":"
+ (null==beanB?"null":beanB.bName)
+ "}}";
}
}
public class BeanB {
public String bName = "B";
@MyAutowired
public BeanA beanA;
@Override
public String toString() {
return "{\"BeanB\":{"
+ "\"bName\":\""
+ bName + '\"'
+ ",\"beanA\":"
+ (null==beanA?"null":beanA.aName)
+ "}}";
}
}
这时候A不光需要B,B也需要A,如果还按照上面的方法那么A要等B创建完,B又要等A创建完,那就永远不会创建出来了,死循环,最终StackOverflowError
- 解决思路1
方案:preInstantiateSingletons
方法先实例化所有bean并存入一级缓存,然后所有bean再循环填充属性,而getBean
只是从bean容器获取,没有创建功能
问题:这样做完全可以解决循环依赖,我当时想到的解法就是这样,但是spring没这么做,原因其实也很简单,这样做只适合同时初始化所有bean,但preInstantiateSingletons
方法只是实例化非懒汉模式的单例bean,但因为懒加载的存在,要求getBean方法必须获取完整的bean对象,这种解法就完全行不通 - 解决思路2
方案:实例化后马上存入一级缓存,然后再去填充属性,这样先A后B的话,先实例化A,存入一级缓存,A填充属性,实例化B,B存入一级缓存,B填充属性,需要A而且一级缓存有,直接获取填充B,回到A的getBean再给A的b属性赋值
问题:这种方案也可以解决循环依赖,但是会出现一个问题,bean在实例化时就已经放入一级缓存,这时候的bean是一个不完整的bean,如果被获取到很容易出问题 - 解决思路3
方案:在2的基础上做优化,再添加一层缓存,名曰“二级缓存”(存放不完整的bean),实例化的bean先放入二级缓存并标志正在创建,获取单例对象时,如果正在创建则从二级缓存取bean做属性填充,最后完整的bean存入一级缓存
问题:无,这就是spring的解决思路
解决方案已出,下面写代码,首先bean容器MySingletonBeanRegistry
需要加入二级缓存,并加入是否正在创建标识功能
public class MySingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry {
/** bean容器,一级缓存 **/
private final Map singletonObjects = new ConcurrentHashMap<>(256);
/** bean容器,二级缓存 **/
private final Map earlySingletonObjects = new HashMap<>(16);
/** 存储正在创建的bean **/
private final Set singletonsCurrentlyInCreation =
Collections.newSetFromMap(new ConcurrentHashMap<>(16));
/**
* 查看bean是否正在创建
*/
public boolean isSingletonCurrentlyInCreation(String beanName) {
return this.singletonsCurrentlyInCreation.contains(beanName);
}
/**
* 标志bean正在创建
*/
protected void beforeSingletonCreation(String beanName) {
this.singletonsCurrentlyInCreation.add(beanName);
}
/**
* 标志bean创建完成
*/
protected void afterSingletonCreation(String beanName) {
this.singletonsCurrentlyInCreation.remove(beanName);
}
/**
* 添加bean二级缓存
*/
protected void addEarly(String beanName, Object singletonObject) {
this.earlySingletonObjects.put(beanName, singletonObject);
}
/** 添加bean **/
@Override
public void registerSingleton(String beanName, Object singletonObject) throws IllegalStateException {
this.singletonObjects.put(beanName, singletonObject);
}
/** 获取bean **/
@Override
public Object getSingleton(String beanName) {
// 一级缓存拿
Object singletonObject = this.singletonObjects.get(beanName);
// 如果拿不到并且正在创建,去二级缓存拿
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
singletonObject = this.earlySingletonObjects.get(beanName);
}
return singletonObject;
}
而BeanFactory需要做的修改,就是getBean 标记(改)
/**
* 获取bean
*/
@Override
public Object getBean(String name) throws BeansException {
try {
// 先去容器里拿
Object singleton = getSingleton(name);
// 如果没有就创建
if (singleton==null) {
// 标记正在创建(改)
beforeSingletonCreation(name);
// 获取bean定义
MyBeanDefinition beanDefinition = (MyBeanDefinition) getBeanDefinition(name);
// 实例化bean
singleton = beanDefinition.getBeanClass().newInstance();
// 提前暴露加到二级缓存(改)
addEarly(name, singleton);
// 填充属性
popular(singleton, beanDefinition.getBeanClass());
// 注册到容器
registerSingleton(name, singleton);
// 标记创建完成(改)
afterSingletonCreation(name);
}
return singleton;
} catch (InstantiationException e) {
return null;
} catch (IllegalAccessException e) {
return null;
}
}
测试一下
System.out.println("===factory===");
MyBeanFactory myBeanFactory = new MyBeanFactory();
myBeanFactory.registerBeanDefinition("BeanA", new MyBeanDefinition(BeanA.class));
myBeanFactory.registerBeanDefinition("BeanB", new MyBeanDefinition(BeanB.class));
myBeanFactory.preInstantiateSingletons();
Object a = myBeanFactory.getBean("BeanA");
Object b = myBeanFactory.getBean("BeanB");
System.out.println(a);
System.out.println(b);
输出
{"A":{"aName":"A","b":B}}
{"B":{"bName":"B","a":A}}
彻底解决了循环依赖
网上人都说二级缓存是为了解决循环依赖,实际上二级缓存是为了解决循环依赖造成的bean不完整问题
代理
解决了循环依赖问题,看下一个问题:动态代理
spring除了IOC,最津津乐道的功能就是AOP,所以再spring的设计中肯定需要考虑AOP
那我们模拟下AOP,先加一个注解
@Target({ElementType.CONSTRUCTOR, ElementType.METHOD, ElementType.PARAMETER, ElementType.FIELD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface AopToString {
}
然后修改两个bean, 再toString方法上都加上该注解
@AopToString
public String toString() {
然后beanFactory发现方法有@AopToString
注解就是用cglib方法生成一个动态代理(再toSring之前输出"TO String AOP"),最终存入bean容器的是这个动态代理对象而不是通过反射创建出的对象,一个AOP就实现了
但问题出现了,什么时候创建代理?
答:考虑到循环依赖,那么肯定是在添加二级缓存前,因为代理对象和实例化出来的对象是两个对象,假如A存在代理,B的依赖注入是A的原对象,那不是打错特错了吗。所以一定是添加二级缓存前前创建代理,代码实现一下,beanFactory修改
/**
* 获取bean
*/
@Override
public Object getBean(String name) throws BeansException {
try {
// 先去容器里拿
Object singleton = getSingleton(name);
// 如果没有就创建
if (singleton==null) {
// 标记正在创建
beforeSingletonCreation(name);
// 获取bean定义
MyBeanDefinition beanDefinition = (MyBeanDefinition) getBeanDefinition(name);
// 实例化bean
singleton = beanDefinition.getBeanClass().newInstance();
//创建代理(新增)
singleton = createBeanProxy(singleton, beanDefinition.getBeanClass());
// 提前暴露加到二级缓存
addEarly(name, singleton);
// 填充属性
popular(singleton, beanDefinition.getBeanClass());
// 注册到容器
registerSingleton(name, singleton);
// 标记创建完成
afterSingletonCreation(name);
}
return singleton;
} catch (InstantiationException e) {
return null;
} catch (IllegalAccessException e) {
return null;
}
}
private Object createBeanProxy(Object singleton, Class> clazz) {
Method[] Methods = clazz.getMethods();
// 循环所有方法
for (Method field : Methods) {
// 如果存在AopToString注解(简化处理只代理一个)
if (field.isAnnotationPresent(AopToString.class)) {
// 使用cglib创建代理
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(clazz);
enhancer.setCallback((MethodInterceptor) (o, method, objects, methodProxy) -> {
if (method.equals(field)) {
// 代理对象toSpring前输出
System.out.print("TO String AOP ");
}
return methodProxy.invokeSuper(o, objects);
});
return enhancer.create();
}
}
return singleton;
}
测试一下原测试方法
TO String AOP {"A":{"aName":"A","b":B}}
{"B":{"bName":"B","a":A}}
再循环依赖的前提下实现了动态代理
三级缓存
网上都说三级缓存为了解决动态代理,但其实到现在为止,只有二级缓存,动态代理也解决了
那要三级缓存干嘛呐,没有看见过官方的解释,但是根据读源码猜测又这几个考虑
- spring的设计思路,动态代理创建应该是最后一步,应该在所有事情(实例化,填充属性,初始化)之后执行
- spring其实并不太希望出现循环依赖(新版的已经默认禁止循环依赖)
- 为了不提倡的循环依赖而把动态代理的创建时机提前,不值得
最终的实现方案:一般情况最后一步创建代理,如果出现循环依赖,提前创建代理
这个其实挺难实现的,因为在某个getBean
执行时候是没有办法确定是否存在循环依赖的,而且要在填充属性前确定,这更难了。
spring的解决方案:
再加个三级缓存
- 如果出现循环依赖
getBean(A)时,取消原来创建代理后存储二级缓存的步骤,修改为存创建代理的方法
至三级缓存,如果出现循环依赖getBean(B)的时候又反过来调用getBean(A),会去bean容器查找,此时二级缓存没有,取三级缓存的方法并执行生成带有代理的对象,存入二级缓存并注入到B。可以正常解决循环依赖并提前创建 - 如果没有出现循环依赖
getBean(A)时,虽然也存入了三级缓存一个创建代理的方法
,但是没有循环依赖所以没有再去bean容器查找,所以三级缓存相当于白存了,正常填充属性,再最后创建代理并返回即可
代码修改下
先定义一个创建代理的方法
的接口
@FunctionalInterface
public interface ObjectFactory {
T getObject() throws BeansException;
}
bean容器中加入三级缓存,完整代买如下(省略未实现方法)
public class MySingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry {
/** bean容器,完整的bean,一级缓存 **/
private final Map singletonObjects = new ConcurrentHashMap<>(256);
/** bean容器,不完整的bean,二级缓存 **/
private final Map earlySingletonObjects = new HashMap<>(16);
/** bean创建方法容器,存储不完整bean的创建方法,三级缓存 **/
private final Map> singletonFactories = new HashMap<>(16);
/** 存储正在创建的bean **/
private final Set singletonsCurrentlyInCreation =
Collections.newSetFromMap(new ConcurrentHashMap<>(16));
/**
* 查看bean是否正在创建
*/
public boolean isSingletonCurrentlyInCreation(String beanName) {
return this.singletonsCurrentlyInCreation.contains(beanName);
}
/**
* 标志bean正在创建
*/
protected void beforeSingletonCreation(String beanName) {
this.singletonsCurrentlyInCreation.add(beanName);
}
/**
* 标志bean创建完成
*/
protected void afterSingletonCreation(String beanName) {
this.singletonsCurrentlyInCreation.remove(beanName);
}
/**
* 添加创建提前暴露bean的方法
*/
protected void addSingletonFactory(String beanName, ObjectFactory> objectFactory) {
this.singletonFactories.put(beanName, objectFactory);
}
/** 添加bean **/
@Override
public void registerSingleton(String beanName, Object singletonObject) throws IllegalStateException {
this.singletonObjects.put(beanName, singletonObject);
}
/** 获取bean **/
@Override
public Object getSingleton(String beanName) {
return getSingleton(beanName, true);
}
public Object getSingleton(String beanName, Boolean allowEarlyReference) {
// 一级缓存拿
Object singletonObject = this.singletonObjects.get(beanName);
// 如果拿不到并且正在创建,去二级缓存拿
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
singletonObject = this.earlySingletonObjects.get(beanName);
// 二级缓存娶不到,三级缓存创建再存入二级缓存
if (singletonObject == null && allowEarlyReference) {
ObjectFactory> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
// 创建早器bean,包含代理的创建
singletonObject = singletonFactory.getObject();
// 这个还是不完整的bean存入二级缓存
this.earlySingletonObjects.put(beanName, singletonObject);
}
}
}
return singletonObject;
}
public class MyBeanFactory extends MySingletonBeanRegistry implements ConfigurableListableBeanFactory, BeanDefinitionRegistry {
/** bean定义容器 **/
private final Map beanDefinitionMap = new ConcurrentHashMap<>(256);
/**
* 注册bean定义
*/
@Override
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) throws BeanDefinitionStoreException {
beanDefinitionMap.put(beanName, beanDefinition);
}
/**
* 获取bean定义
*/
@Override
public BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException {
return this.beanDefinitionMap.get(beanName);
}
/**
* 提前初始化所有bean
* @throws BeansException
*/
@Override
public void preInstantiateSingletons() throws BeansException {
// 循环所有bean定义
for (Map.Entry entry : beanDefinitionMap.entrySet()) {
// 生产bean
getBean(entry.getKey());
}
}
/**
* 获取bean
*/
@Override
public Object getBean(String name) throws BeansException {
try {
// 先去容器里拿
Object singleton = getSingleton(name);
// 如果没有就创建
if (singleton==null) {
// 标记正在创建
beforeSingletonCreation(name);
// 获取bean定义
MyBeanDefinition beanDefinition = (MyBeanDefinition) getBeanDefinition(name);
// 获取class
Class> beanClass = beanDefinition.getBeanClass();
// 实例化bean
singleton = beanClass.newInstance();
// 添加创建提前暴露bean的方法,包括代理
Object finalSingleton = singleton;
addSingletonFactory(name, ()-> createBeanProxy(finalSingleton, beanClass));
// 填充属性
popular(singleton, beanClass);
// 看看有没有提前暴露
Object singletonEarly = getSingleton(name, false);
if (singletonEarly!=null) {
singleton = singletonEarly;
} else {
// 创建代理
System.out.println(name + " create proxy at last");
singleton = createBeanProxy(finalSingleton, beanClass);
}
// 注册到容器
registerSingleton(name, singleton);
// 标记创建完成
afterSingletonCreation(name);
}
return singleton;
} catch (InstantiationException e) {
return null;
} catch (IllegalAccessException e) {
return null;
}
}
/**
* 填充属性
* @param singleton
* @param clazz
*/
private void popular(Object singleton, Class> clazz) {
// 循环属性
for (Field declaredField : clazz.getDeclaredFields()) {
// 看看是否有MyAutowired注解
MyAutowired annotation = declaredField.getAnnotation(MyAutowired.class);
if (annotation!=null) {
declaredField.setAccessible(true);
try {
// 属性赋值
declaredField.set(singleton, getBean(declaredField.getType().getSimpleName()));
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
}
/**
* 模仿cglib创建代理,这里做了特殊处理,这种代理方式
* 实际上是给proxy对象增加一个target指向原对象,所以调用代理A的getB方法实际
* 上是调用A.target.getB方法。这样就解决了代理实际上没有注入属性的问题
* @param singleton
* @param clazz
* @return
*/
private Object createBeanProxy(Object singleton, Class> clazz) {
Method[] Methods = clazz.getMethods();
for (Method mth : Methods) {
// 简化处理只代理一个
if (mth.isAnnotationPresent(AopToString.class)) {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(clazz);
enhancer.setCallback((MethodInterceptor) (o, method, objects, methodProxy) -> {
if (method.equals(mth)) {
System.out.print("TO String AOP ");
}
return method.invoke(singleton, objects);
});
return enhancer.create();
}
}
return singleton;
}
再加个没有循环依赖的BeanC
public class BeanC {
public String cName = "C";
@Override
@AopToString
public String toString() {
return "{\"C\":{"
+ "\"cName\":\""
+ cName + '\"'
+ "}}";
}
}
测试
public class CircularApplication {
public static void main(String[] args) {
System.out.println("===factory===");
MyBeanFactory myBeanFactory = new MyBeanFactory();
myBeanFactory.registerBeanDefinition("BeanA", new MyBeanDefinition(BeanA.class));
myBeanFactory.registerBeanDefinition("BeanB", new MyBeanDefinition(BeanB.class));
myBeanFactory.registerBeanDefinition("BeanC", new MyBeanDefinition(BeanC.class));
myBeanFactory.preInstantiateSingletons();
Object a = myBeanFactory.getBean("BeanA");
Object b = myBeanFactory.getBean("BeanB");
Object c = myBeanFactory.getBean("BeanC");
System.out.println(a);
System.out.println(b);
System.out.println(c);
}
}
输出:
===factory===
BeanB create proxy at last
BeanC create proxy at last
TO String AOP {"A":{"aName":"A","b":B}}
{"BeanB":{"bName":"B","beanA":A}}
TO String AOP {"C":{"cName":"C"}}
可以看到,循环依赖没问题,代理没问题,而最后创建代理的只有BeanB和BeanC,BeanC就不用说了,没有循环依赖,A和B互相依赖,由于先创建A再B,B创建时已经可以获取到A的二级缓存了,所以B并不需要提前暴露。
有点绕,有空补个时序图吧
以上是BeanFactory的简单模拟,起名基本参照spring,但spring的源码肯定更复杂更多判断,比如代理是通过后置处理器实现的,但大体思路差不多
over~