Spring Framework 源码阅读(三):认识FactoryBean
FactoryBean和BeanFactory虽然从命名上看起来相似,但作用却大不相同,BeanFactory负责创建和管理Spring容器中的bean,为bean从初始化到销毁建立了一整套统一的流程,让使用者可以不需要关注复杂的流程,只需关注bean本身的逻辑。而FactoryBean可以提供自定义bean初始化流程的功能,因此FactoryBean可以用于创建一类bean。
FactoryBean
public interface FactoryBean<T> {
String OBJECT_TYPE_ATTRIBUTE = "factoryBeanObjectType";
@Nullable
T getObject() throws Exception;
@Nullable
Class<?> getObjectType();
default boolean isSingleton() {
return true;
}
}- 如果一个
bean实现了FactoryBean接口,那么该bean将作为某一类bean的工厂,而不是直接作为一个bean。 - 实现
FactoryBean接口的bean不能用作普通bean。FactoryBean是以bean定义的,但是bean引用的对象始终是getObject方法创建的对象。 -
FactoryBean(不是单指FactoryBean接口)可以支持单例和原型,并且可以根据需要以懒加载的形式创建对象,也可以在启动时立即创建对象。SmartFactoryBean接口允许更细粒度的行为元数据。 -
FactoryBean接口在Spring框架中大量使用,例如ProxyFactoryBean(AOP)或JndiObjectFactoryBean。它也可用于定制component。
SmartFactoryBean接口源码:
public interface SmartFactoryBean<T> extends FactoryBean<T> {
default boolean isPrototype() {
return false;
}
default boolean isEagerInit() {
return false;
}
}创建module
先在Spring Framework源码中增加一个application module,这在之前的博文中已经介绍过了,这里就不再赘述:
- Spring Framework 源码阅读(一):Aware接口及其实现类的作用

IMessageService接口:
package com.kaven.service;
/**
* @Author: ITKaven
* @Date: 2021/09/25 14:04
* @Leetcode: https://leetcode-cn.com/u/kavenit
* @Notes:
*/
public interface IMessageService {
default String getMessage() {
return "default message";
}
}
MessageServiceImpl实现类:
package com.kaven.service.impl;
import com.kaven.service.IMessageService;
/**
* @Author: ITKaven
* @Date: 2021/09/25 14:05
* @Leetcode: https://leetcode-cn.com/u/kavenit
* @Notes:
*/
public class MessageServiceImpl implements IMessageService {
public String message;
public MessageServiceImpl(String message) {
this.message = message;
}
@Override
public String getMessage() {
return message;
}
}
MessageServiceFactoryBean类(实现FactoryBean接口):
package com.kaven.factory;
import com.kaven.service.IMessageService;
import com.kaven.service.impl.MessageServiceImpl;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.stereotype.Component;
/**
* @Author: ITKaven
* @Date: 2021/10/28 20:01
* @Leetcode: https://leetcode-cn.com/u/kavenit
* @Notes:
*/
@Component("myFactoryBean")
public class MessageServiceFactoryBean implements FactoryBean<IMessageService> {
@Override
public IMessageService getObject() throws Exception {
return new MessageServiceImpl("Hello Spring");
}
@Override
public Class<?> getObjectType() {
return IMessageService.class;
}
@Override
public boolean isSingleton() {
return false;
}
}
Application启动类:
package com.kaven;
import com.kaven.factory.MessageServiceFactoryBean;
import com.kaven.service.IMessageService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.ComponentScan;
import java.util.Arrays;
/**
* @Author: ITKaven
* @Date: 2021/09/25 13:54
* @Leetcode: https://leetcode-cn.com/u/kavenit
* @Notes:
*/
@ComponentScan({"com.kaven"})
public class Application {
public static void main(String[] args) {
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(Application.class);
IMessageService messageServiceBean = (IMessageService) applicationContext.getBean("myFactoryBean");
System.out.println(messageServiceBean.getMessage());
IMessageService messageServiceBean2 = (IMessageService) applicationContext.getBean("myFactoryBean");
System.out.println("messageServiceBean == messageServiceBean2: " + (messageServiceBean == messageServiceBean2));
MessageServiceFactoryBean messageServiceFactoryBean = (MessageServiceFactoryBean) applicationContext.getBean("&myFactoryBean");
System.out.println("isSingleton: " + messageServiceFactoryBean.isSingleton());
System.out.println(applicationContext.getBeanDefinitionCount());
Arrays.stream(applicationContext.getBeanDefinitionNames()).forEach(System.out::println);
}
}
运行输出:
> Task :application:Application.main()
Hello Spring
messageServiceBean == messageServiceBean2: false
isSingleton: false
6
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
application
myFactoryBean
很显然输出结果符合预期,通过FactoryBean的bean名称获取bean,只会获取该FactoryBean中getObject()方法返回的实例,也就是这里的MessageServiceImpl实例,如果想要获取FactoryBean本身的bean,需要在FactoryBean的bean名称前拼接一个&字符,在代码中已经有演示了。
想要了解为什么会创建下面这4个bean,可以阅读这篇博客:
- Spring Framework 源码阅读(二):BeanDefinition的作用
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
源码分析
现在开始分析为什么实现了FactoryBean接口,就可以自定义创建某一类bean的流程了,以及获取FactoryBean本身的bean,为什么要在FactoryBean的bean名称前拼接一个&字符。
自定义的bean,大部分会在DefaultListableBeanFactory类的preInstantiateSingletons方法中被开始创建(删除了部分代码):
@Override
public void preInstantiateSingletons() throws BeansException {
List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
for (String beanName : beanNames) {
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
if (isFactoryBean(beanName)) {
Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
if (bean instanceof FactoryBean) {
FactoryBean<?> factory = (FactoryBean<?>) bean;
boolean isEagerInit;
if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
isEagerInit = AccessController.doPrivileged(
(PrivilegedAction<Boolean>) ((SmartFactoryBean<?>) factory)::isEagerInit,
getAccessControlContext());
}
else {
isEagerInit = (factory instanceof SmartFactoryBean &&
((SmartFactoryBean<?>) factory).isEagerInit());
}
if (isEagerInit) {
getBean(beanName);
}
}
}
else {
getBean(beanName);
}
}
}
}
Debug如下图所示:

关注这一行(!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()结果是true,这些在AbstractBeanDefinition抽象类中设置了默认值,博主在上一篇博客中进行了介绍,并且isFactoryBean方法也会返回true,因为它就是FactoryBean):
Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
String FACTORY_BEAN_PREFIX = "&";
很显然beanName就是FactoryBean的bean名称,而FACTORY_BEAN_PREFIX + beanName就是&myFactoryBean,所以这里是获取FactoryBean本身的bean。
后面还会调用AbstractBeanFactory抽象类的getObjectForBeanInstance方法(删除了部分代码):
protected Object getObjectForBeanInstance(
Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {
if (BeanFactoryUtils.isFactoryDereference(name)) {
if (beanInstance instanceof NullBean) {
return beanInstance;
}
if (!(beanInstance instanceof FactoryBean)) {
throw new BeanIsNotAFactoryException(beanName, beanInstance.getClass());
}
if (mbd != null) {
mbd.isFactoryBean = true;
}
return beanInstance;
}
if (!(beanInstance instanceof FactoryBean)) {
return beanInstance;
}
Object object = null;
if (mbd != null) {
mbd.isFactoryBean = true;
}
else {
object = getCachedObjectForFactoryBean(beanName);
}
if (object == null) {
FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
if (mbd == null && containsBeanDefinition(beanName)) {
mbd = getMergedLocalBeanDefinition(beanName);
}
boolean synthetic = (mbd != null && mbd.isSynthetic());
object = getObjectFromFactoryBean(factory, beanName, !synthetic);
}
return object;
}

getObjectForBeanInstance方法会进行判断选择分支,会有三个分支,如果是获取FactoryBean本身的bean(getObjectForBeanInstance方法中的beanInstance参数其实在前面的调用链中已经被创建,如上图所示的sharedInstance变量,这里就不详细介绍,不然显得太杂乱,博主会在以后的博客中详细介绍bean的创建流程和生命周期),就会进入第一个分支:
if (BeanFactoryUtils.isFactoryDereference(name)) {
if (beanInstance instanceof NullBean) {
return beanInstance;
}
if (!(beanInstance instanceof FactoryBean)) {
throw new BeanIsNotAFactoryException(beanName, beanInstance.getClass());
}
if (mbd != null) {
mbd.isFactoryBean = true;
}
return beanInstance;
}BeanFactoryUtils抽象类的isFactoryDereference方法(就是判断name参数在不为null的情况下有没有&前缀):
public static boolean isFactoryDereference(@Nullable String name) {
return (name != null && name.startsWith(BeanFactory.FACTORY_BEAN_PREFIX));
}因此第一个分支就是返回FactoryBean本身的bean。
第二个分支(beanInstance参数不是FactoryBean实例,就是返回跟factory不相关的bean):
if (!(beanInstance instanceof FactoryBean)) {
return beanInstance;
}第三个分支(很显然是返回FactoryBean对应的那一类bean,下面会详细介绍):
Object object = null;
if (mbd != null) {
mbd.isFactoryBean = true;
}
else {
object = getCachedObjectForFactoryBean(beanName);
}
if (object == null) {
FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
if (mbd == null && containsBeanDefinition(beanName)) {
mbd = getMergedLocalBeanDefinition(beanName);
}
boolean synthetic = (mbd != null && mbd.isSynthetic());
object = getObjectFromFactoryBean(factory, beanName, !synthetic);
}
回到获取FactoryBean本身bean的preInstantiateSingletons方法中的这个部分:
if (bean instanceof FactoryBean) {
FactoryBean<?> factory = (FactoryBean<?>) bean;
boolean isEagerInit;
if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
isEagerInit = AccessController.doPrivileged(
(PrivilegedAction<Boolean>) ((SmartFactoryBean<?>) factory)::isEagerInit,
getAccessControlContext());
}
else {
isEagerInit = (factory instanceof SmartFactoryBean &&
((SmartFactoryBean<?>) factory).isEagerInit());
}
if (isEagerInit) {
getBean(beanName);
}
}SmartFactoryBean接口的源码在上面已经展示过了,非常简单,就是继承了FactoryBean接口,并且增加了两个方法,比如上面出现的isEagerInit()方法,这些源码都是相互联系的,大家还是要亲自Debug体验一下。因此这里的isEagerInit变量是false,因为MessageServiceFactoryBean类实现的是FactoryBean接口,所以实现FactoryBean接口的MessageServiceFactoryBean类不会立即(懒加载)创建它对应的那一类bean(MessageServiceImpl实例)。如果实现SmartFactoryBean接口,并且让isEagerInit方法返回true,在创建FactoryBean本身的bean后,也会立即创建FactoryBean对应的那一类bean,大家可以动手试一试。
因此,在ApplicationContext applicationContext = new AnnotationConfigApplicationContext(Application.class);这行代码结束后,FactoryBean本身的bean就已经在Spring容器中了,以便后续可以创建该FactoryBean对应的那一类bean。
之后通过FactoryBean的bean名称来获取bean,就是该FactoryBean对应的那一类bean(通过getObject方法返回的实例)。
IMessageService messageServiceBean = (IMessageService) applicationContext.getBean("myFactoryBean");Bebug如下图所示:

会调用AbstractBeanFactory抽象类的getObjectForBeanInstance方法(删除了部分代码),并且factory参数就是之前创建好的FactoryBean本身的bean(上面说过这里的beanInstance参数就是FactoryBean本身的bean,并且已经在之前的调用链中被创建好了,这里只是强转为FactoryBean<?>类型,方便后续调用getObject方法)。
protected Object getObjectForBeanInstance(
Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {
Object object = null;
if (mbd != null) {
mbd.isFactoryBean = true;
}
else {
object = getCachedObjectForFactoryBean(beanName);
}
if (object == null) {
FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
if (mbd == null && containsBeanDefinition(beanName)) {
mbd = getMergedLocalBeanDefinition(beanName);
}
boolean synthetic = (mbd != null && mbd.isSynthetic());
object = getObjectFromFactoryBean(factory, beanName, !synthetic);
}
return object;
}
重点在这一行:
object = getObjectFromFactoryBean(factory, beanName, !synthetic);
调用了FactoryBeanRegistrySupport抽象类的getObjectFromFactoryBean方法(删除了部分代码):
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)) {
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;
}
}这里的factory.isSingleton()会返回false,因此会执行下面这一行:
Object object = doGetObjectFromFactoryBean(factory, beanName);
调用了FactoryBeanRegistrySupport抽象类的doGetObjectFromFactoryBean方法:
private Object doGetObjectFromFactoryBean(FactoryBean<?> factory, String beanName) throws BeanCreationException {
Object object;
try {
if (System.getSecurityManager() != null) {
AccessControlContext acc = getAccessControlContext();
try {
object = AccessController.doPrivileged((PrivilegedExceptionAction<Object>) factory::getObject, acc);
}
catch (PrivilegedActionException pae) {
throw pae.getException();
}
}
else {
object = factory.getObject();
}
}
return object;
}最终会执行object = factory.getObject();,而factory参数就是之前创建好的FactoryBean本身的bean,因此会调用FactoryBean中的getObject方法,创建了与该FactoryBean对应的那一类bean。
Debug如下图所示:

阅读源码需要耐心,一步步进行Debug,每个人的理解不同,如果博主有说错的地方或者大家有不同的见解,欢迎大家评论补充。










