• springboot中使用工厂方法


    参考:

    https://www.shuzhiduo.com/A/ke5jZwbO5r/

    https://blog.csdn.net/Li_haiyu/article/details/124341345

    工厂方法是我们实际工作中经常用到的。

    比如下面的例子,一个接口有多个实现类,我们自然而然会想到使用工厂方法。

    //接口类
    public interface ReportService {
        String getResult();
    }
    
    //实现类
    public class ReportServiceA1 implements ReportService {
        @Override
        public String getResult() {
            return "我是A1";
        }
    }
    
    //实现类
    public class ReportServiceA2 implements ReportService {
        @Override
        public String getResult() {
            return "我是A2";
        }
    }

    为了构造实现类的实例,我们创建一个工厂类

    public class ReportFactory {
        public static ReportService createService(String name){
            if(name.equals("A1")){
                return new ReportServiceA1();
            }else if(name.equals("A2")){
                return new ReportServiceA2();
            }else{
                throw new IllegalArgumentException("不支持的类型");
            }
        }
    
        public static void main(String[] args) {
            ReportService a1 = createService("A1");
            String result = a1.getResult();
            System.out.println(result);
        }
    }

    输出:

    我是A1

    其实在SpringBoot中,也支持以依赖注入的方式实现工厂方法。

    我们只需要对类稍加改造即可。

    //接口实现不变
    public interface ReportService {
        String getResult();
    }
    
    //给实现类加上名字
    @Component("A1")
    public class ReportServiceA1 implements ReportService {
        @Override
        public String getResult() {
            return "我是A1";
        }
    }
    
    //给实现类加上名字
    @Component("A2")
    public class ReportServiceA2 implements ReportService {
        @Override
        public String getResult() {
            return "我是A2";
        }
    }

    新工厂类实现

    @Service
    public class ReportFactory {
        //这个地方是关键,项目启动时springboot会被所有ReportService实现类注入到这个map中
        @Autowired
        private final Map<String,ReportService> map=new ConcurrentHashMap<>();
    
        public ReportService get(String name){
            return map.get(name);
        }
    
    
    }

    测试一下,可以看出对应每个不同的实现类都只有唯一的一个实例,并且建立了name和实例的映射关系。

    而且这种工厂方法的实现比自己手写if/else工厂方法优雅多了。

    @SpringBootTest(classes= Application.class)
    class ReportFactoryTest {
    
        @Autowired
        private ReportFactory reportFactory;
    
        @Test
        void get() {
            ReportService a1 = reportFactory.get("A1");
            ReportService a11 = reportFactory.get("A1");
            System.out.println(a1);
            System.out.println(a11);
            System.out.println( a1.getResult());
            ReportService a2 = reportFactory.get("A2");
            System.out.println(a2.getResult());
        }
    }

    输出:

    cn.jinka.gcdp.metacenter.application.metadata.ReportServiceA1@d3e9629
    cn.jinka.gcdp.metacenter.application.metadata.ReportServiceA1@d3e9629
    我是A1
    我是A2
  • 相关阅读:
    创建用户自定义函数 SQL
    关于“该列没有包含在聚合函数或 GROUP BY 子句中”
    转Oracle性能参数—经典常用
    The server committed a protocol violation. Section=ResponseHeader Detail=CR must be followed by LF 错误
    js定时刷新
    用户获取mac地址的方法
    聚集索引和非聚集索引的区别
    WCF启动报错:“进程不具有此命名空间的访问权限”的解决方法
    利用js文件加载js文件的方法
    C#下载的几种方法
  • 原文地址:https://www.cnblogs.com/wangbin2188/p/16469012.html
Copyright © 2020-2023  润新知