0


BeanFactory和FactoryBean的区别

区别:

https://liayun.blog.csdn.net/article/details/110391066
BeanFactory是个Factory,也就是IOC容器或对象工厂,
而FactoryBean就是个Bean。在Spring中,所有的Bean都是由BeanFactory(也就是IOC容器)来进行管理的。

但对FactoryBean而言,这个Bean不是简单的Bean,FactoryBean是一个能生产或者修饰对象生成的工厂Bean,它的实现与设计模式中的工厂模式和修饰器模式类似。

FactoryBean 的源码分析;
在这里插入图片描述

FactoryBean概述

一般情况下,Spring是通过反射机制利用bean的class属性指定实现类来实例化bean的。在某些情况下,实例化bean过程比较复杂,如果按照传统的方式,那么则需要在标签中提供大量的配置信息,配置方式的灵活性是受限的,这时采用编码的方式可以得到一个更加简单的方案。Spring为此提供了一个org.springframework.bean.factory.FactoryBean的工厂类接口,用户可以通过实现该接口定制实例化bean的逻辑。

FactoryBean接口对于Spring框架来说占有非常重要的地位,Spring自身就提供了70多个FactoryBean接口的实现。它们隐藏了实例化一些复杂bean的细节,给上层应用带来了便利。从Spring 3.0开始,FactoryBean开始支持泛型,即接口声明改为FactoryBean的形式。
在这里插入图片描述

当配置文件中标签的class属性配置的实现类是FactoryBean时,通过 getBean()方法返回的不是FactoryBean本身,而是FactoryBean#getObject()方法所返回的对象,相当于FactoryBean#getObject()代理了getBean()方法。

FactoryBean案例

首先,创建一个ColorFactoryBean类,它得实现FactoryBean接口,如下所示。

packagecom.meimeixia.bean;importorg.springframework.beans.factory.FactoryBean;/**
 * 创建一个Spring定义的FactoryBean
 * T(泛型):指定我们要创建什么类型的对象
 * @author liayun
 * 
 */publicclassColorFactoryBeanimplementsFactoryBean<Color>{// 返回一个Color对象,这个对象会添加到容器中@OverridepublicColorgetObject()throwsException{// TODO Auto-generated method stubSystem.out.println("ColorFactoryBean...getObject...");returnnewColor();}@OverridepublicClass<?>getObjectType(){// TODO Auto-generated method stubreturnColor.class;// 返回这个对象的类型}// 是单例吗?// 如果返回true,那么代表这个bean是单实例,在容器中只会保存一份;// 如果返回false,那么代表这个bean是多实例,每次获取都会创建一个新的bean@OverridepublicbooleanisSingleton(){// TODO Auto-generated method stubreturnfalse;}}

然后,我们在MainConfig2配置类中加入ColorFactoryBean的声明,如下所示。

packagecom.meimeixia.config;importorg.springframework.context.annotation.Bean;importorg.springframework.context.annotation.Conditional;importorg.springframework.context.annotation.Configuration;importorg.springframework.context.annotation.Import;importorg.springframework.context.annotation.Lazy;importcom.meimeixia.bean.Color;importcom.meimeixia.bean.ColorFactoryBean;importcom.meimeixia.bean.Person;importcom.meimeixia.bean.Red;importcom.meimeixia.condition.LinuxCondition;importcom.meimeixia.condition.MyImportBeanDefinitionRegistrar;importcom.meimeixia.condition.MyImportSelector;importcom.meimeixia.condition.WindowsCondition;// 对配置类中的组件进行统一设置@Conditional({WindowsCondition.class})// 满足当前条件,这个类中配置的所有bean注册才能生效@Configuration@Import({Color.class,Red.class,MyImportSelector.class,MyImportBeanDefinitionRegistrar.class})// @Import快速地导入组件,id默认是组件的全类名publicclassMainConfig2{@Lazy@Bean("person")publicPersonperson(){System.out.println("给容器中添加咱们这个Person对象...");returnnewPerson("美美侠",25);}@Bean("bill")publicPersonperson01(){returnnewPerson("Bill Gates",62);}@Conditional({LinuxCondition.class})@Bean("linus")publicPersonperson02(){returnnewPerson("linus",48);}@BeanpublicColorFactoryBeancolorFactoryBean(){returnnewColorFactoryBean();}}

这里需要小伙伴们注意的是:我在这里使用@Bean注解向Spring容器中注册的是ColorFactoryBean对象。

那现在我们就来看看Spring容器中到底都有哪些bean。我们所要做的事情就是,运行IOCTest类中的testImport()方法,此时,输出的结果信息如下所示。
在这里插入图片描述
可以看到,结果信息中输出了一个colorFactoryBean,我们看下这个colorFactoryBean到底是个什么鬼!此时,我们对IOCTest类中的testImport()方法稍加改动,添加获取colorFactoryBean的代码,并输出colorFactoryBean实例的类型,如下所示。

@TestpublicvoidtestImport(){AnnotationConfigApplicationContext applicationContext =newAnnotationConfigApplicationContext(MainConfig2.class);String[] definitionNames = applicationContext.getBeanDefinitionNames();for(String name : definitionNames){System.out.println(name);}// 工厂bean获取的是调用getObject方法创建的对象Object bean2 = applicationContext.getBean("colorFactoryBean");System.out.println("bean的类型:"+ bean2.getClass());}

再次运行IOCTest类中的testImport()方法,发现输出的结果信息如下所示。
在这里插入图片描述
可以看到,虽然我在代码中使用@Bean注解注入的是ColorFactoryBean对象,但是实际上从Spring容器中获取到的bean对象却是调用ColorFactoryBean类中的getObject()方法获取到的Color对象。

如何在Spring容器中获取到FactoryBean对象本身呢?
在这里插入图片描述

看到这里,是不是明白了呢?没错,在BeanFactory接口中定义了一个&前缀,只要我们使用bean的id来从Spring容器中获取bean时,Spring就会知道我们是在获取FactoryBean本身。

BeanFactory概述

1、简单介绍

这个其实是所有Spring Bean的容器根接口,给Spring 的容器定义一套规范,给IOC容器提供了一套完整的规范,比如我们常用到的getBean方法等。

进入到这个类,我们可以看到如下注释,意思是:访问Spring bean容器的根接口。
在这里插入图片描述

2、定义方法

  • 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所对应的所有的别名。

3、主要实现类(包括抽象类)

  • AbstractBeanFactory:抽象Bean工厂,绝大部分的实现类,都是继承于它。
  • DefaultListableBeanFactory:Spring默认的工厂类。
  • XmlBeanFactory:前期使用XML配置用的比较多的时候用的Bean工厂。
  • AbstractXmlApplicationContext:抽象应用容器上下文对象。
  • ClassPathXmlApplicationContext:XML解析上下文对象,用户创建Bean对象我们早期写Spring的时候用的就是它。#FFFFE4

4、使用方式

BeanFactory的使用方式有很多,这里就不一一列举了,具体请查看源码。

举一个简单的例子,使用ClassPathXmlApplicationContext读取对应的xml文件实例对应上下文对象:

ApplicationContext context =newClassPathXmlApplicationContext(newString[]{"applicationContext.xml"});BeanFactory factory =(BeanFactory) context;
标签: spring java 后端

本文转载自: https://blog.csdn.net/weixin_45723046/article/details/124546156
版权归原作者 Been Doing 所有, 如有侵权,请联系我们删除。

“BeanFactory和FactoryBean的区别”的评论:

还没有评论