BeanFactory 和 FactoryBean 的理解

大家好,我是本周的值班编辑 江南一点雨 ,本周将由我为大家排版并送出技术干货,大家可以在公众号后台回复“springboot”,获取最新版 Spring Boot2.1.6 视频教程试看。



我们或多或少都会经历过若干个面试,而每每问到 Spring 的时候都少不了IOC容器的影子,那么这个 IOC 容器是什么呢? 本篇文章就来了解一下 BeanFactory 和 FactoryBean

BeanFactory 是什么

BeanFactory 是用于Spring Bean 容器的根接口,它是 IOC 的基本容器,负责管理和加载 Bean,它为其他具体的IOC容器提供了最基本的规范,比如 DefaultListableBeanFactoryConfigurableBeanFactory,BeanFactory 也提供了用于读取 XML 配置文件的实现,比如 XMLBeanFactory

ApplicationContext 接口是 BeanFactory 的扩展,它除了具备 BeanFactory 接口所拥有的全部功能外,还有应用程序上下文的一层含义,主要包括

  • 继承自 ListableBeanFactory 接口,可以访问 Bean 工厂上下文的组件

  • 继承自 ResourceLoader 接口,以通用的方式加载文件资源

  • 继承自 ApplicationContextPublisher 接口,拥有发布事件注册监听的能力

  • 继承自 MessageSource 接口,解析消息支持国际化

它最主要的实现就是 ClassPathXmlApplicationContext,用来读取XML 配置文件,现在我们用的更多的是 ClassPathXmlApplicationContext 而不是 XMLBeanFactory 了。

BeanFactory 的基本使用

上面了解了一下 BeanFactory 的基本概念之后,下面来介绍一下 BeanFactory 的基本使用

新建一个Maven 项目,配置基本的 Spring 依赖,新建一个简单的测试Bean —> HelloBean

HelloBean.java

 
 
  1. public class HelloBean {

  2. private String message;

  3. get and set...

  4. public void printMsg(){

  5. System.out.println("message = " + message);

  6. }

  7. }

在 /resources 目录下新建一个 spring-beans.xml 配置文件,用来配置一下上面这个简单的bean

 
 
  1. <?xml version="1.0" encoding="UTF-8"?>

  2. <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd" >

  3. <beans>

  4. <bean id="helloBean" class="com.factory.bean.HelloBean">

  5. <property name="message">

  6. <value>Hello Beans</value>

  7. </property>

  8. </bean>

  9. </beans>

新建一个测试类测试一下这个demo

 
 
  1. public class FactoryBeanApplicationTests {

  2. public static void main(String[] args) {

  3. // BeanFactory beanFactory = new XmlBeanFactory(new FileSystemResource("/Users/mr.l/test/spring-beans.xml"));

  4. ApplicationContext beanFactory = new ClassPathXmlApplicationContext("spring-beans.xml");

  5. HelloBean helloBean = (HelloBean) beanFactory.getBean("helloBean");

  6. helloBean.printMsg();

  7. }

  8. }

一些其他的表现形式:

 
 
  1. Resource resource = new FileSystemResource("spring-beans.xml");

  2. BeanFactory factory = new XmlBeanFactory(resource);

  3. ApplicationContext context = new ClassPathXmlApplicationContext(new String[] {"applicationContext.xml", "applicationContext-part2.xml"});

  4. BeanFactory factory = (BeanFactory) context;

现在更多的采用 ClassPathXmlApplicationContext 路径上下文读取XML配置文件,XmlBeanFactory 已经被废弃。

FactoryBean 是什么

FactoryBean 是一个接口,它本身就是一个对象工厂,如果bean 实现了这个接口,它被用作公开的对象工厂,而不是作为直接将bean暴露的实例。该接口在框架内部大量使用,例如 AOP ProxyFactoryBean 或者 JndiObjectFactoryBean。 也能自定义组件;然而,这仅适用于基础框架代码。FactoryBeans 支持单例或多例,并且可以根据需要懒加载创建对象,也可以在启动时 急切创建对象

我们先来看一下 FactoryBean 的基本接口表示

 
 
  1. public interface FactoryBean<T> {

  2. @Nullable

  3. T getObject() throws Exception;

  4. @Nullable

  5. Class<?> getObjectType();

  6. default boolean isSingleton() {

  7. return true;

  8. }

  9. }

接口很简单,只有三个方法,我们来讨论一下上面几个方法分别代表了什么意思:

  • getObject: 返回一个工厂生产出来的对象,这个对象将要使用在Spring IOC 容器中

  • getObjectType : 顾名思义就是返回工厂生产出来对象的类型

  • isSingleton: 表示生产出来的对象是否是单例的

FactoryBean 的基本使用

下面我们来用一个简单的示例演示一下 FactoryBean 的用法

  • 先构建一个普通的pojo类,只有一个简单的属性

 
 
  1. public class Tool {

  2. private int id;

  3. public Tool(int id){

  4. this.id = id;

  5. }

  6. get and set...

  7. }

  • 构建一个 ToolFactory 类,实现了 FactoryBean 接口,用于生产 Tool 的对象

 
 
  1. public class ToolFactory implements FactoryBean<Tool> {

  2. private int factoryId;

  3. private int toolId;

  4. @Override

  5. public Tool getObject() throws Exception {

  6. return new Tool(toolId);

  7. }

  8. @Override

  9. public Class<?> getObjectType() {

  10. return Tool.class;

  11. }

  12. @Override

  13. public boolean isSingleton() {

  14. return false;

  15. }

  16. get and set...

  17. }

  • 在 /resources 目录下新建一个 factorybean-spring.xml ,用于给 ToolFactory 赋值

 
 
  1. <beans>

  2. <bean id="tool" class="com.factory.bean.util.ToolFactory">

  3. <property name="factoryId" value="9090" />

  4. <property name="toolId" value="1"/>

  5. </bean>

  6. </beans>

  • 新建一个测试类 FactoryXmlTest 测试 FactoryBean 生产的实例

 
 
  1. @RunWith(SpringJUnit4ClassRunner.class)

  2. @ContextConfiguration(locations = "classpath:factorybean-spring.xml")

  3. public class FactoryXmlTest {

  4. // 使用 & 读取xml 中的配置值

  5. @Resource(name = "&tool")

  6. private ToolFactory toolFactory;

  7. @Test

  8. public void testFactory(){

  9. System.out.println(toolFactory.getFactoryId());

  10. System.out.println(toolFactory.getObjectType());

  11. System.out.println(toolFactory.getToolId());

  12. }

  13. }

输出:

9090 class com.factory.bean.pojo.Tool 1



往期精彩回顾:

浅谈Java中字符串的初始化及字符串操作类

MyBatis 核心配置综述之 ParameterHandlers

spring 注解编程之注解属性别名与覆盖

分布式下必备神器之分布式锁


640?wx_fmt=jpeg

于加入知识星球的同学提供基本的福利:

文章有疑问的地方可以提问,其他工作问题都可以提问出来,作者免费作答。

 https://t.zsxq.com/Y3fYny7


每周都有大牛分享一些面试题,和面试注意的知识点!

 https://t.zsxq.com/2bufE2v


每周由Java极客技术独家编制的设计模式与大家分享!

 https://t.zsxq.com/3bUNbEI


每两周还会分享一个话题,和大家一起成长!

 https://t.zsxq.com/BI6Unm2


还有Java极客技术团队亲自录制了一套 Spring Boot 视频,这套视频加密,加密后放到云盘上,下载链接加密之后,一机一码,每个星球的用户一个播放授权码。

 

我们做知识星球的目的和其他星主一样,就是为了帮助大家一起更好的成长,与高手拉近距离,减少差距,其实你也是高手!

640?wx_fmt=png 640?wx_fmt=jpeg 640?wx_fmt=jpeg 640?wx_fmt=jpeg 640?wx_fmt=jpeg

1000人,50元/每年,现在大约还剩不到300个名额。

长按二维码

640?wx_fmt=png


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值