一文讀懂BeanFactory和FactoryBean區別
阿新 • • 發佈:2020-08-24
>一直以來,很多人對於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