发布于2026-05-31 阅读(0)
扫一扫,手机访问
FactoryBean 这个接口,说白了就是 Spring 给咱们预留的一个“自定义对象工厂”的钩子。你实现它之后,把它丢进 Spring 容器,它不光自己会变成 bean,还能捎带手把它要创建的 bean 也一并注册进去。本质上和设计模式里的工厂模式没啥两样——区别只在于一个是 Spring 容器帮你管,另一个得你自个儿手动折腾。
接口里就三个方法,核心逻辑全在这儿了:
public interface FactoryBean{ String OBJECT_TYPE_ATTRIBUTE = "factoryBeanObjectType"; @Nullable T getObject() throws Exception; @Nullable Class> getObjectType(); default boolean isSingleton() { return true; } }
getObject() 返回你要创建的 bean 实例;getObjectType() 告诉别人这个 bean 的类型是啥;isSingleton() 决定要不要缓存为单例,默认 true。简单明了。
在实际场景里,FactoryBean 很少单独出现,往往是和 Spring 提供的其他接口(比如 InitializingBean)搭着用。
先准备一个普通的 POJO 和一个 Builder,方便后续组装:
@Data
public class Customize {
private String id;
private String name;
private int age;
private String address;
private String phone;
}
public class CustomizeBuilder {
private Customize customize;
public CustomizeBuilder builder() {
customize = new Customize();
return this;
}
// ... 各种 setter 方法
public Customize build() {
return customize;
}
}
写一个 CustomizeFactoryBean,同时实现 FactoryBean 和 InitializingBean。后者会在所有属性注入完成后自动调用 afterPropertiesSet(),我们正好在这里把 bean 初始化好。
@Component public class CustomizeFactoryBean implements FactoryBean, InitializingBean { private Customize customize; @Override public Customize getObject() throws Exception { return customize; } @Override public Class> getObjectType() { return Customize.class; } @Override public void afterPropertiesSet() throws Exception { if (customize == null) { customize = new CustomizeBuilder().builder() .id("1") .name("sun") .age(18) .address("beijing") .phone("123456789") .build(); } } }
接着写个测试类验证一下:
@SpringBootTest
class SpringBeanApplicationTests {
@Autowired
private Customize customize;
@Autowired
private CustomizeFactoryBean customizeFactoryBean;
@Test
public void contextLoads() throws Exception {
System.out.println(customizeFactoryBean);
System.out.println(customizeFactoryBean.getObject());
System.out.println(customize);
}
}
输出结果:
com.agp.springbean.factorybean.CustomizeFactoryBean@5a592c70
Customize(id=1, name=sun, age=18, address=beijing, phone=123456789)
Customize(id=1, name=sun, age=18, address=beijing, phone=123456789)
跑一下就能看出,@Autowired 直接注入 Customize 拿到的是工厂里创建的那个对象;而注入 CustomizeFactoryBean 拿到的是工厂本身。如果想获取工厂实例,可以通过 &+factoryBeanName 的方式。


上面那个例子虽然能用 @Component 把工厂注册进容器,但这并不是它最正宗的玩法。想注册一个 bean 方法多的是,没必要这样绕。其实 FactoryBean 最大的价值在于——把第三方框架优雅地集成进 Spring。
咱们来看看 MyBatis 和 Spring 整合时是怎么做的。
MyBatis 的核心是 SqlSession,所有 SQL 操作都得通过它。而 SqlSession 是由 SqlSessionFactory 造出来的。只要拿到 SqlSessionFactory,就等于拿到了 MyBatis 的全部能力。具体解析过程的细节这里不展开,核心就是通过 build() 方法创建出 SqlSessionFactory。
public SqlSessionFactory build(Reader reader, String environment, Properties properties) {
try {
XMLConfigBuilder parser = new XMLConfigBuilder(reader, environment, properties);
return build(parser.parse());
} catch (Exception e) { ... }
}
那么问题来了:怎么把 SqlSessionFactory 塞进 Spring?答案就在 SqlSessionFactoryBean 这个 FactoryBean 里。
public class SqlSessionFactoryBean
implements FactoryBean, InitializingBean, ApplicationListener{
private SqlSessionFactory sqlSessionFactory;
@Override
public void afterPropertiesSet() throws Exception {
// 各种校验...
this.sqlSessionFactory = buildSqlSessionFactory();
}
@Override
public SqlSessionFactory getObject() throws Exception {
if (this.sqlSessionFactory == null) {
afterPropertiesSet();
}
return this.sqlSessionFactory;
}
@Override
public Class extends SqlSessionFactory> getObjectType() {
return this.sqlSessionFactory == null ? SqlSessionFactory.class : this.sqlSessionFactory.getClass();
}
@Override
public boolean isSingleton() {
return true;
}
}
你看,afterPropertiesSet() 里调用了 buildSqlSessionFactory() 来创建 SqlSessionFactory;getObject() 再把创建好的实例返回。这样,只要在 Spring 配置里(XML 或 JavaConfig)声明这个 SqlSessionFactoryBean,就能把 MyBatis 的核心组件无缝挂载到容器里,后面直接注入 SqlSessionFactory 干活就行。
FactoryBean 本质上是 Spring 在初始化阶段创建 bean 的一个“定制工厂”。个人觉得它更像一个插件接口——能把第三方的类以非常优雅的方式加载到 Spring 容器中。当然,它的用途不止于此,还有不少高级玩法值得深挖。
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
正版软件
正版软件
正版软件
正版软件
正版软件
1
2
3
7
8