Spring中BeanFactory和FactoryBean区别

目录

一、BeanFactory

二、FactoryBean 

三、小结


Spring学习专栏

1. Spring源码分析(一)基本框架介绍

2. Spring源码分析(二)两种方案搭建基础框架

3. Spring中@Conditional注解详细讲解及示例

4. Spring中@Import注解详细讲解及示例

5. 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对象我们早期

 使用方式:

1. 使用ClassPathXmlApplicationContext读取对应的xml文件实例对应上下文对象

 ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-config.xml");
        User user = applicationContext.getBean("user", User.class);

2.使用AnnotationConfigApplicationContext读取@Bean对应上下文对象

AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(BeanFactoryConfig.class);
Person person =  applicationContext.getBean("person", Person.class);

二、FactoryBean 

 

该类是SpringIOC容器是创建Bean的一种形式,这种方式创建Bean会有加成方式,融合了简单的工厂设计模式于装饰器模式
/*nterface 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. 创建 Person类

public class Person {

    private String userName;
    private Integer age;

    public Person() { }

    public Person(String userName, Integer age) {
        this.userName = userName;
        this.age = age;
    }

    @Override
    public String toString() {
        return "Person{" +
                "userName='" + userName + '\'' +
                ", age='" + age + '\'' +
                '}';
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public void setAge(Integer age) {
        this.age = age;
    }
}

 2. 创建 MyFactoryBean类实现FactoryBean

public class MyFactoryBean implements FactoryBean {


    private String initStr;

    public MyFactoryBean(String initStr) {
        this.initStr = initStr;
    }

    /**
     * 获取Bean返回对象
     * @date: 2021/2/26 11:35
     * @return: java.lang.Object 
     */
    public Object getObject() throws Exception {

        //这里我需要获取对应参数
        String[] split = initStr.split(",");
        Person person =new Person();
        person.setAge(Integer.parseInt(split[0]));
        person.setUserName(split[1]);
        return person;
    }

    public Class getObjectType() {
        return Person.class;
    }

    public boolean isSingleton() {
        return true;
    }

    public String getInitStr() {
        return initStr;
    }


}

 3. 创建 BeanFactoryConfig

@Configuration
public class BeanFactoryConfig {


    @Bean(name = "person")
    protected Person getBillInfo() {

        return new Person("bill", 45);
    }

    @Bean("myFactoryBean")
    protected MyFactoryBean getMyFactoryBean() {

        return new MyFactoryBean("30,init from factory");
    }

}

 4. 创建 BeanFactoryTest测试

public class BeanFactoryTest {

    private static AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(BeanFactoryConfig.class);

    @Test
    public void test1(){

        Person person =  applicationContext.getBean("person", Person.class);
        System.out.println(person);
        //获取从工厂Bean中获取对象
        Person myFactoryBean = applicationContext.getBean("myFactoryBean", Person.class);
        System.out.println(myFactoryBean);
        //获取对应的personFactory
        MyFactoryBean factoryBean = applicationContext.getBean("&myFactoryBean",MyFactoryBean.class);
        System.out.println("初始化参数为:"+factoryBean.getInitStr());

    }
}

 控制台打印结果输出

三、小结

  1.  BeanFactory:负责生产和管理Bean的一个工厂接口,提供一个Spring Ioc容器规范。
  2.  FactoryBean: 一种Bean创建的一种方式,对Bean的一种扩展。对于复杂的Bean对象初始化创建使用其可封装对象的创建细节,FactoryBean在IOC容器的基础上给Bean的实现加上了一个简单工厂模式和装饰模式(如果想了解装饰模式参考:修饰者模式(装饰者模式,Decoration) 我们可以在getObject()方法中灵活配置。

 

项目地址

https://gitee.com/gaibianzlp/spring-study-demo.git

 

参考文档

1. BeanFactory 简介以及它 和FactoryBean的区别(阿里面试)


感谢大家看到最后,如文章有不足,欢迎大家在评论区支持,给予意见。如果觉得我的文章对你有帮助,那就给我一个赞同吧。

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值