- getBean(String name)
- doGetBean开始获取bean
-
- doGetBean分段1
-
- AbstractAutowireCapableBeanFactory的getObjectForBeanInstance
- AbstractBeanFactory的getObjectForBeanInstance
-
- getCachedObjectForFactoryBean从缓存里获取
- getObjectFromFactoryBean创建bean
-
- doGetObjectFromFactoryBean
- beforeSingletonCreation和afterSingletonCreation
- postProcessObjectFromFactoryBean对创建出来的bean进行处理器处理
- 实战例子
getBean(String name)
昨天我们讲了单例实例化的时候会先判断是否是FactoryBean
类型的,是的话会进行相应处理,但是没讲最关键的getBean
,现在我们就开始讲这个,可能需要很多个篇幅,里面涉及了很多东西。废话不多说,我们开始吧。这些是我们要进行实例化的单例:
但是前面有一些已经被创建出来了,可以直接获取:
其实我们就只要关心我们自定义的两个对象:
我们开始吧:
doGetBean开始获取bean
我们来看下这个方法的参数:
name 就是bean名字
requiredType 表示需要的类型,如果有类型,创建后会进行类型转换
args 表示参数,也就是构造方法的参数
typeCheckOnly 表示只是做检查,并不是真的要用,这个会影响一些逻辑
因为代码比较长,我们分段来分析比较好,就保留和核心的代码:
doGetBean分段1
首先判断单例存在,且没有参数,这个时候还不能直接返回,还要做一些处理,因为传进来的名字可能是FactoryBean
本身,也就是name=&beanName
。
protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
//获取规范的名字
final String beanName = transformedBeanName(name);
Object bean;
//检查是否手动注册了单例
Object sharedInstance = getSingleton(beanName);
if (sharedInstance != null && args == null) {
//存在单例了
...
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
AbstractAutowireCapableBeanFactory的getObjectForBeanInstance
这个方法有两个重要的参数name
和beanName
,name
是指传进来的名字,可能是FactoryBean
本身的名字,有&
前缀,也可能是一般的bean
名字,beanName
是规范后的名字,去掉了&
前缀,所以要进行处理。比如这种:
@Override
protected Object getObjectForBeanInstance(
Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {
//如果有正在创建的bean要建立以来关系,后面讲
String currentlyCreatedBean = this.currentlyCreatedBean.get();
if (currentlyCreatedBean != null) {
registerDependentBean(beanName, currentlyCreatedBean);
}
return super.getObjectForBeanInstance(beanInstance, name, beanName, mbd);
}
AbstractBeanFactory的getObjectForBeanInstance
最后调用父类的处理方法,会下判断name
是不是FactoryBean
自身的名字,如果是,就判断beanInstance
是不是FactoryBean
类型的,是的话就直接返回,也就是说,要找的就是FactoryBean
自身,而不是他创建的bean
。如果不是FactoryBean
自身的名字,类型也不是FactoryBean
,那就普通的单例,直接返回。否则就是说明应该获取的是FactoryBean
创建的bean
。如果RootBeanDefinition
不为空的话,设置FactoryBean=true
,否则就从FactoryBean
的缓存中获取,如果获取到就直接返回,否则就要创建,然后返回。
protected Object getObjectForBeanInstance(
Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {
if (BeanFactoryUtils.isFactoryDereference(name)) {
//是否是FactoryBean名字的前缀
if (beanInstance instanceof NullBean) {
return beanInstance;
}
if (!(beanInstance instanceof FactoryBean)) {
//不是FactoryBean的话名字有&会报异常
throw new BeanIsNotAFactoryException(beanName, beanInstance.getClass());
}
if (mbd != null) {
mbd.isFactoryBean = true;
}
return beanInstance;
}
if (!(beanInstance instanceof FactoryBean)) {
//不是FactoryBean就直接返回
return beanInstance;
}
//创建FactoryBean中的bean
Object object = null;
if (mbd != null) {
mbd.isFactoryBean = true;
}
else {
//从FactoryBean的缓存中获取
object = getCachedObjectForFactoryBean(beanName);
}
if (object == null) {
FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
if (mbd == null && containsBeanDefinition(beanName)) {
//mbd没定义,但是FactoryBean是有定义的,获取mbd
mbd = getMergedLocalBeanDefinition(beanName);
}
boolean synthetic = (mbd != null && mbd.isSynthetic());
object = getObjectFromFactoryBean(factory, beanName, !synthetic);
}
return object;
}
getCachedObjectForFactoryBean从缓存里获取
factoryBeanObjectCache
就是FactoryBean
创建的bean
的缓存,创建一次后会进行缓存,下次直接拿。
@Nullable
protected Object getCachedObjectForFactoryBean(String beanName) {
return this.factoryBeanObjectCache.get(beanName);
}
getObjectFromFactoryBean创建bean
这里就是FactoryBean
创建bean
的过程。如果FactoryBean
是单例,且已经创建出来了,先从缓存里获取看看,如果存在直接返回。如果不存在就进行doGetObjectFromFactoryBean
创建,其实就是调用了getObject()
获取对象。这里又做了一次从缓存中获取,感觉挺奇怪的,前面已经获取不存在了,这里怎么又能存在,其实是因为getObject()
创建的时候可以自定义,可能有处理器处理,可能会对factoryBeanObjectCache
进行设置,所以这里还要判断一次,如果存在的话,就应该获取存在的,而不是刚创建的,这样的话处理器才算是有扩展的功能,否则处理了也等于没用。如果没有缓存存在,判断是否是否需要处理,其实这里说的就是不是合成的对象!synthetic
,比如AOP
的advice
通知就算是合成的,一般的对象都不合成的,如果需要处理,但是是正在创建中的单例,直接返回不处理,否则要进行处理器处理,最后放进缓存。如果是原型的话每次都创建一个新的。
protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess) {
if (factory.isSingleton() && containsSingleton(beanName)) {
synchronized (getSingletonMutex()) {
Object object = this.factoryBeanObjectCache.get(beanName);
if (object == null) {
object = doGetObjectFromFactoryBean(factory, beanName);
Object alreadyThere = this.factoryBeanObjectCache.get(beanName);
if (alreadyThere != null) {
object = alreadyThere;
}
else {
if (shouldPostProcess) {
//需要处理
if (isSingletonCurrentlyInCreation(beanName)) {
//直接返回
return object;
}
beforeSingletonCreation(beanName);
try {
object = postProcessObjectFromFactoryBean(object, beanName);//进行后置处理器处理
}
catch (Throwable ex) {
throw new BeanCreationException(beanName,
"Post-processing of FactoryBean's singleton object failed", ex);
}
finally {
afterSingletonCreation(beanName);
}
}
if (containsSingleton(beanName)) {
//如果包含了FactoryBean,就将创建的对象缓存
this.factoryBeanObjectCache.put(beanName, object);
}
}
}
return object;
}
}
else {
//FactoryBean是原型的话
Object object = doGetObjectFromFactoryBean(factory, beanName);
if (shouldPostProcess) {
try {
object = postProcessObjectFromFactoryBean(object, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(beanName, "Post-processing of FactoryBean's object failed", ex);
}
}
return object;
}
}
doGetObjectFromFactoryBean
其实没别的东西,就是调用getObject()
创建对象,如果返回null的话,就封装成一个NullBean
。
private Object doGetObjectFromFactoryBean(final FactoryBean<?> factory, final String beanName)
throws BeanCreationException {
Object object;
...
object = factory.getObject();//调用自定义的FactoryBean的getObject获取对象
...
if (object == null) {
if (isSingletonCurrentlyInCreation(beanName)) {
//如果是正在创建的FactoryBean,还没能获得bean,就报异常
throw new BeanCurrentlyInCreationException(
beanName, "FactoryBean which is currently in creation returned null from getObject");
}
object = new NullBean();
}
return object;
}
beforeSingletonCreation和afterSingletonCreation
这个就是标记下,正在创建这个bean
,创建处理完了就清除标记。
protected void beforeSingletonCreation(String beanName) {
if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.add(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);//没有在排除范围里内且添加不成功,可能就是循环引用了
}
}
protected void afterSingletonCreation(String beanName) {
if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.remove(beanName)) {
throw new IllegalStateException("Singleton '" + beanName + "' isn't currently in creation");
}
}
postProcessObjectFromFactoryBean对创建出来的bean进行处理器处理
就是进行BeanPostProcessor
的postProcessAfterInitialization
处理,也就是可以扩展的地方。
@Override
protected Object postProcessObjectFromFactoryBean(Object object, String beanName) {
return applyBeanPostProcessorsAfterInitialization(object, beanName);
}
@Override
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
for (BeanPostProcessor processor : getBeanPostProcessors()) {
Object current = processor.postProcessAfterInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}
实战例子
测试例子:
没有设置原型:
设置了原型:
可见在FactoryBean
上设置了@Scope("prototype")
会影响创建的bean
。
果然讲细了没多少东西好讲,但是不讲清除直接跳过去等于没学什么,走马观花,到头来遇到问题还是得深入探究,学东西还是有点研究精神好。剩下的下篇继续吧。
好了,今天就到这里了,希望对学习理解有帮助,大神看见勿喷,仅为自己的学习理解,能力有限,请多包涵。