讲一下beanfactory和factory bean不憋

8次阅读
没有评论

我再详细深入地讲解一下 BeanFactory 和 FactoryBean 的区别,这次从源码层面和实际应用角度来分析:

1. 概念对比

BeanFactory

  • 是什么:Spring IoC 容器的根接口
  • 作用:负责 Bean 的创建、管理、依赖注入
  • 定位:Spring 容器的基础设施

FactoryBean

  • 是什么:一个特殊的 Bean,实现了 FactoryBean 接口
  • 作用:用于创建复杂的对象,是 Bean 的工厂
  • 定位:自定义 Bean 创建逻辑的工具

2. 源码分析

BeanFactory 接口(简化版)

  1. public interface BeanFactory {
  2. String FACTORY_BEAN_PREFIX = "&"; // 获取 FactoryBean 本身的前缀
  3. Object getBean(String name) throws BeansException;
  4. <T> T getBean(Class<T> requiredType) throws BeansException;
  5. <T> T getBean(String name, Class<T> requiredType) throws BeansException;
  6. Object getBean(String name, Object... args) throws BeansException;
  7. <T> T getBean(Class<T> requiredType, Object... args) throws BeansException;
  8. boolean containsBean(String name);
  9. boolean isSingleton(String name) throws NoSuchBeanDefinitionException;
  10. boolean isPrototype(String name) throws NoSuchBeanDefinitionException;
  11. boolean isTypeMatch(String name, ResolvableType typeToMatch) throws NoSuchBeanDefinitionException;
  12. boolean isTypeMatch(String name, Class<?> typeToMatch) throws NoSuchBeanDefinitionException;
  13. Class<?> getType(String name) throws NoSuchBeanDefinitionException;
  14. String[] getAliases(String name);
  15. }

FactoryBean 接口

  1. public interface FactoryBean<T> {
  2. String OBJECT_TYPE_ATTRIBUTE = "factoryBeanObjectType";
  3. @Nullable
  4. T getObject() throws Exception; // 返回工厂生产的对象
  5. @Nullable
  6. Class<?> getObjectType(); // 返回对象的类型
  7. default boolean isSingleton() { // 是否单例
  8. return true;
  9. }
  10. }

3. 核心区别

维度 BeanFactory FactoryBean
本质 Spring 容器的接口 一个特殊的 Bean
职责 管理所有 Bean 创建特定类型的 Bean
继承关系 根接口 普通接口
使用方式 作为容器使用 实现接口后注册到容器
获取对象 getBean("beanName") getBean("factoryBeanName") 返回其创建的对象
获取自身 不适用 getBean("&factoryBeanName")

4. 获取方式详解

获取 FactoryBean 创建的对象

  1. ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
  2. // MyFactoryBean 是一个 FactoryBean
  3. MyObject obj = context.getBean("myFactoryBean"); // 返回 getObject() 的结果

获取 FactoryBean 本身

  1. // 加上 "&" 前缀
  2. MyFactoryBean factory = context.getBean("&myFactoryBean");

Spring 源码中的处理逻辑(AbstractBeanFactory):

  1. protected Object getObjectForBeanInstance(
  2. Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {
  3. // 如果是 FactoryBean 且请求的是工厂本身(以 & 开头)
  4. if (BeanFactoryUtils.isFactoryDereference(name)) {
  5. if (beanInstance instanceof NullBean) {
  6. return beanInstance;
  7. }
  8. if (!(beanInstance instanceof FactoryBean)) {
  9. throw new BeanIsNotAFactoryException(beanName, beanInstance.getClass());
  10. }
  11. return beanInstance; // 返回 FactoryBean 本身
  12. }
  13. // 如果不是 FactoryBean,直接返回
  14. if (!(beanInstance instanceof FactoryBean)) {
  15. return beanInstance;
  16. }
  17. // 如果是 FactoryBean,返回其创建的对象
  18. Object object = null;
  19. if (mbd != null) {
  20. mbd.isFactoryBean = true;
  21. }
  22. object = getObjectFromFactoryBean((FactoryBean<?>) beanInstance, beanName, !synthetic);
  23. return object;
  24. }

5. 实际应用示例

示例 1:自定义 FactoryBean 创建复杂对象

  1. @Component
  2. public class ConnectionFactoryBean implements FactoryBean<Connection> {
  3. private String url;
  4. private String username;
  5. private String password;
  6. public void setUrl(String url) { this.url = url; }
  7. public void setUsername(String username) { this.username = username; }
  8. public void setPassword(String password) { this.password = password; }
  9. @Override
  10. public Connection getObject() throws Exception {
  11. DriverManager.getConnection(url, username, password);
  12. }
  13. @Override
  14. public Class<?> getObjectType() {
  15. return Connection.class;
  16. }
  17. @Override
  18. public boolean isSingleton() {
  19. return false; // 每次获取都创建新连接
  20. }
  21. }

示例 2:Spring 内置的 FactoryBean

Spring 内部大量使用 FactoryBean,例如:

SqlSessionFactoryBean(MyBatis 集成):

  1. public class SqlSessionFactoryBean implements FactoryBean<SqlSessionFactory>, InitializingBean, ApplicationListener<ApplicationEvent> {
  2. @Override
  3. public SqlSessionFactory getObject() throws Exception {
  4. return this.sqlSessionFactory;
  5. }
  6. @Override
  7. public Class<?> getObjectType() {
  8. return this.sqlSessionFactory == null ? SqlSessionFactory.class : this.sqlSessionFactory.getClass();
  9. }
  10. }

使用方式

  1. @Configuration
  2. public class MyBatisConfig {
  3. @Bean
  4. public SqlSessionFactoryBean sqlSessionFactory(DataSource dataSource) {
  5. SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
  6. factoryBean.setDataSource(dataSource);
  7. factoryBean.setMapperLocations(new PathMatchingResourcePatternResolver()
  8. .getResources("classpath:mapper/*.xml"));
  9. return factoryBean;
  10. }
  11. }
  12. // 获取 SqlSessionFactory
  13. SqlSessionFactory sessionFactory = context.getBean(SqlSessionFactory.class);

6. FactoryBean 的生命周期

  1. @Component
  2. public class MyFactoryBean implements FactoryBean<MyObject>, InitializingBean, DisposableBean {
  3. @Override
  4. public void afterPropertiesSet() throws Exception {
  5. System.out.println("FactoryBean 初始化");
  6. }
  7. @Override
  8. public MyObject getObject() throws Exception {
  9. System.out.println("创建 MyObject");
  10. return new MyObject();
  11. }
  12. @Override
  13. public Class<?> getObjectType() {
  14. return MyObject.class;
  15. }
  16. @Override
  17. public void destroy() throws Exception {
  18. System.out.println("FactoryBean 销毁");
  19. }
  20. }

执行顺序

  1. FactoryBean 实例化
  2. afterPropertiesSet() 执行
  3. 第一次 getBean() 时调用 getObject()
  4. 容器关闭时调用 destroy()

7. 常见使用场景

① 创建第三方复杂对象

  1. @Component
  2. public class RedisConnectionFactoryBean implements FactoryBean<RedisConnection> {
  3. @Override
  4. public RedisConnection getObject() throws Exception {
  5. return new JedisConnectionFactory().getConnection();
  6. }
  7. @Override
  8. public Class<?> getObjectType() {
  9. return RedisConnection.class;
  10. }
  11. }

② 需要动态代理的对象

  1. @Component
  2. public class ProxyFactoryBean implements FactoryBean<Object> {
  3. private Object target;
  4. @Override
  5. public Object getObject() throws Exception {
  6. return Proxy.newProxyInstance(
  7. target.getClass().getClassLoader(),
  8. target.getClass().getInterfaces(),
  9. new MyInvocationHandler(target)
  10. );
  11. }
  12. @Override
  13. public Class<?> getObjectType() {
  14. return target.getClass();
  15. }
  16. }

③ 整合第三方框架

  1. // Spring 整合 RabbitMQ
  2. @Bean
  3. public RabbitAdmin rabbitAdmin(ConnectionFactory connectionFactory) {
  4. return new RabbitAdmin(connectionFactory);
  5. }
  6. @Bean
  7. public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory) {
  8. return new RabbitTemplate(connectionFactory);
  9. }

8. 总结对比图

  1. ┌─────────────────────────────────────────────────────────┐
  2. Spring 容器
  3. (BeanFactory)
  4. ┌─────────────────────────────────────────────────┐
  5. 普通 Bean
  6. ┌─────────────────────────────────────────┐
  7. UserService
  8. OrderService
  9. └─────────────────────────────────────────┘
  10. └─────────────────────────────────────────────────┘
  11. ┌─────────────────────────────────────────────────┐
  12. FactoryBean(特殊 Bean
  13. ┌─────────────────────────────────────────┐
  14. SqlSessionFactoryBean
  15. └─> 创建 SqlSessionFactory
  16. ConnectionFactoryBean
  17. └─> 创建 Connection
  18. └─────────────────────────────────────────┘
  19. └─────────────────────────────────────────────────┘
  20. └─────────────────────────────────────────────────────────┘

一句话总结

BeanFactory 是 Spring 容器本身,负责管理所有 Bean;FactoryBean 是一个特殊的 Bean,用于创建其他 Bean。当你需要自定义复杂对象的创建逻辑时,就实现 FactoryBean 接口。

希望这次更深入的解释能帮助你更好地理解这

正文完
 0
bdspAdmin
版权声明:本站原创文章,由 bdspAdmin 于2026-04-24发表,共计6165字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
评论(没有评论)