我经常被“FactoryBean与BeanFacory区别是什么?”这个问题搞的怀疑人生,究其原因是因为没用过FactoryBean,不理解其究竟是干什么的。
spring任何问题都先默念三遍,“一切都是bean”。
那么如果我们定义一个bean,步骤如下
<bean id="car" class="com.brianway.learning.spring.ioc.beanfactory.Car"
init-method="myInit"
destroy-method="myDestroy"
p:brand="LC 200"
p:maxSpeed="270"
scope="singleton"/>
怎么使用呢?
ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("bean.xml");
Car car = (Car) ctx.getBean("car");
这样就得到了之前定义的bean
回到正题,FactoryBean是做什么的呢,直接上代码
public class MyCarFactoryBean implements FactoryBean<Car> {
public Car getObject() throws Exception {
Car car = new Car();
car.setBrand("LC 200");
car.setMaxSpeed(270);
car.setPrice(Double.parseDouble("450000"));
return car;
}
public Class<Car> getObjectType() {
return Car.class;
}
public boolean isSingleton() {
return true;
}
}
同样,将其配置为一个bean
<bean id="myCarFactorybean" class="com.brianway.learning.spring.ioc.factorybean.MyCarFactoryBean"/>
然后使用
ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("com/brianway/learning/spring/ioc/factorybean/beans-factorybean.xml");
Car car1 = (Car) ctx.getBean("myCarFactorybean");
此时得到的是一个car对象,不是一个MyCarFactoryBean对象。
car:brand:LC 200/maxSpeed:270/price:450000.0
一切都是bean,那么我们并没有直接注册一个Car的bean,却实现了获取Car对象的效果。FactoryBean 的作用已经很清楚了,就是为了定义复杂的bean。简单的bean直接进行配置,复杂的bean配置起来太费劲了,直接配置一个FactoryBean即可。在FactoryBean实现代码中进行bean的配置。
曾经遇到过一个现在想想有些刁钻的问题,一个不受Spring管理的自定义的类,依赖一个受Spring管理的bean,如何实现注入?
其中一个方式就是,为这个不受管理的自定义类注册一个FactoryBean,在getObject方法中,实现属性的依赖。
比如我的Car类不受Spring管理,Car依赖一个Wheel的属性,Wheel是Spring管理之下的一个bean。就可以这么做
public class MyCarFactoryBean implements FactoryBean<Car> {
private Wheel wheel;
public Wheel getWheel() {
return wheel;
}
public void setWheel(Wheel wheel) {
this.wheel = wheel;
}
public Car getObject() throws Exception {
Car car = new Car();
car.setBrand("LC 200");
car.setMaxSpeed(270);
car.setPrice(Double.parseDouble("450000"));
car.setWheel(wheel);
return car;
}
public Class<Car> getObjectType() {
return Car.class;
}
public boolean isSingleton() {
return true;
}
}
配置文件这么配
<bean id="wheel" class="com.brianway.learning.spring.ioc.factorybean.Wheel"
p:maxSpeed="350"
p:size="20"
p:price="2000"
scope="singleton"/>
<bean id="myCarFactorybean" class="com.brianway.learning.spring.ioc.factorybean.MyCarFactoryBean">
<property name="wheel">
<ref bean="wheel"/>
</property>
不受Spring管理的Car类,去注册一个FactoryBean,就实现了对其他受Spring管理的bean的依赖。
(对于简单类来说,是不是也有点多此一举的感觉?没办法,总有人会提些刁钻的问题)
网友评论