FactoryBean的使用

65 阅读1分钟

在一般情况下,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());
    }
}

输出:

image.png
通过getBean("car")得到的其实是调用CarFactoryBean中的getObject方法得到的Car的Bean。如果想的到CarFactoryBean本身,需要在beanName前面加上"&",如getBean("&car")。