首先我们可以看到FactoryBeanRegistrySupport其只有一个全局变量:
factoryBeanObjectCache:
然后这个类会牵扯到一个接口FactoryBean,即工厂Bean:
先来看一个简单的工厂bean的使用案例,来了解其用法,再通过源码说明其加载过程:
先注册一个Bean标签,
<bean id="stuFactory" class = "fev.test.StudentFactory"/>,之后:
public class StudentFactory implements FactoryBean<Student>{
@Override
public Student getObject() throws Exception {
return new Student("AAA");
}
@Override
public Class<?> getObjectType() {
return Student.class;
}
}
然后获取:
@Test
public void testStuFactory() throws Exception {
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
new XmlBeanDefinitionReader(factory).loadBeanDefinitions(RETURNS_NULL_CONTEXT);
Student stuFactory = (Student) factory.getBean("stuFactory");
System.out.println(stuFactory.toString());
}
再看输出:
在这里有没有发现--我们获取的是一个Student对象,而不是一个StudentFactory对象,现在我们可以知道其就是一个产生需要对象的工厂。
现在我们通过源码来看其加载过程:
首先我们来看FactoryBeanRegistrySupport的方法:
我们抓住其几个关键方法:
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);
// Only post-process and store if not put there already during getObject() call above
// (e.g. because of circular reference processing triggered by custom getBean calls)
Object alreadyThere = this.factoryBeanObjectCache.get(beanName);
if (alreadyThere != null) {
object = alreadyThere;
}
else {
if (shouldPostProcess) {
try {
object = postProcessObjectFromFactoryBean(object, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(beanName,
"Post-processing of FactoryBean's singleton object failed", ex);
}
}
this.factoryBeanObjectCache.put(beanName, object);
}
}
return object;
}
}
else {
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;
}
}
两个关键方法,通过
getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess)方法,调用
doGetObjectFromFactoryBean(final FactoryBean<?> factory, final String beanName)方法产生一个对象一个对象:
object = factory.getObject();也就是调用FactoryBean对象的getObject()返回一个对象,之后将这个对象像三层缓存那样放到
factoryBeanObjectCache中。而postProcessObjectFromFactoryBean方法就是调用BeanPostProcessor接口其操作产生的Bean对象。
然后我们直接看在哪里会调用getObjectFromFactoryBean方法。
这里可以直接看到,是在AbstractBeanFactory的:
public Object getBean(String name) throws BeansException {
return doGetBean(name, null, null, false);
}
也就是获取bean时:
直接进入doGetBean方法:这里会有几个地方调用到getObjectForBeanInstance方法,其调用的时机都是一样的:即就是在获取Bean对象之后,
if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, () -> {
try {
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
// Explicitly remove instance from singleton cache: It might have been put there
// eagerly by the creation process, to allow for circular reference resolution.
// Also remove any beans that received a temporary reference to the bean.
destroySingleton(beanName);
throw ex;
}
});
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
在这里我们可以清楚,这个sharedInstance 就是BeanFactory(StudentFactory)对象,而我们要的最终的bean(Student)对象,就是通过getObjectForBeanInstance方法产生的,而getObjectForBeanInstance方法会判断其是不是一个FactoryBean的实例:
protected Object getObjectForBeanInstance(
Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {
// Don't let calling code try to dereference the factory if the bean isn't a factory.
if (BeanFactoryUtils.isFactoryDereference(name)) {
if (beanInstance instanceof NullBean) {
return beanInstance;
}
if (!(beanInstance instanceof FactoryBean)) {
throw new BeanIsNotAFactoryException(transformedBeanName(name), beanInstance.getClass());
}
}
// Now we have the bean instance, which may be a normal bean or a FactoryBean.
// If it's a FactoryBean, we use it to create a bean instance, unless the
// caller actually wants a reference to the factory.
if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) {
return beanInstance;
}
Object object = null;
if (mbd == null) {
object = getCachedObjectForFactoryBean(beanName);
}
if (object == null) {
// Return bean instance from factory.
FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
// Caches object obtained from FactoryBean if it is a singleton.
if (mbd == null && containsBeanDefinition(beanName)) {
mbd = getMergedLocalBeanDefinition(beanName);
}
boolean synthetic = (mbd != null && mbd.isSynthetic());
object = getObjectFromFactoryBean(factory, beanName, !synthetic);
}
return object;
}
如果是其就调用FactoryBeanRegistrySupport对象的
getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess)
方法去创建一个对象,也就是我们上面描叙的。如果不是就直接放行。
所以通过上方我们可以清楚FactoryBean、以及FactoryBeanRegistrySupport的逻辑关系:
正常我们需要一个A,就是通过直接产生一个A,而如果我们想自己去创建这个A对象,我们可以通过这个FactoryBean,也就是B。然后过程是,spring先创建B,然后调用B的方法去创建A。即Spring容器->A,Spring容器-B->A。