Spring中的beanFactory和FactoryBean
2018-01-31 本文已影响106人
一滴水的坚持
首先,BeanFactory,FactoryBean都是Spring中的接口。
-
BeanFactory顾名思义,是用来管理,配置Bean的Factory。 -
FactoryBean顾名思义,首先是一个Bean,为什么叫FactoryBean,因为它是由Spring管理的,一个产生Bean的Bean,调用它真正返回的Bean不是factoryBean的实例,而是返回实现该接口的getObject()中返回的Bean,如果要返回该FactoryBean实例,需要在调用的位置加上&号。
首先看一下接口:
public interface FactoryBean<T> {
//通过Spring容器获取的Bean实质是getObject()方法返回的对象T
T getObject() throws Exception;
//返回类型
Class<?> getObjectType();
//是否单例
boolean isSingleton();
}
举个例子:
- 首先定义一个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;
}
}
- 实现两种不同的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方法运行测试
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);
}
}
- 运行结果:
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
我们能看到,通过Spring容器获取protoTypeCarFactoryBean,singletonCarFactoryBean对象,实质返回的是该对象调用的getObject()方法返回的对象,如果要获取FactoryBean的真正类型,则需要在beanId前加上&符号。
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);
}
运行结果和上面的运行结果完全一样。
这就表示着在Spring中,所有的bean都是被beanFactory管理,需要获取bean的时候,实质是去beanFactory中获取。applicationContext本身是实现BeanFactory接口的实现。
如下:
public interface ApplicationContext extends EnvironmentCapable, ListableBeanFactory, HierarchicalBeanFactory,
MessageSource, ApplicationEventPublisher, ResourcePatternResolver {
HierarchicalBeanFactory本身是继承BeanFactory接口的。
也就是上面所说的,FactoryBean是一个为了产生Bean的 Bean,而BeanFactory是用来管理,产生Bean的一个Factory。
代码地址:https://gitee.com/shxz130/SpringInterfaceDemo/