首先秒紧,BeanFactory
绢陌,FactoryBean
都是Spring
中的接口。
-
BeanFactory
顧名思義熔恢,是用來(lái)管理脐湾,配置Bean
的Factory
。 -
FactoryBean
顧名思義绩聘,首先是一個(gè)Bean
沥割,為什么叫FactoryBean
耗啦,因?yàn)樗怯?code>Spring管理的凿菩,一個(gè)產(chǎn)生Bean
的Bean
,調(diào)用它真正返回的Bean
不是factoryBean
的實(shí)例帜讲,而是返回實(shí)現(xiàn)該接口的getObject()
中返回的Bean
衅谷,如果要返回該FactoryBean
實(shí)例,需要在調(diào)用的位置加上&
號(hào)似将。
首先看一下接口:
public interface FactoryBean<T> {
//通過(guò)Spring容器獲取的Bean實(shí)質(zhì)是getObject()方法返回的對(duì)象T
T getObject() throws Exception;
//返回類(lèi)型
Class<?> getObjectType();
//是否單例
boolean isSingleton();
}
舉個(gè)例子:
- 首先定義一個(gè)Bean:
package com.github.jettyrun.springinterface.demo.bean;
/**
* Created by jetty on 18/1/31.
*/
public class Car {
private String name;
private String color;
private String weight;
public void setName(String name) {
this.name = name;
}
public void setColor(String color) {
this.color = color;
}
public void setWeight(String weight) {
this.weight = weight;
}
}
- 實(shí)現(xiàn)兩種不同的FactoryBean获黔,一種單例(Singleton)蚀苛,一種多例(protoType)
package com.github.jettyrun.springinterface.demo.factorybean;
import com.github.jettyrun.springinterface.demo.bean.Car;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.stereotype.Component;
/**
* Created by jetty on 18/1/31.
*/
@Component("protoTypeCarFactoryBean")
public class ProtoTypeCarFactoryBean implements FactoryBean<Car>{
public Car getObject() throws Exception {
return new Car();
}
public Class<?> getObjectType() {
return Car.class;
}
public boolean isSingleton() {
return false;
}
}
package com.github.jettyrun.springinterface.demo.factorybean;
import com.github.jettyrun.springinterface.demo.bean.Car;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.stereotype.Component;
/**
* Created by jetty on 18/1/31.
*/
@Component("singletonCarFactoryBean")
public class SingletonCarFactoryBean implements FactoryBean<Car>{
private Car carProxy=new Car();
public Car getObject() throws Exception {
return carProxy;
}
public Class<?> getObjectType() {
return null;
}
public boolean isSingleton() {
return true;
}
}
- main方法運(yùn)行測(cè)試
package com.github.jettyrun.springinterface.demo.factorybean;
import com.github.jettyrun.springinterface.demo.bean.Car;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* Created by jetty on 18/1/31.
*/
public class Main {
public static void main(String[] args) {
ApplicationContext beans=new ClassPathXmlApplicationContext("classpath:application-usertag.xml");
Car protoTypeCar1= (Car)beans.getBean("protoTypeCarFactoryBean");
Car protoTypeCar2= (Car)beans.getBean("protoTypeCarFactoryBean");
System.out.println(""+(protoTypeCar1==protoTypeCar2)+" "+protoTypeCar1+" "+protoTypeCar2);
Car singletonCar1= (Car)beans.getBean("singletonCarFactoryBean");
Car singletonCar2= (Car)beans.getBean("singletonCarFactoryBean");
System.out.println(""+(singletonCar1==singletonCar2)+" "+singletonCar1+" "+singletonCar2);
SingletonCarFactoryBean factoryBean1=(SingletonCarFactoryBean)beans.getBean("&singletonCarFactoryBean");
SingletonCarFactoryBean factoryBean2=(SingletonCarFactoryBean)beans.getBean("&singletonCarFactoryBean");
System.out.println(""+(factoryBean1==factoryBean2)+" "+factoryBean1+" "+factoryBean2);
}
}
- 運(yùn)行結(jié)果:
false com.github.jettyrun.springinterface.demo.bean.Car@710f4d59 com.github.jettyrun.springinterface.demo.bean.Car@239f480c
true com.github.jettyrun.springinterface.demo.bean.Car@2e331e19 com.github.jettyrun.springinterface.demo.bean.Car@2e331e19
true com.github.jettyrun.springinterface.demo.factorybean.SingletonCarFactoryBean@1dfd1301 com.github.jettyrun.springinterface.demo.factorybean.SingletonCarFactoryBean@1dfd1301
我們能看到,通過(guò)Spring容器獲取protoTypeCarFactoryBean
玷氏,singletonCarFactoryBean
對(duì)象堵未,實(shí)質(zhì)返回的是該對(duì)象調(diào)用的getObject()
方法返回的對(duì)象,如果要獲取FactoryBean
的真正類(lèi)型盏触,則需要在beanId
前加上&
符號(hào)渗蟹。
BeanFactory到底又是如何使用的。
我們將上面的main方法做一下改變赞辩,將ApplicationContext改為BeanFactory雌芽。如下:
public static void main(String[] args){
Resource resource = new FileSystemResource("src/main/resources/application-usertag.xml");
BeanFactory factory = new XmlBeanFactory(resource);
Car protoTypeCar1= (Car)factory.getBean("protoTypeCarFactoryBean");
Car protoTypeCar2= (Car)factory.getBean("protoTypeCarFactoryBean");
System.out.println(""+(protoTypeCar1==protoTypeCar2)+" "+protoTypeCar1+" "+protoTypeCar2);
Car singletonCar1= (Car)factory.getBean("singletonCarFactoryBean");
Car singletonCar2= (Car)factory.getBean("singletonCarFactoryBean");
System.out.println(""+(singletonCar1==singletonCar2)+" "+singletonCar1+" "+singletonCar2);
SingletonCarFactoryBean factoryBean1=(SingletonCarFactoryBean)factory.getBean("&singletonCarFactoryBean");
SingletonCarFactoryBean factoryBean2=(SingletonCarFactoryBean)factory.getBean("&singletonCarFactoryBean");
System.out.println(""+(factoryBean1==factoryBean2)+" "+factoryBean1+" "+factoryBean2);
}
運(yùn)行結(jié)果和上面的運(yùn)行結(jié)果完全一樣。
這就表示著在Spring中辨嗽,所有的bean
都是被beanFactory
管理世落,需要獲取bean的時(shí)候,實(shí)質(zhì)是去beanFactory
中獲取糟需。applicationContext
本身是實(shí)現(xiàn)BeanFactory
接口的實(shí)現(xiàn)屉佳。
如下:
public interface ApplicationContext extends EnvironmentCapable, ListableBeanFactory, HierarchicalBeanFactory,
MessageSource, ApplicationEventPublisher, ResourcePatternResolver {
HierarchicalBeanFactory
本身是繼承BeanFactory
接口的。
也就是上面所說(shuō)的篮灼,FactoryBean
是一個(gè)為了產(chǎn)生Bean
的 Bean
忘古,而BeanFactory
是用來(lái)管理河闰,產(chǎn)生Bean
的一個(gè)Factory
睬捶。
代碼地址:https://gitee.com/shxz130/SpringInterfaceDemo/