• spring6-工厂设计模式与bean的实例化方式


    bean的作用域

    ioc容器默认bean是单例的(singleton)。

    bean对象的创建是在初始化上下文的时候就创建了,每一次调用getBean()时,都返回那个单例对象。

    // 这行代码会创建配置里面的bean对象
    ApplicationContext context = new FileSystemXmlApplicationContext("D:/applicationContext.xml");
    

    那如何把bean设置成多例的?

    
    <bean id="sb" class="com.ali.bean.SpringBean"  scope="prototype"/>
    
    // 由于这个bean是多例模式,这行代码不会创建bean对象。而是在调用getBean()时创建对象
    ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml","spring-dao.xml");
    // 这行代码才会创建bean对象
    Object user=  context.getBean("sb");
    
    
        <bean id="sb" class="com.ali.bean.SpringBean"  scope="prototype"/>
    

    自定义scope

    1. 自定义Scope(实现Scope接口)

      • spring内置了线程范围类: org.springframework.context.support.SimpleThreadScope
    2. 添加配置信息

        <bean id="sb" class="com.ali.bean.SpringBean"  scope="threadScope"/>
    
    
        <bean class="org.springframework.beans.factory.config.CustomScopeConfigurer" >
            <property name="scopes">
                <map>
                    <entry key="threadScope">
    
                        <bean class="org.springframework.context.support.SimpleThreadScope">bean>
                    entry>
                map>
            property>
        bean>
    

    GoF之工厂模式

    工厂模式的三种形态

    1. 简单工厂模式(Simple Factory):又叫静态工厂方法模式。是工厂方法模式的一种特殊实现。
    2. 工厂方法模式 (Factory Method)
    3. 抽象工厂模式 (Abstract Factory)

    简单工厂模式

    简单工厂模式包括三个角色:抽象产品、具体产品、工厂类。代码如下:

    1. 抽象产品类
    // 抽象产品角色
    public abstract class Weapon {
    	public abstract void attack();
    }
    
    1. 具体产品

      // 具体产品角色:匕首
      public class Dagger extends Weapon{
          @Override
          public void attack() {
              System.out.println("匕首攻击...");
          }
      }
      
    // 具体产品角色:战斗机
    public class Fighter extends Weapon{
        @Override
        public void attack() {
            System.out.println("战斗机攻击...");
        }
    }
    
    // 具体产品角色:坦克
    public class Tank extends Weapon{
        @Override
        public void attack() {
          System.out.println( "坦克攻击。。。");
        }
    }
    
    1. 工厂类角色
    // 工厂类角色
    public class WeaponFactory {
        /**
         * 静态方法:根据传入的参数获取相应的武器
         * @return
         */
        public static Weapon get(String type){
            switch (type){
                case "Tank":
                    return new Tank();
                case "Fighter":
                    return new Fighter();
                case "Dagger":
                    return new Dagger();
                default:
                    return null;
            }
        }
    }
    

    测试代码:

    public class Main {
        public static void main(String[] args) {
            // 简单工厂模式达到职责分离。客户端不关心产品生产的细节
            // 客户端只负责消费,工厂类负责生产。这就是简单工厂模式的作用。
            Weapon weapon1 = WeaponFactory.get("Tank");
            weapon1.attack();
            Weapon weapon2 = WeaponFactory.get("Fighter");
            weapon2.attack();
            Weapon weapon3 = WeaponFactory.get("Dagger");
            weapon3.attack();
        }
    }
    

    优缺点:

    优点:实现职责分离。

    缺点:假如要添加新产品。需要修改工厂类代码。显然违反了ocp原则。

    ​ 工厂类责任重大。一旦瘫痪,这个系统必然瘫痪。

    工厂方法模式

    工厂方法模式保留了简单工厂模式的优点。同时解决了简单工厂模式的缺点。

    解决方法是:一个工厂对应一个产品。符合ocp原则。

    优点:扩展性高。要想增加一个产品。只要扩展一个工厂类就可以。

    	屏蔽产品具体实现。调用者只关心产品的接口。
    

    缺点:会使类的数量成倍增加,增加系统复杂度。

    工厂方法模式的角色包括:

    • 抽象工厂角色
    • 具体工厂角色
    • 抽象产品角色
    • 具体产品角色

    代码如下:

    // 抽象产品角色
    public abstract class Weapon {
        public abstract void attack();
    }
    
    // 具体产品角色:匕首
    public class Dagger extends Weapon {
        @Override
        public void attack() {
            System.out.println("匕首攻击...");
        }
    }
    
    // 具体产品角色:枪械
    public class Gun extends Weapon{
        @Override
        public void attack() {
            System.out.println("枪械攻击...");
        }
    }
    
    // 抽象工厂类
    public abstract class WeaponFactory {
    
        public abstract Weapon get();
    }
    
    // 具体工厂类:匕首工厂
    public class DaggerFactory extends WeaponFactory{
        @Override
        public Weapon get() {
            return new Dagger();
        }
    }
    
    // 具体工厂类:枪械工厂
    public class GunFactory extends WeaponFactory{
        @Override
        public Weapon get() {
            return new Gun();
        }
    }
    

    测试代码:

    public static void main(String[] args) {
        WeaponFactory weaponFactory = new DaggerFactory();
        Weapon dagger = weaponFactory.get();
        dagger.attack();
    
        WeaponFactory weaponFactory1 = new GunFactory();
        Weapon gun = weaponFactory1.get();
        gun.attack();
    }
    

    bean的实例化

    spring为bean提供了多种实例化的方式,通常包括4种方式。

    1. 通过构造方法实例化
    2. 通过简单工厂模式实例化
    3. 通过factory-bean实例化
    4. 通过FactoryBean接口实例化

    通过构造方法实例化

    
        <bean id="springBean" class="com.ali.bean.SpringBean" />
    

    通过简单工厂模式实例化

    // 工厂类
    public class StarFactory {
        public static Star createStar() {
            return new Star();
        }
    }
    
    
      <bean id="starBean" class="com.ali.bean.StarFactory" factory-method="createStar">bean>
    

    通过factory-bean实例化

    // 工厂方法模式中的具体产品类
    public class Gun {
        public Gun() {
            System.out.println("无参数构造器:Gun()");
        }
    }
    
    // 工厂方法模式中的具体工厂类
    public class GunFactory {
        public Gun get(){
            return new Gun();
        }
    }
    
    
        <bean id="gunFactory" class="com.ali.bean.GunFactory">bean>
        <bean id="gun" factory-bean="gunFactory" factory-method="get">bean>
    

    通过FactoryBean接口实例化

    通过factory-bean实例化的方式需要我们自定义factory-bean和factory-method。

    在spring中,当自己的类实现了FactoryBean接口后factory-bean和factory-method就不需要指定了。factory-bean会自动指向实现FactoryBean接口的类,factory-method会自动指向getObject()方法。

    public class PersonFactoryBean implements FactoryBean {
        @Override
        public Person getObject() throws Exception {
            // 手动创建对象
            return new Person();
        }
    
        @Override
        public Class getObjectType() {
            return null;
        }
    
    }
    
    
    <bean id="person" class="com.ali.bean.PersonFactoryBean">bean>
    

    BeanFactory和FactoryBean的区别

    BeanFactory:spring ioc容器的顶级对象,负责创建bean对象。BeanFactory是工厂

    FactoryBean:本质是一个bean。能够辅助spring实例化其他bean对象。

  • 相关阅读:
    【限制输入框值类型】自定义指令el-input输入类型限制,vue和html两个版本
    [附源码]SSM计算机毕业设计学生宿舍管理系统JAVA
    【Filament】材质系统
    vite react react-pdf pdfjs-dist 加载不全的解决方案 cmaps本地路径
    Vue--组件数据传递与组件切换
    为什么你的static_assert不能按预期的工作?
    1区TOP正刊,SCI&EI双检,IF逐年上涨,正在邀稿中~
    【必知 - 软件版本号如何定义及使用】
    axios取消请求原理、拦截器原理- http状态码 - http请求方式
    04 MongoDB各种查询操作 以及聚合操作总结
  • 原文地址:https://www.cnblogs.com/alineverstop/p/19570969