美文网首页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