【SpringBoot系列】BeanFactory 和 FactoryBean傻傻分不清楚

被问起这个问题,记录下。

1、定义

1.1 简单理解

BeanFactory 翻译下 bean工厂,是一个工厂。

FactoryBean 翻一下 工厂Bean,是一个bean 。

1.2 你看到的实例

BeanFactory 最直接的实现就是DefaultListableBeanFactory,认识吧,简单点就是spring的容器

FactoryBean的最直接的实现就是 JpaRepositoryFactory ,认识不

1.3 废话解释

BeanFactory定义了IOC容器的最基本形式,并提供了IOC容器应遵守的的最基本的接口。在Spring代码中,BeanFactory只是个接口,并不是IOC容器的具体实现,但是Spring容器给出了很多种实现,如 DefaultListableBeanFactory、XmlBeanFactory、ApplicationContext等,都是附加了某种功能的实现。

FactoryBean 在某些情况下,实例化Bean过程比较复杂,则需要提供大量的配置信息。采用编码的方式可能会得到更灵活简单的方案。Spring为此提供了一个org.springframework.bean.factory.FactoryBean的工厂类接口,用户可以通过实现该接口定制实例化Bean的逻辑。

2、使用场景

2.1 beanFactory

通常会使用 ApplicationContext 接口的实现类,例如 ClassPathXmlApplicationContext 或者 AnnotationConfigApplicationContext,因为它们扩展了 BeanFactory 接口,提供了更多的功能,如国际化支持、事件发布等。

总的来说,BeanFactory 是 Spring 中负责管理 Bean 的核心接口,它在应用程序中起着至关重要的作用。

在一个Spring应用中,通常只会存在一个BeanFactory实例。BeanFactory是Spring框架中负责管理Bean的核心接口,它负责创建、配置和管理Bean对象,以及解决Bean之间的依赖关系。

在Spring中,有两种常用的BeanFactory实现:

DefaultListableBeanFactory

:这是Spring的默认实现,它支持完整的Bean定义、注册、查找和解析等功能。

XmlBeanFactory

(已在Spring 3.1中废弃):它从一个XML文件中读取Bean的配置信息,属于比较早期的实现。

通常情况下,一个Spring应用会初始化一个BeanFactory,该BeanFactory会根据配置文件中的信息创建、管理各种Bean。

如果你在一个Spring应用中确实有多个BeanFactory,那通常是因为你在特殊情况下需要手动创建额外的BeanFactory实例,例如为了实现特定的定制化需求或测试目的。但这不是常见的做法,绝大多数情况下,一个Spring应用只会使用一个BeanFactory。

2.2 FactoryBean

动态创建Bean

FactoryBean 可以根据需要动态地创建不同类型的Bean实例。这在某些场景下是非常有用的,比如根据配置文件中的条件来动态选择创建哪种类型的Bean。

AOP(面向切面编程):

通过 FactoryBean 可以实现自定义的AOP代理创建逻辑,从而在创建代理对象时可以添加一些额外的处理。

懒加载:

FactoryBean 可以实现懒加载,即只有在第一次获取Bean时才会进行初始化和创建。 FactoryBean在Spring中最为典型的一个应用就是用来创建AOP的代理对象。

AOP是Spring在运行时创建了代理对象,而不是一开始就定义好的,这很符合工厂方法模式。AOP代理对象通过Java的反射机制,在运行时创建了一个代理对象,在代理对象的目标方法中根据业务要求织入了相应的方法。这个对象在Spring中就是------ProxyFactoryBean。

3、FactoryBean实例

3.1 创建FactoryBean

创建FactoryBean 的实现类TestFactoryBean ,并使用@Service注解放入IOC容器中

js 复制代码
@Service
public class TestFactoryBean implements FactoryBean {
 
 
    @Override
    public Object getObject() throws Exception {
		//手动创建bean
        return new PlayerServiceImpl();
    }
 
    @Override
    public Class<?> getObjectType() {
        return PlayerServiceImpl.class;
    }
 
	//这个方法可以不用覆写,父类默认是单例,如果想设置成非单例可以覆写方法返回false
    public boolean isSingleton() {
        return false;
    }
}

3.2 创建PlayerServiceImpl类,

这里我们没有使用@Service,@Componet等注解,在应用启动后不会被加入Springboot的容器当中。

js 复制代码
public class PlayerServiceImpl implements IPlayerService{
 
    public void say() {
        System.out.println("hello 香菜");
    }
}

3.3 测试一下

js 复制代码
@SpringBootTest
class DemoApplicationTests {
 
    @Autowired
    ApplicationContext applicationContext;
 
    @Test
    void test() {
        PlayerService bean = applicationContext.getBean(IPlayerService .class);
        System.out.println(bean);
        bean.say();
        PersonService bean2 = applicationContext.getBean(IPlayerService .class);
        System.out.println(bean2);
    }
 
}
相关推荐
小江的记录本19 小时前
【事务】Spring Framework核心——事务管理:ACID特性、隔离级别、传播行为、@Transactional底层原理、失效场景
java·数据库·分布式·后端·sql·spring·面试
sheji341619 小时前
【开题答辩全过程】以 基于springboot的校园失物招领系统为例,包含答辩的问题和答案
java·spring boot·后端
程序员cxuan19 小时前
人麻了,谁把我 ssh 干没了
人工智能·后端·程序员
wuyikeer21 小时前
Spring Framework 中文官方文档
java·后端·spring
Victor35621 小时前
MongoDB(61)如何避免大文档带来的性能问题?
后端
Victor35621 小时前
MongoDB(62)如何避免锁定问题?
后端
wuyikeer1 天前
Spring BOOT 启动参数
java·spring boot·后端
子木HAPPY阳VIP1 天前
Ubuntu 22.04 VMware 设置固定IP配置
人工智能·后端·目标检测·机器学习·目标跟踪
人间打气筒(Ada)1 天前
如何基于 Go-kit 开发 Web 应用:从接口层到业务层再到数据层
开发语言·后端·golang
开心就好20251 天前
使用Wireshark进行TCP数据包抓包分析:三次握手与四次挥手详解
后端·ios