美文网首页Spring专题
Spring专题:1.FactoryBean是什么?

Spring专题:1.FactoryBean是什么?

作者: 北交吴志炜 | 来源:发表于2018-12-25 11:14 被阅读0次

我经常被“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的依赖。
(对于简单类来说,是不是也有点多此一举的感觉?没办法,总有人会提些刁钻的问题)

相关文章

网友评论

    本文标题:Spring专题:1.FactoryBean是什么?

    本文链接:https://www.haomeiwen.com/subject/sdgxlqtx.html