【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);
    }
 
}
相关推荐
raoxiaoya25 分钟前
同时安装多个版本的golang
开发语言·后端·golang
考虑考虑2 小时前
go使用gorilla/websocket实现websocket
后端·程序员·go
李少兄2 小时前
解决Spring Boot多模块自动配置失效问题
java·spring boot·后端
Piper蛋窝3 小时前
Go 1.19 相比 Go 1.18 有哪些值得注意的改动?
后端
码农BookSea3 小时前
不用Mockito写单元测试?你可能在浪费一半时间
后端·单元测试
codingandsleeping4 小时前
Express入门
javascript·后端·node.js
ss2735 小时前
基于Springboot + vue + 爬虫实现的高考志愿智能推荐系统
spring boot·后端·高考
专注API从业者5 小时前
《Go 语言高并发爬虫开发:淘宝商品 API 实时采集与 ETL 数据处理管道》
开发语言·后端·爬虫·golang
Asthenia04125 小时前
Netty writeAndFlush与Pipeline深入分析
后端
欧先生^_^6 小时前
Scala语法基础
开发语言·后端·scala