在一般情况下,spring都是通过反射机制来获取类的class属性,从而创建bean。在某些情况下,实例化bean比较复杂,例如有多个参数的情况下,为了更加灵活,spring提供了FactoryBean接口,用户可以自定义bean的实例化策略。
FactoryBean接口中提供了三个方法
public interface FactoryBean<T> {
/**程序将会调用此
**方法来实例化bean
**/
@Nullable
T getObject() throws Exception;
/**指定bean的class
**/
@Nullable
Class<?> getObjectType();
/**是否是单例bean
**/
default boolean isSingleton() {
return true;
}
}
下面手写了一个demo展示一下
Car:
package myTest.factoryBean;
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:
package myTest.factoryBean;
import org.springframework.beans.factory.FactoryBean;
public class CarFactoryBean implements FactoryBean<Car> {
private String carInfo;
public String getCarInfo() {
return carInfo;
}
public void setCarInfo(String carInfo) {
this.carInfo = carInfo;
}
@Override
public Car getObject() throws Exception {
Car car = new Car();
String[] infos = carInfo.split(",");
car.setBrand(infos[0]);
car.setMaxSpeed(Integer.parseInt(infos[1]));
car.setPrice(Double.parseDouble(infos[2]));
return car;
}
@Override
public Class<?> getObjectType() {
return Car.class;
}
@Override
public boolean isSingleton() {
return FactoryBean.super.isSingleton();
}
}
XML配置文件:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="car" class="myTest.factoryBean.CarFactoryBean">
<property name="carInfo" value="超级跑车,400,20000000000"/>
</bean>
</beans>
运行程序
public class MyTest {
public static void main(String[] args) {
ClassPathXmlApplicationContext classPathXmlApplicationContext = new ClassPathXmlApplicationContext("configTest/springConfig.xml");
Car car = (Car) classPathXmlApplicationContext.getBean("car");
System.out.println(car.getBrand());
}
}
输出:
通过getBean("car")得到的其实是调用CarFactoryBean中的getObject方法得到的Car的Bean。如果想的到CarFactoryBean本身,需要在beanName前面加上"&",如getBean("&car")。