开发者社区> 灰小猿> 正文
阿里云
为了无法计算的价值
打开APP
阿里云APP内打开

手把手教你应用三种工厂模式在SpringIOC中创建对象实例【案例详解】

简介:
+关注继续查看

 

目录

一、工厂模式介绍

二、通过静态工厂方法创建Bean实例

三、通过实例工厂方法创建Bean实例

四、通过自定义的factoryBean来创建bean对象


Hello,你好呀,我是灰小猿!一个超会写bug的程序猿!

工厂模式相信很多小伙伴们都有听说过,但是工厂模式在Java中的具体使用你有了解过吗?今天在这里和大家讲一下在Spring中如何使用三种工厂模式(静态工厂、实例工厂、自定义工厂)来创建bean对象并使用。

在这里我们先来讨论一下何为“工厂模式”,使用工厂模式的好处。

一、工厂模式介绍

工厂模式(Factory Pattern)是 Java 中最常用的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。

在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,而是通过使用一个共同的接口来指向新创建的对象。

使用意图:定义一个创建对象的接口,让其子类自己决定实例化哪一个工厂类,工厂模式使其创建过程延迟到子类进行。

主要解决:主要解决接口选择的问题。

何时使用:我们明确地计划不同条件下创建不同实例时使用。

如何解决:让其子类实现工厂接口,返回的也是一个抽象的产品。

关键代码:创建过程在其子类执行。

应用实例: 比如说你需要一辆汽车,你可以直接从工厂里面提货就可以了,而不用去管这辆汽车是怎么做出来的,以及这个汽车里面的具体实现。这就是工厂模式。

优点: 1、一个调用者想创建一个对象,只要知道其名称就可以了。 2、扩展性高,如果想增加一个产品,只要扩展一个工厂类就可以。 3、屏蔽产品的具体实现,调用者只关心产品的接口。

缺点:每次增加一个产品时,都需要增加一个具体类和对象实现工厂,使得系统中类的个数成倍增加,在一定程度上增加了系统的复杂度,同时也增加了系统具体类的依赖。

注意事项:作为一种创建类模式,在任何需要生成复杂对象的地方,都可以使用工厂方法模式。有一点需要注意的地方就是复杂对象适合使用工厂模式,而简单对象,特别是只需要通过 new 就可以完成创建的对象,无需使用工厂模式。如果使用工厂模式,就需要引入一个工厂类,会增加系统的复杂度。

以上就是工厂模式的基本介绍和使用场景,那么到底应该如何在Java中实现工厂模式呢?下面我将通过在Spring中对bean进行实例化的例子来和大家详细分析一下三种工厂模式的具体使用。首先做一个准备工作,我们创建一个bean类AirPlane(飞机类),并实现属性的get和set方法;

package com.spring.beans;
/**
 * 飞机类
 * */
public class AirPlane {
    private String fdj;//飞机发动机
    private String yc;//机翼长度
    private String jzName;//机长名
    private String fjzName;//副机长名
    private Integer personNum;//乘客数
    
    
    public String getFdj() {
        return fdj;
    }
    public void setFdj(String fdj) {
        this.fdj = fdj;
    }
    public String getYc() {
        return yc;
    }
    public void setYc(String yc) {
        this.yc = yc;
    }
    public String getJzName() {
        return jzName;
    }
    public void setJzName(String jzName) {
        this.jzName = jzName;
    }
    public String getFjzName() {
        return fjzName;
    }
    public void setFjzName(String fjzName) {
        this.fjzName = fjzName;
    }
    public Integer getPersonNum() {
        return personNum;
    }
    public void setPersonNum(Integer personNum) {
        this.personNum = personNum;
    }
    
    @Override
    public String toString() {
        return "AirPlane [fdj=" + fdj + ", yc=" + yc + ", jzName=" + jzName
                + ", fjzName=" + fjzName + ", personNum=" + personNum + "]";
    }
    
    
}

image.gif

二、通过静态工厂方法创建Bean实例

在Spring中调用静态工厂方法创建bean是将对象创建的过程封装到静态方法中。当客户端需要对象时,只需要简单地调用静态方法,而不用关心创建对象的细节。

在IOC容器中,通过静态工厂方法声明创建bean的步骤是:

    1. 首先在bean的class属性里指定静态工厂类的全类名,
    2. 同时在factory-method属性里指定工厂方法的名称。
    3. 最后使用<constrctor-arg>元素为该方法传递方法参数。

    接下来我们通过具体的代码来实现:

    写一个静态工厂的实现类AirplaneStaticFactory,其中实现造飞机的静态方法getAirPlane(String jzName),传入一个参数代表机长姓名。并将创建的飞机对象返回。

    package com.spring.factory;
    import com.spring.beans.AirPlane;
    /**
     * 飞机静态工厂
     * */
    public class AirplaneStaticFactory {
        /**
         *  private String fdj;//飞机发动机
        private String yc;//机翼长度
        private String jzName;//机长名
        private String fjzName;//副机长名
        private Integer personNum;//乘客数
         * */
        public static AirPlane getAirPlane(String jzName) {
            AirPlane airPlane = new AirPlane();
            airPlane.setFdj("太行");
            airPlane.setYc("190.2");
            airPlane.setJzName(jzName);
            airPlane.setFjzName("小刚");
            airPlane.setPersonNum(300);
            return airPlane;
        }
    }

    image.gif

    以上准备工作完成之后,就是通过静态工厂方法声明创建bean的实现了,按照上面的步骤在ioc容器中进行实现,

    <!-- 通过静态工厂方法创建airplane实例 
        factory-method指定工厂方法名 -->
    <bean id="airplane01" class="com.spring.factory.AirplaneStaticFactory" factory-method="getAirPlane">
        <!-- 为该方法传递方法参数-->
        <constructor-arg name="jzName" value="静态机长01"></constructor-arg>
    </bean>

    image.gif

    之后通过ioc容器的getBean()方法就可以获取到创建的bean对象。测试如下:

    //****************利用工厂方法来创建bean*************    
        ApplicationContext iocContext4 = new ClassPathXmlApplicationContext("ioc4.xml");
                
        /**
         * 利用工厂方法创建实例
         * */
        @Test
        public void test10() {
    //      利用静态工厂创建实例
            AirPlane airPlane01 = (AirPlane)iocContext4.getBean("airplane01");
            System.out.println(airPlane01);
            
    //      利用实例工厂创建实例
            AirPlane airPlane02 = (AirPlane)iocContext4.getBean("airplane02");
            System.out.println(airPlane02);
            
    //      利用自定义工厂创建实例
            AirPlane airPlane03 = (AirPlane)iocContext4.getBean("myFactoryBean");
            System.out.println(airPlane03);
        }

    image.gif

    测试结果:

    imageimage.gif编辑

    三、通过实例工厂方法创建Bean实例

    实例工厂方法是将对象的创建过程封装到另外一个对象实例的方法里。当客户端需要请求对象时,只需要简单的调用该实例方法而不需要关心对象的创建细节。

    实例工厂的实现步骤是

      1. 配置工厂类实例的bean
      2. 在factory-method属性里指定该工厂方法的名称
      3. 使用 construtor-arg 元素为工厂方法传递方法参数

      首先我们先写一个实现实例工厂的类AirplaneInstanceFactory,在其中实现创建bean对象的实例方法getAirPlane(String jzName),

      package com.spring.factory;
      import com.spring.beans.AirPlane;
      /**
       * 飞机实例工厂
       * */
      public class AirplaneInstanceFactory {
          
          public AirPlane getAirPlane(String jzName) {
              AirPlane airPlane = new AirPlane();
              airPlane.setFdj("太行");
              airPlane.setYc("190.2");
              airPlane.setJzName(jzName);
              airPlane.setFjzName("小刚");
              airPlane.setPersonNum(300);
              return airPlane;
          }
      }

      image.gif

      之后在IOC容器中配置实现工厂类的bean,指明是将哪一个实例工厂类实例化的。

      <!-- 创建一个实例工厂 -->
      <bean id="airplaneInstanceFacatory" class="com.spring.factory.AirplaneInstanceFactory"></bean>

      image.gif

      现在就是将bean对象进行实例化的过程了,在IOC容器中,我们创建一个bean实例,调用实例工厂中的工厂方法,来对bean进行实例化,在这里我们需要使用factory-method属性里指定该工厂方法的名称,同时使用 construtor-arg 元素为工厂方法传递方法参数。具体实现是这样的:

      <!-- 创建一个bean实例,调用实例工厂中的工厂方法 -->
      <bean id="airplane02" class="com.spring.beans.AirPlane" 
      factory-bean="airplaneInstanceFacatory" factory-method="getAirPlane"
      >
          <constructor-arg name="jzName" value="实例机长01"></constructor-arg>
      </bean>

      image.gif

      现在通过实例工厂创建bean对象的过程就结束了,通过获取到ioc容器中的bean对象进行测试:

      //****************利用工厂方法来创建bean*************    
          ApplicationContext iocContext4 = new ClassPathXmlApplicationContext("ioc4.xml");
                  
          /**
           * 利用工厂方法创建实例
           * */
          @Test
          public void test10() {
      //      利用静态工厂创建实例
              AirPlane airPlane01 = (AirPlane)iocContext4.getBean("airplane01");
              System.out.println(airPlane01);
              
      //      利用实例工厂创建实例
              AirPlane airPlane02 = (AirPlane)iocContext4.getBean("airplane02");
              System.out.println(airPlane02);
              
      //      利用自定义工厂创建实例
              AirPlane airPlane03 = (AirPlane)iocContext4.getBean("myFactoryBean");
              System.out.println(airPlane03);
          }

      image.gif

      测试结果:

      imageimage.gif编辑

      四、通过自定义的factoryBean来创建bean对象

      通过自定义的factoryBean来创建bean对象时,我们需要在工厂类上实现factoryBean接口,

      Spring中有两种类型的bean,一种是普通bean,另一种是工厂bean,即FactoryBean。

      工厂bean跟普通bean不同,其返回的对象不是指定类的一个实例,其返回的是该工厂bean的getObject方法所返回的对象。

      工厂bean必须实现org.springframework.beans.factory.FactoryBean接口,使用factoryBean接口的一个好处就是只要是实现这个接口的类,spring都会认为是工厂。

      该接口规定了三个方法:

      imageimage.gif编辑

       我们先来创建一个自定义的、容器能够认识的factoryBean类,并且重写其中的三个方法。

      package com.spring.factory;
      import org.springframework.beans.factory.FactoryBean;
      import com.spring.beans.AirPlane;
      import com.spring.beans.Book;
      /**
       * 创建一个实例工厂的接口
       * 创建一个容器能够认识的factoryBean类,
       * 只要是这个接口实现的类,spring都会认为是工厂
       * */
      public class MyFactoryBeanImplements implements FactoryBean<AirPlane>{
          /**
           * 工厂方法,返回创建的对象
           * */
          @Override
          public AirPlane getObject() throws Exception {
              // TODO Auto-generated method stub
              AirPlane airPlane = new AirPlane();
              airPlane.setFdj("太行-2");
              airPlane.setYc("290.2");
              airPlane.setJzName("自定义机长01");
              airPlane.setFjzName("小刚");
              airPlane.setPersonNum(300);
              return airPlane;
          }
          /**
           * 返回对象的类型
           * */
          @Override
          public Class<?> getObjectType() {
              // TODO Auto-generated method stub
              return AirPlane.class;
          }
          
          /**
           * isSingleton 是单例吗?
           * false 不是单例
           * true 是单例
           * false和true是可以切换的
           * */
          @Override
          public boolean isSingleton() {
              // TODO Auto-generated method stub
              return false;
          }
      }

      image.gif

      之后在IOC容器中直接对该自定义工厂类进行实例化,即可完成相应的bean的实例创建。

      <!-- 通过自定义的factoryBean来创建对象 -->
      <!-- 该bean只有在调用时才会被创建,容器创建时不会创建该bean -->
      <bean id="myFactoryBean" class="com.spring.factory.MyFactoryBeanImplements" ></bean>

      image.gif

      在使用该实例化的bean的时候,同样也是直接在IOC容器中获取相应的实例工厂即可。

      //****************利用工厂方法来创建bean*************    
          ApplicationContext iocContext4 = new ClassPathXmlApplicationContext("ioc4.xml");
                  
          /**
           * 利用工厂方法创建实例
           * */
          @Test
          public void test10() {
      //      利用静态工厂创建实例
              AirPlane airPlane01 = (AirPlane)iocContext4.getBean("airplane01");
              System.out.println(airPlane01);
              
      //      利用实例工厂创建实例
              AirPlane airPlane02 = (AirPlane)iocContext4.getBean("airplane02");
              System.out.println(airPlane02);
              
      //      利用自定义工厂创建实例
              AirPlane airPlane03 = (AirPlane)iocContext4.getBean("myFactoryBean");
              System.out.println(airPlane03);
          }

      image.gif

      测试结果:

      imageimage.gif编辑

       至此,在spring中使用三种工厂模式创建bean实例的过程就和大家讲完了,其中有不足的地方欢迎小伙伴们评论指正!

      点赞关注,以留备用哟!

      我是灰小猿,我们下期见!

      imageimage.gif编辑

      版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

      相关文章
      04.创建型:简单工厂模式
      创建型:简单工厂模式
      16 0
      【漫画】Java对象的创建和访问全过程详解(下)
      【漫画】Java对象的创建和访问全过程详解
      29 0
      《跟二师兄学Nacos吧》EXT-01篇 看看Nacos是怎么活学活用简单工厂模式的!
      《跟二师兄学Nacos吧》EXT-01篇 看看Nacos是怎么活学活用简单工厂模式的!
      70 0
      JAVA对象创建过程内存图解
      JAVA对象创建过程内存图解1、类与对象类是现实事物的抽象,将现实事物描述成对应的类,类中封装了成员变量、构造方法、成员方法、set/get方法。 比如说人,人都有哪些属性?姓名,年龄,性别...等等这些都属于人的属性,可以将其封装为类的成员变量。
      1027 0
      简单工厂、工厂方法、抽象工厂、策略模式、策略与工厂的区别
      【本文转自简单工厂、工厂方法、抽象工厂、策略模式、策略与工厂的区别】 结合简单示例和UML图,讲解工厂模式简单原理。 一、引子 话说十年前,有一个爆发户,他家有三辆汽车(Benz(奔驰)、Bmw(宝马)、Audi(奥迪)),还雇了司机为他开车。不过,爆发户坐车时总是这样:上Benz车后跟司机说“开奔驰车!”,坐上Bmw后他说“开宝马车!”,坐上 Audi后他说“开奥迪车!
      1325 0
      [转]Java中堆和栈创建对象的区别
      转载自http://blog.csdn.net/hbhhww/article/details/8152838 栈与堆都是Java用来在Ram中存放数据的地方。与C++不同,Java自动管理栈和堆,程序员不能直接地设置栈或堆。
      855 0
      详解 JAVA 创建对象 NEW
      假设我们在函数中写了如下这个简单的语句:   StringBuffer str = new StringBuffer("Hello world");   别看这个语句简单,其实包含了如下三个步骤:   首先,newStringBuffer("Helloworld")在堆里申请了一坨内存,把创建好的StringBuffer对象放进去。
      874 0
      +关注
      灰小猿
      一个用代码编织世界的工程师
      70
      文章
      0
      问答
      文章排行榜
      最热
      最新
      相关电子书
      更多
      低代码开发师(初级)实战教程
      立即下载
      阿里巴巴DevOps 最佳实践手册
      立即下载
      冬季实战营第三期:MySQL数据库进阶实战
      立即下载