目录
1.FactoryBean
接口简述
BeanFactory
与 FactoryBean
接口,相信很多刚翻看 Spring
源码跟我一样很好奇这俩货怎么长得这么像,分别都是干啥用的。BeanFactory
是 Spring
中 Bean
工厂的顶层接口,也是我们常说的 Spring IOC
容器,它定下了 IOC
容器的一些规范和常用方法并管理着 Spring
中所有的 Bean
,今天我们不讲它,我们看一下后面那个 FactoryBean
public interface FactoryBean<T> {
@Nullable
T getObject() throws Exception;
@Nullable
Class<?> getObjectType();
default boolean isSingleton() {
return true;
}
}
先说下 FactoryBean
和其作用再开始分析:首先它是一个 Bean
,但又不仅仅是一个 Bean
。它是一个能生产或修饰对象生成的工厂 Bean
,类似于设计模式中的工厂模式和装饰器模式。它能在需要的时候生产一个对象,且不仅仅限于它自身,它能返回任何 Bean
的实例
2.FactoryBean
在 Spring
中的应用
在 Spring
中我们的 Bean
都会被 Spring
的 IOC
容器所管理,在 AbstractApplicationContext
中有一个很重要的方法:refresh()
,项目启动或重启的时候 refresh()
会调用 getBean()
初始化所有的 Bean
,这个 getBean()
最终会指向 AbstractBeanFactory
中的 getBean()
方法。上述方法的调用链过长,我们不过多赘述,详细的 getBean()
源码 在这里
在 AbstractBeanFactory
抽象类中,不管是根据名称还是根据类型,getBean()
方法最终都会调用 doGetBean()
方法
2.1.doGetBean()
在 doGetBean()
方法中一开始就获取了名称 beanName
和实例 sharedInstance
@SuppressWarnings("unchecked")
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) {
if (logger.isDebugEnabled()) {
if (isSingletonCurrentlyInCreation(beanName)) {
logger.debug("Returning eagerly cached instance of singleton bean '" + beanName +
"' that is not fully initialized yet - a consequence of a circular reference");
}
else {
logger.debug("Returning cached instance of singleton bean '" + beanName + "'");
}
}
// 如果 sharedInstance 是普通的单例 bean,下面的方法会直接返回。但如果
// 是 FactoryBean 类型的,则需调用 getObject 工厂方法获取真正的 bean 实例
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
else {
// 如果是原型不应该在初始化的时候创建,在这里直接抛出异常
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
BeanFactory parentBeanFactory = getParentBeanFactory();
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
// 将别名解析成真正的beanName
String nameToLookup = originalBeanName(name);
// 如果parentBeanFactory存在,并且beanName在当前BeanFactory不存在Bean定义,则尝试从parentBeanFactory中获取bean实例
if (parentBeanFactory instanceof AbstractBeanFactory) {
return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
nameToLookup, requiredType, args, typeCheckOnly);
}
// 尝试在parentBeanFactory中获取bean对象实例
else if (args != null) {
return (T) parentBeanFactory.getBean(nameToLookup, args);
}
else {
return parentBeanFactory.getBean(nameToLookup, requiredType);
}
}
if (!typeCh