一文读懂BeanFactory和FactoryBean区别

一直以来,很多人对于Spring中的BeanFactory和FactoryBean都是分不清楚的
BeanFactory 这个其实是所有Spring Bean的容器根接口,给Spring 的容器定义一套规范,给IOC容器提供了一套完整的规范,比如我们常用到的getBean方法等
The root interface for accessing a Spring bean container. This is the basic client view of a bean container;
定义方法:
  • getBean(String name): Spring容器中获取对应Bean对象的方法,如存在,则返回该对象
  • containsBean(String name):Spring容器中是否存在该对象
  • isSingleton(String name):通过beanName是否为单例对象
  • isPrototype(String name):判断bean对象是否为多例对象
  • isTypeMatch(String name, ResolvableType typeToMatch):判断name值获取出来的bean与typeToMath是否匹配
  • getType(String name):获取Bean的Class类型
  • getAliases(String name):获取name所对应的所有的别名
主要的实现类(包括抽象类):
  • AbstractBeanFactory:抽象Bean工厂,绝大部分的实现类,都是继承于他
  • DefaultListableBeanFactory:Spring默认的工厂类
  • XmlBeanFactory:前期使用XML配置用的比较多的时候用的Bean工厂
  • AbstractXmlApplicationContext:抽象应用容器上下文对象
  • ClassPathXmlApplicationContext:XML解析上下文对象,用户创建Bean对象我们早期写Spring的时候用的就是他
一文读懂BeanFactory和FactoryBean区别
文章图片

使用方式:
  1. 使用ClassPathXmlApplicationContext读取对应的xml文件实例对应上下文对象
ApplicationContext context = new ClassPathXmlApplicationContext(new String[] {"applicationContext.xml"}); BeanFactory factory = (BeanFactory) context;

FactoryBean
该类是SpringIOC容器是创建Bean的一种形式,这种方式创建Bean会有加成方式,融合了简单的工厂设计模式于装饰器模式
* Interface to be implemented by objects used within a {@link BeanFactory} which * are themselves factories for individual objects. If a bean implements this * interface, it is used as a factory for an object to expose, not directly as a * bean instance that will be exposed itself.

有些人就要问了,我直接使用Spring默认方式创建Bean不香么,为啥还要用FactoryBean做啥,在某些情况下,对于实例Bean对象比较复杂的情况下,使用传统方式创建bean会比较复杂,例如(使用xml配置),这样就出现了FactoryBean接口,可以让用户通过实现该接口来自定义该Bean接口的实例化过程。即包装一层,将复杂的初始化过程包装,让调用者无需关系具体实现细节。
方法:
  • T getObject():返回实例
  • Class getObjectType(); :返回该装饰对象的Bean的类型
  • default boolean isSingleton():Bean是否为单例
常用类
  • ProxyFactoryBean :Aop代理Bean
  • GsonFactoryBean:Gson
使用
  1. Spring XML方式
application.xml

personFactoryBean.java
package cn.lonecloud.spring.example.bean; import cn.lonecloud.spring.example.bo.Person; import org.springframework.beans.factory.FactoryBean; import java.util.Objects; /** * TODO * * @author lonecloud * @date 2020/8/4 23:39 * @since v1.0 */ public class PersonFactoryBean implements FactoryBean {/** * 初始化Str */ private String initStr; @Override public Person getObject() throws Exception { //这里我需要获取对应参数 Objects.requireNonNull(initStr); String[] split = initStr.split(","); Person p=new Person(); p.setAge(Integer.parseInt(split[0])); p.setName(split[1]); //这里可能需要还要有其他复杂事情需要处理 return p; }@Override public Class getObjectType() { return Person.class; }public String getInitStr() { return initStr; }public void setInitStr(String initStr) { this.initStr = initStr; } }

main方法
package cn.lonecloud.spring.example.factory; import cn.lonecloud.spring.example.bo.Person; import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.FactoryBean; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; /** * BeanFactory 例子 * * @author lonecloud * @date 2020/8/4 23:32 * @since v1.0 */ public class SpringBeanFactoryMain {public static void main(String[] args) { //这个是BeanFactory BeanFactory beanFactory = new ClassPathXmlApplicationContext("application.xml"); //获取对应的对象化 Object demo = beanFactory.getBean("demo"); System.out.println(demo instanceof Person); System.out.println(demo); //获取从工厂Bean中获取对象 Person demoFromFactory = beanFactory.getBean("demoFromFactory", Person.class); System.out.println(demoFromFactory); //获取对应的personFactory Object bean = beanFactory.getBean("&demoFromFactory"); System.out.println(bean instanceof PersonFactoryBean); PersonFactoryBean factoryBean=(PersonFactoryBean) bean; System.out.println("初始化参数为:"+factoryBean.getInitStr()); } }

输出
true Person{name='xiaoMing', age=10} Person{name='init from factory', age=10} true 初始化参数为:10,init from factory

区别
  1. BeanFactory:负责生产和管理Bean的一个工厂接口,提供一个Spring Ioc容器规范,
  2. FactoryBean: 一种Bean创建的一种方式,对Bean的一种扩展。对于复杂的Bean对象初始化创建使用其可封装对象的创建细节。
【一文读懂BeanFactory和FactoryBean区别】代码:GitHub地址

    推荐阅读