1. 程式人生 > >一文讀懂BeanFactory和FactoryBean區別

一文讀懂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的時候用的就是他 ![](https://img2020.cnblogs.com/blog/917948/202008/917948-20200823205948024-1600725213.png) ## 使用方式: 1. 使用`ClassPathXmlApplicationContext`讀取對應的xml檔案例項對應上下文物件 ```java 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 ```xml
``` personFactoryBean.java ```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方法 ```java 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物件初始化建立使用其可封裝物件的建立細節。 程式碼:[GitHub地址](https://github.com/lonecloud/blog-example/tree/master/framework-example/spring-example/src/main/java/cn/lonecloud/spring/example/f