1、FactoryBean和BeanFactory的區(qū)別
BeanFactory,就是bean的工廠急鳄,主要是通過定位、加載乐导、注冊以及實(shí)例化來維護(hù)對象與對象之間的依賴關(guān)系典阵,以此來管理bean
FactoryBean奋渔,bean的一種,顧名思義壮啊,它也可以用來生產(chǎn)bean嫉鲸,也實(shí)現(xiàn)了相應(yīng)的工廠方法。
一般來說歹啼,Bean是由BeanFactory生產(chǎn)玄渗,但FactoryBean的特殊之處就在于它也能生產(chǎn)bean。
獲取FactoryBean的方法是getBean("&"+beanName);
就是在beanName加個(gè)"&"前綴狸眼,若直接getBean(beanName),獲取到的是FactoryBean通過getObject接口生成的Bean藤树。見代碼:
Car
public class Car {
private int maxSpeed;
private String brand;
private double price;
public int getMaxSpeed() {
return maxSpeed;
}
public void setMaxSpeed(int maxSpeed) {
this.maxSpeed = maxSpeed;
}
public String getBrand() {
return brand;
}
public void setBrand(String brand) {
this.brand = brand;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
}
CarFactoryBean:
public class CarFactoryBean implements FactoryBean<Car> {
private String carInfo;
@Override
public Car getObject() throws Exception {
Car car = new Car () ;
String [] infos = carInfo .split ( "," ) ;
car.setBrand ( infos [ 0 ]) ;
car.setMaxSpeed ( Integer.valueOf ( infos [ 1 ])) ;
car.setPrice ( Double.valueOf ( infos [ 2 ])) ;
return car;
}
@Override
public Class<?> getObjectType() {
return Car.class;
}
@Override
public boolean isSingleton() {
return false;
}
public String getCarInfo() {
return carInfo;
}
public void setCarInfo(String carInfo) {
this.carInfo = carInfo;
}
}
bean配置:
<bean id="car" class="com.wl.service.factorybean.CarFactoryBean" >
<property name="carInfo" value="超級跑車,200,20000000"/>
</bean>
測試:
ApplicationContext context = new ClassPathXmlApplicationContext("classpath*:applicationContext.xml");
Object car = context.getBean("car");
Object carFactoryBean = context.getBean("&car");
System.out.println(car);
System.out.println(carFactoryBean);
結(jié)果為:
com.wl.service.factorybean.Car@13805618
com.wl.service.factorybean.CarFactoryBean@56ef9176
經(jīng)過上面的測試可以知道,通過“&”前綴可以獲取到FactoryBean拓萌,不加前綴獲取到的則是普通的bean岁钓。
2、factoryBean的源碼走讀
public interface FactoryBean<T> {
@Nullable
T getObject() throws Exception;
@Nullable
Class<?> getObjectType();
default boolean isSingleton() {
return true;
}
}
實(shí)現(xiàn)該接口的類需要實(shí)現(xiàn)以上的方法微王,其中g(shù)etObject就是用來生產(chǎn)bean的方法屡限。
通過AbstractBeanFactory.doGetBean可以知道,不論是單例還是原型的實(shí)例對象炕倘,最終都要通過getObjectForBeanInstance進(jìn)行轉(zhuǎn)換钧大,最終得到的才是符合要求的bean實(shí)例。如:
// Create bean instance.
//單例的處理
//首先創(chuàng)建beanFactory,即ObjectBeanFacotry并實(shí)現(xiàn)getObject接口
if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, () -> {
try {
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
// Explicitly remove instance from singleton cache: It might have been put there
// eagerly by the creation process, to allow for circular reference resolution.
// Also remove any beans that received a temporary reference to the bean.
destroySingleton(beanName);
throw ex;
}
});
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
進(jìn)入到getObjectForBeanInstance
protected Object getObjectForBeanInstance(
Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {
//進(jìn)行類型檢測罩旋,如果是&作為前綴拓型,但是傳入beanInstance不是FactoryBean類型的,則拋出異常
if (BeanFactoryUtils.isFactoryDereference(name)) {
if (beanInstance instanceof NullBean) {
return beanInstance;
}
if (!(beanInstance instanceof FactoryBean)) {
throw new BeanIsNotAFactoryException(transformedBeanName(name), beanInstance.getClass());
}
}
// Now we have the bean instance, which may be a normal bean or a FactoryBean.
// If it's a FactoryBean, we use it to create a bean instance, unless the
// caller actually wants a reference to the factory.
//如果是非FactoryBean或者是&作為前綴的前綴瘸恼,則返回實(shí)例對象劣挫,無需轉(zhuǎn)換
if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) {
return beanInstance;
}
//需要轉(zhuǎn)換,說明輸入的name獲取的bean是需要調(diào)用FactoryBean的getObject
//也就是說东帅,beanInstance是FactoryBean類型压固,同時(shí)name不是以&作為前綴
//舉個(gè)例子:
//<bean id="car" class="com.wl.service.factorybean.CarFactoryBean" >
// <property name="carInfo" value="超級跑車,200,20000000"/>
//</bean>
//這里輸入getBean("car"),首先beanInstance為CarFactoryBean,則需要通過CarFactoryBean.getObject進(jìn)行轉(zhuǎn)換
Object object = null;
if (mbd == null) {
//先到FactoryBean生產(chǎn)bean對象的緩存中去取靠闭,如果沒有的話則用factorybean去生產(chǎn)一個(gè)
object = getCachedObjectForFactoryBean(beanName);
}
if (object == null) {
// Return bean instance from factory.
FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
// Caches object obtained from FactoryBean if it is a singleton.
if (mbd == null && containsBeanDefinition(beanName)) {
mbd = getMergedLocalBeanDefinition(beanName);
}
boolean synthetic = (mbd != null && mbd.isSynthetic());
//通過factoryBean去生產(chǎn)bean
object = getObjectFromFactoryBean(factory, beanName, !synthetic);
}
return object;
}
通過這個(gè)方法我們可以得出以下幾點(diǎn):
1)getObjectForBeanInstance這個(gè)方法通過輸入的beanInstance的有這么幾種情況:
beanInstance | name | getBean |
---|---|---|
instance of FactoryBean為true | 非“&”前綴 | 拋出異常 |
instance of FactoryBean為false | 非“&”前綴 | 返回beanInstance |
instance of FactoryBean為true | “&”前綴 | 返回beanInstance同時(shí)也是FactoryBean |
instance of FactoryBean為true | 非“&”前綴 | 先通過getCachedObjectForFactoryBean去緩存取該對象帐我,如果沒有表示第一次獲取,通過FactoryBean生成 |
3愧膀、factoryBean的源碼深入走讀
首先拦键,假如現(xiàn)在要獲取的是FactoryBean生成的bean實(shí)例,那么首先檩淋,會(huì)去緩存中取這個(gè)bean
Object object = null;
if (mbd == null) {
//先到FactoryBean生產(chǎn)bean對象的緩存中去取芬为,如果沒有的話則用factorybean去生產(chǎn)一個(gè)
object = getCachedObjectForFactoryBean(beanName);
}
進(jìn)入到getCachedObjectForFactoryBean萄金,是FactoryBeanRegistrySupport的方法
/** Cache of singleton objects created by FactoryBeans: FactoryBean name --> object */
/** 由factoryBean生成的單例bean都會(huì)緩存到factoryBeanObjectCache*/
private final Map<String, Object> factoryBeanObjectCache = new ConcurrentHashMap<>(16);
protected Object getCachedObjectForFactoryBean(String beanName) {
return this.factoryBeanObjectCache.get(beanName);
}
假如獲取不到,則生成對應(yīng)的FactoryBean媚朦,然后通過FactoryBean去生成
if (object == null) {
//獲取對應(yīng)的FactoryBean
FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
//......省略
//通過factoryBean去生產(chǎn)bean
object = getObjectFromFactoryBean(factory, beanName, !synthetic);
}
進(jìn)入到getObjectFromFactoryBean,是FactoryBeanRegistrySupport的方法
protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess) {
//針對單例的處理
if (factory.isSingleton() && containsSingleton(beanName)) {
synchronized (getSingletonMutex()) {
Object object = this.factoryBeanObjectCache.get(beanName);
if (object == null) {
//通過factory.getObject獲取
object = doGetObjectFromFactoryBean(factory, beanName);
// Only post-process and store if not put there already during getObject() call above
// (e.g. because of circular reference processing triggered by custom getBean calls)
Object alreadyThere = this.factoryBeanObjectCache.get(beanName);
if (alreadyThere != null) {
object = alreadyThere;
}
else {
if (shouldPostProcess) {
if (isSingletonCurrentlyInCreation(beanName)) {
// Temporarily return non-post-processed object, not storing it yet..
return object;
}
beforeSingletonCreation(beanName);
try {
object = postProcessObjectFromFactoryBean(object, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(beanName,
"Post-processing of FactoryBean's singleton object failed", ex);
}
finally {
afterSingletonCreation(beanName);
}
}
if (containsSingleton(beanName)) {
//將獲取到的對象放到factoryBeanObjectCache單例緩存map進(jìn)行存儲(chǔ)
this.factoryBeanObjectCache.put(beanName, object);
}
}
}
return object;
}
}
else {
//非單例的處理氧敢,直接通過factory.getObejct獲取,然后再返回給用戶
Object object = doGetObjectFromFactoryBean(factory, beanName);
if (shouldPostProcess) {
try {
object = postProcessObjectFromFactoryBean(object, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(beanName, "Post-processing of FactoryBean's object failed", ex);
}
}
return object;
}
}
無論是單例和非單例询张,都會(huì)調(diào)用doGetObjectFromFactoryBean方法孙乖,看來此方法,就是生成bean對象的方法:
private Object doGetObjectFromFactoryBean(final FactoryBean<?> factory, final String beanName)
throws BeanCreationException {
Object object;
try {
if (System.getSecurityManager() != null) {
AccessControlContext acc = getAccessControlContext();
try {
object = AccessController.doPrivileged((PrivilegedExceptionAction<Object>) factory::getObject, acc);
}
catch (PrivilegedActionException pae) {
throw pae.getException();
}
}
else {
object = factory.getObject();//生成對象
}
}
catch (FactoryBeanNotInitializedException ex) {
throw new BeanCurrentlyInCreationException(beanName, ex.toString());
}
catch (Throwable ex) {
throw new BeanCreationException(beanName, "FactoryBean threw exception on object creation", ex);
}
// Do not accept a null value for a FactoryBean that's not fully
// initialized yet: Many FactoryBeans just return null then.
if (object == null) {
if (isSingletonCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(
beanName, "FactoryBean which is currently in creation returned null from getObject");
}
object = new NullBean();
}
return object;
}
至此份氧,針對FactoryBean的解析就到此結(jié)束唯袄。