BeanFactory 是接口,可以理解为bean工厂(ioc容器),用来生产和管理bean的整个生命周期
FactoryBean也是接口,可以理解为工厂bean,既然是bean,也要交由BeanFactory进行管理的,但是与普通bean不同,它可以生产对象,经过装饰之后将对象也交由BeanFactory管理(比如返回某个对象的代理对象,Mybatis继集成spring就是这样做的),我们通过FactoryBean的beanName去获取Bean时,获取到的是它的getObject()方法返回的对象,只有在beanName前面加上&符号,才能获取到真正的factoryBean对象。
BeanFactory 可以生产bean
FactoryBean只会返回普通的对象交由spring管理,而不是真正意义上的bean,他并没有经过完整的bean的生命周期
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MyApplicationContextConfig.class);
User user = (User)context.getBean("userFactoryBean");
FactoryBean factoryBean = (FactoryBean) context.getBean("&userFactoryBean");
System.out.println(factoryBean);
System.out.println(user);AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MyApplicationContextConfig.class);
User user = (User)context.getBean("userFactoryBean");
FactoryBean factoryBean = (FactoryBean) context.getBean("&userFactoryBean");
System.out.println(factoryBean);
System.out.println(user);
源码剖析:
首先明确,在生成bean的beanDefinition时,是不会判断是否为FactoryBean,会像普通的bean一样,将其放入beanDefinitionMap中
public void preInstantiateSingletons() throws BeansException {
......
// 如果是工厂bean在实例化时,会在beanName前面加上&,再去执行getBean()方法,但是在getBean()方法中,经过转化,还是会去掉&,按正常流程生成bean,放入singletonObjects中,也就是说beanFactory在单例池中还是以(beanName,BeanFactory类型)存在的
if (this.isFactoryBean(beanName)) {
bean = this.getBean("&" + beanName);
break;
}
this.getBean(beanName);
....
}
当我们手动的调用getBean(xxx)方法时,会进入如下代码:
protected <T> T doGetBean(String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly) throws BeansException {
// 进行名称的转换,如果传入的xxx是以&开头的,会返回去掉了&的beanName,如果不是直接返回。
String beanName = this.transformedBeanName(name);
// 从单例池中获取beanName对应的bean,根据前面的创建原则我们可以知道,如果获取的是FactoryBean,那么此处返回的就是FactoryBean本身
Object sharedInstance = this.getSingleton(beanName);
Object beanInstance;
// sharedInstance从单例池中获取到了bean不为null,args默认就是null,除非我们手动传参,进入判断
if (sharedInstance != null && args == null) {
if (this.logger.isTraceEnabled()) {
if (this.isSingletonCurrentlyInCreation(beanName)) {
this.logger.trace("Returning eagerly cached instance of singleton bean '" + beanName + "' that is not fully initialized yet - a consequence of a circular reference");
} else {
this.logger.trace("Returning cached instance of singleton bean '" + beanName + "'");
}
}
// 此处就是判断获取到的bean是不是FactoryBean并且name是不是以&开头
// 1.如果不是FactoryBean或者是FactoryBean且beanName以&开头(想要获取FactoryBean本身),直接返回原sharedInstance
//2.如果是FactoryBean且不是以&开头(表明想要获取FactoryBean所包裹的对象),会调用它的getObject()方法,获取方法返回的对象,并返回
beanInstance =
this.getObjectForBeanInstance(sharedInstance, name, beanName, (RootBeanDefinition)null);
} else {
......
// 在bean还未被创建时会进入此else中,也就是刚开始创建bean
if (mbd.isSingleton()) {
// FactoryBean也按照普通bean的创建方式在此处创建
sharedInstance = this.getSingleton(beanName, () -> {
try {
return this.createBean(beanName, mbd, args);
} catch (BeansException var5) {
this.destroySingleton(beanName);
throw var5;
}
});
// 此处与上面相同↑,但是如果是工厂bean,在此方法中会直接将工厂bean返回
beanInstance = this.getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}else if{
......
}else{
......
}
}
getObjectForBeanInstance()
protected Object getObjectForBeanInstance(Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {
// 判断name是不是以&开头的,如果是进入if
if (BeanFactoryUtils.isFactoryDereference(name)) {
if (beanInstance instanceof NullBean) {
return beanInstance;
// 判断从单例池中拿到的bean是不是FactoryBean类型的,如果不是抛出异常,也就是说如果你想获取一个普通bean,但是你在它的名字前面加上了&,在获取时就会报错,抛出BeanIsNotAFactoryException异常
} else if (!(beanInstance instanceof FactoryBean)) {
throw new BeanIsNotAFactoryException(beanName, beanInstance.getClass());
} else {
if (mbd != null) {
// 经过上述判断,来到此处,将其标志为工厂Bean
mbd.isFactoryBean = true;
}
// 到这里,就可以知道它是一个工厂bean,并且name以&开头,想要获取工厂bean本身,直接返回原bean即可
return beanInstance;
}
// 如果不是工厂bean,直接返回原bean
} else if (!(beanInstance instanceof FactoryBean)) {
return beanInstance;
} else {
// 如果是工厂bean,但是不是以&开头的,所以会去获取getObject()所返回的对象
Object object = null;
if (mbd != null) {
mbd.isFactoryBean = true;
} else {
object = this.getCachedObjectForFactoryBean(beanName);
}
if (object == null) {
FactoryBean<?> factory = (FactoryBean)beanInstance;
if (mbd == null && this.containsBeanDefinition(beanName)) {
mbd = this.getMergedLocalBeanDefinition(beanName);
}
// 判断beanDefinition是不是合成的,一般情况下由spring容器产生的beanDefinition都不是合成的
boolean synthetic = mbd != null && mbd.isSynthetic();
// 调用FactoryBean的getObject()方法,获取其返回的对象
object = this.getObjectFromFactoryBean(factory, beanName, !synthetic);
}
return object;
}
}
getObjectFromFactoryBean()
protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess) {
if (factory.isSingleton() && this.containsSingleton(beanName)) {
synchronized(this.getSingletonMutex()) {
//从FactoryBean对象的缓存池中获取,因为是首次获取,肯定是获取不到的
// Map<String, Object> factoryBeanObjectCache = new ConcurrentHashMap(16);
Object object = this.factoryBeanObjectCache.get(beanName);
if (object == null) {
// 调用FactoryBean的getObject()方法,获取对象
object = this.doGetObjectFromFactoryBean(factory, beanName);
// 再次尝试从缓存池中获取
Object alreadyThere = this.factoryBeanObjectCache.get(beanName);
if (alreadyThere != null) {
// 如果缓存池中存在了,直接更新objects为缓存池中的值
object = alreadyThere;
} else {
// 此处判断需不需要对该对象进行后置处理(比如对其进行aop增强)
// shouldPostProcess = !synthetic,只要beanDefinition不是合成的,就需要进行后置处理
if (shouldPostProcess) {
if (this.isSingletonCurrentlyInCreation(beanName)) {
return object;
}
// 将该工厂bean声明为正在创建状态
this.beforeSingletonCreation(beanName);
try {
// 调用BeanPostProcessor后置处理器的postProcessAfterInitialization方法,如果FactoryBean进行了Aop代理增强,那么也需要对object进行aop增强
object = this.postProcessObjectFromFactoryBean(object, beanName);
} catch (Throwable var14) {
throw new BeanCreationException(beanName, "Post-processing of FactoryBean's singleton object failed", var14);
} finally {
this.afterSingletonCreation(beanName);
}
}
if (this.containsSingleton(beanName)) {
// 将getObject()获取到的对象放入factoryBean的对象缓存池中,下次直接从缓存池中获取
this.factoryBeanObjectCache.put(beanName, object);
}
}
}
return object;
}
} else {
Object object = this.doGetObjectFromFactoryBean(factory, beanName);
if (shouldPostProcess) {
try {
object = this.postProcessObjectFromFactoryBean(object, beanName);
} catch (Throwable var17) {
throw new BeanCreationException(beanName, "Post-processing of FactoryBean's object failed", var17);
}
}
return object;
}
}
doGetObjectFromFactoryBean()
private Object doGetObjectFromFactoryBean(FactoryBean<?> factory, String beanName) throws BeanCreationException {
Object object;
try {
// 系统的安全管理员默认是null
if (System.getSecurityManager() != null) {
AccessControlContext acc = this.getAccessControlContext();
try {
object = AccessController.doPrivileged(factory::getObject, acc);
} catch (PrivilegedActionException var6) {
throw var6.getException();
}
} else {
// 调用其getObject()方法,获取对象
object = factory.getObject();
}
} catch (FactoryBeanNotInitializedException var7) {
throw new BeanCurrentlyInCreationException(beanName, var7.toString());
} catch (Throwable var8) {
throw new BeanCreationException(beanName, "FactoryBean threw exception on object creation", var8);
}
if (object == null) {
if (this.isSingletonCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName, "FactoryBean which is currently in creation returned null from getObject");
}
// 如果object是null,并且当前工厂对象没有处于正在创建的状态,就返回NullBean对象
object = new NullBean();
}
// 将object返回
return object;
}
总结:
1.
FactoryBean
包裹的对象是天然懒加载的,如果FactoryBean是单例的,则会在第一个调用getBean()
的时候创建,然后放到factoryBeanObjectCache缓存中,并且FactoryBean在单例池中就是以beanName,bean的形式存在的,并不会加上&,只有在getBean(“xxx”),才会根据传入的beanName去进行判断,从不同的地方获取2.我们在写AOP增强的时候,不只是会增强FactoryBean本身,还会增强FactoryBean所包裹的对象
如有问题欢迎指正讨论......