• (II)第五节:工厂方式创建 bean


    一、静态工厂创建 bean

      当我们创建一个复杂对象的时候,可以利用工厂模式来创建 bean 对象。

    工厂模式:工厂帮我们创建对象,有一个专门帮我们创建对象的类,这个类就是工厂
    静态工厂:工厂本身不用创建,通过静态方法调用:对象 = 工厂类.工厂方法名()
    实例工厂:工厂本身需要创建对象
    工厂类 工厂对象 = new 工厂类();
    工厂对象.getAirPlane("");

      有这样一个复杂的类 AirPlane:

    public class AirPlane {
    
        private String model; //型号
        private String wing; //机翼
        private Integer personNum; //载客量
        private String captain;   //机长
        // 省略 getter/setter 构造器
    }

      为其创建静态工厂:

    /**
     * 静态工厂
     */
    public class AirPlaneStaticFactory {
    
        public static AirPlane getAirPlane(String captain) {
            System.out.println("AirPlaneStaticFactory正在造飞机。。。");
            AirPlane airPlane = new AirPlane();
            airPlane.setModel("太行");
            airPlane.setPersonNum(300);
            airPlane.setWing("50M");
            airPlane.setCaptain(captain);
            return airPlane;
        }
    }

      把静态工厂配置在容器中:

        <!--  1、静态工厂(不需要创建工厂本身)
                class:指定静态工厂全类名
                factory-method="getAirPlane" 指定哪个方法是工厂方法
                constructor-arg 可以为方法传参
        -->
        <bean id="airPlane01" class="com.njf.spring.factory.AirPlaneStaticFactory" factory-method="getAirPlane">
            <!--为静态方法指定参数-->
            <constructor-arg name="captain" value="刘哲"></constructor-arg>
        </bean>

        测试:

        @Test
        public void test5() {
            ApplicationContext ioc = new ClassPathXmlApplicationContext("ioc3.xml");
    
            AirPlane airPlane01 = (AirPlane) ioc.getBean("airPlane01");
            System.out.println("airPlane01 = " + airPlane01);
        }

        虽然在配置文件中配置的静态工厂,但会帮我们调用工厂方法创建对象。

    二、实例工厂创建 bean

      创建一个飞机的实例工厂:

    public class AirPlaneInstatceFactory {
    
        public AirPlane getAirPlane(String captain) {
            System.out.println("AirPlaneInstatceFactory正在造飞机。。。");
            AirPlane airPlane = new AirPlane();
            airPlane.setModel("太行");
            airPlane.setPersonNum(300);
            airPlane.setWing("50M");
            airPlane.setCaptain(captain);
            return airPlane;
        }
    }

      在配置文件中进行配置:

        <!-- 实例工厂使用 -->
        <bean id="airPlaneInstanceFactory" class="com.njf.spring.factory.AirPlaneInstatceFactory"></bean>
        <!--
            factory-bean:指定当前对象创建使用哪个工厂
            1、先配置出实例工厂对象
            2、配置我们要创建的 Airplane 使用哪个工厂创建
                (1)factory-bean:指定使用哪个工厂实例
                (2)factory-method:使用哪个工厂方法
        -->
        <bean id="airPlane02" class="com.njf.spring.bean.AirPlane" factory-bean="airPlaneInstanceFactory" factory-method="getAirPlane">
            <!--为静态方法指定参数-->
            <constructor-arg name="captain" value="王鄂峰"></constructor-arg>
        </bean>

      测试代码:

        @Test
        public void test6() {
            ApplicationContext ioc = new ClassPathXmlApplicationContext("ioc3.xml");
    
            AirPlane airPlane02 = (AirPlane) ioc.getBean("airPlane02");
            System.out.println("airPlane02 = " + airPlane02);
        }

      这样就可以调用实例工厂创建对应的 bean 对象。

    三、实现 FactoryBean 的工厂

      Spring 中有两种类型的 bean,一种是 普通的 bean,另一种是工程 bean,即 FactoryBean。
      工厂 bean 与普通 bean 不同,其返回的对象不是指定类的一个实例,其返回的是该工程 bean 的 getObject 方法所返回的对象
      工厂 bean 必须要实现 org.springframework.beans.factory.FactoryBean  接口
      

       创建 FactoryBean 的实现类:

    /**
     * 实现了 FactoryBean 接口的类都是Spring可以认识的类,Spring会自动的调用工厂方法创建实例
     *
     * 1、编写一个 FactoryBean 的实现类
     * 2、在Spring的配置文件中进行注册
     *
     */
    public class MyFactoryBeanImpl implements FactoryBean<Book> {
    
        /**
         * getObject: 工厂方法,返回创建的对象
         * @return
         * @throws Exception
         */
        @Override
        public Book getObject() throws Exception {
            Book book = new Book();
            book.setBookName("西游记");
            book.setAuthor("吴承恩");
            return book;
        }
    
        /**
         * 返回创建的对象的类型
         *  Spring会调用这个方法来确认创建的对手是什么类型
         * @return
         */
        @Override
        public Class<?> getObjectType() {
            return Book.class;
        }
    
        /**
         * isSingleton:是单例?
         *  false:不是单例
         *  true:是单例
         * @return
         */
        @Override
        public boolean isSingleton() {
            return false;
        }
    }

       在Spring 的配置文件中进行注册:

        <!--
            FactoryBean 是Spring规定的一个接口,只要是该接口的实现类,Spring都认为这是一个工厂。
            1、IOC 容器启动的时候不会创建实例
            2、FactoryBean 获取的时候才创建对象
        -->
        <bean id="myFactoryBeanImpl" class="com.njf.spring.factory.MyFactoryBeanImpl"></bean>

      测试:

        @Test
        public void test7() {
            ApplicationContext ioc = new ClassPathXmlApplicationContext("ioc3.xml");
    
            Object bean = ioc.getBean("myFactoryBeanImpl");
            Object bean2 = ioc.getBean("myFactoryBeanImpl");
            System.out.println("bean = " + bean);
            System.out.println("bean2 = " + bean2);
            System.out.println(bean == bean2);  //false
        }
  • 相关阅读:
    [leetcode] Maximum Depth of Binary Tree
    [leetcode] Binary Tree Zigzag Level Order Traversal
    [leetcode] Binary Tree Level Order Traversal
    软工第二次极限测试
    动手动脑的问题以及课后实验性的问题3
    计算几何--半平面交与平面区域
    拉格朗日插值法
    计算几何--最小圆覆盖与最小球覆盖
    计算几何--圆与球
    程序员修炼之道读后感1
  • 原文地址:https://www.cnblogs.com/niujifei/p/15414646.html
Copyright © 2020-2023  润新知