FactoryBean接口
Bean可以继承此接口。
getBean的时候,BeanName如果以 &开头,就直接返回此Bean
如果不是,就返回 getObject()
public interface FactoryBean<T> {
String OBJECT_TYPE_ATTRIBUTE = "factoryBeanObjectType";
@Nullable
T getObject() throws Exception;
@Nullable
Class<?> getObjectType();
default boolean isSingleton() {
return true;
}
}
继承了此接口的Bean,在getBean时有特殊处理,流程如下:
app.getBean("FactoryBeanName");或app.getBean("&FactoryBeanName");
public Object getBean(String name) throws BeansException {
assertBeanFactoryActive();
// 分析 .getBean(name)
return getBeanFactory().getBean(name);
}
AbstractBeanFactory.getBean();
public Object getBean(String name) throws BeansException {
// 分析 doGetBean
return this.doGetBean(name, (Class)null, (Object[])null, false);
}
AbstractBeanFactory.doGetBean();
protected <T> T doGetBean(String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly) throws BeansException {
String beanName = this.transformedBeanName(name);
Object sharedInstance = this.getSingleton(beanName);
Object bean;
if (sharedInstance != null && args == null) {
// ...
// 分析 getObjectForBeanInstance
bean = this.getObjectForBeanInstance(sharedInstance, name, beanName, (RootBeanDefinition)null);
} else // ... 当然 else 中也有 getObjectForBeanInstance
}
AbstractBeanFactory.getObjectForBeanInstance();
public static boolean isFactoryDereference(@Nullable String name) {
// 判断 BeanName 是否以 & 开头
return name != null && name.startsWith("&");
}
protected Object getObjectForBeanInstance(Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {
// isFactoryDereference 在上面
if (BeanFactoryUtils.isFactoryDereference(name)) { // 如果beanName以 & 开头,直接返回Bean
if (beanInstance instanceof NullBean) {
return beanInstance;
} else if (!(beanInstance instanceof FactoryBean)) {
throw new BeanIsNotAFactoryException(beanName, beanInstance.getClass());
} else {
if (mbd != null) {
mbd.isFactoryBean = true;
}
return beanInstance;
}
} else if (!(beanInstance instanceof FactoryBean)) { // 如果没有继承FactoryBean,直接返回
return beanInstance;
} else { // 继承了FactoryBean,BeanName不以 & 开头
// ...
if (object == null) {
// ...
// 分析 getObjectFromFactoryBean
object = this.getObjectFromFactoryBean(factory, beanName, !synthetic);
}
return object;
}
}
FactoryBeanRegistrySupport.getObjectFromFactoryBean();
protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess) {
if (factory.isSingleton() && this.containsSingleton(beanName)) {
// ...
} else {
// 分析 doGetObjectFromFactoryBean
Object object = this.doGetObjectFromFactoryBean(factory, beanName);
// ...
return object;
}
}
private Object doGetObjectFromFactoryBean(FactoryBean<?> factory, String beanName) throws BeanCreationException {
Object object;
try {
if (System.getSecurityManager() != null) {
// ...
} else {
// 这行代码眼熟吧,就是FactoryBean接口里用来返回对象的。
object = factory.getObject();
}
} // ...
return object;
}
通过 factory.getObject()获取真实对象,如果BeanName用 &开头,就直接返回那个 FeactoryBean。

浙公网安备 33010602011771号