一、静态工厂创建 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
    }

 

 

 

 

 

posted on 2021-10-16 17:11  格物致知_Tony  阅读(219)  评论(0编辑  收藏  举报