• Spring策略模式之Spring Plugin


    • 一般来说,简单的策略模式大概有这么2种用法,分别是:

      1. 传入一个参数作为策略,然后根据参数做一些事情,比如TreeMapComparator接口
      2. 传入一个参数作为策略,然后根据参数返回一个对应的对象,然后用户拿到此对象做一些事情
    • 我们在使用Spring时往往是使用如下方式:

      • 定义一个接口Stratege

        public interface Stratege {
            void doSomething(String param);
        }
        
      • 定义2个实现类AB

        @Component
        public static class A implements Stratege {
            @Override
            public void doSomething(String param) {
                // ...
            }
        }
        
        @Component
        public static class B implements Stratege {
            @Override
            public void doSomething(String param) {
                // ...
            }
        }
        
      • 于是就可以在某个注入类似Map<String, Stratege>或者List<Stratege>对象,然后从集合中获取相应的对象

    • 上述方式是可以很好的运行的,以前也一直这么用,某天看Swagger源码的时候发现Swagger用了很多Plugin方式,于是研究了一下Spring的plugin

    • 官网上说,这是有史以来最小的插件,数了下,整个包只有十来个类,他的原理和上面方式是一样的,也是通过传入某个参数,然后返回一个对象的对象,只不过上面的Map变成了PluginRegistry对象,Mapget(k)方法变成了getPluginFor或者getRequiredPluginFor(接口还有一些其他的方法,都是类似的)

      • 定义接口参数对象

        public class Param {
          String key;
        }
        
      • 定义接口

        public interface Stratege extends Plugin<Param> {
          void doSomething(Param param);
        }
        
      • 定义2个实现类AB

        @Component
        public class A implements Stratege {
          @Override
          public void doSomething(Param param) {
        	  // ...
          }
        
          @Override
          public boolean supports(Param delimiter) {
        	  return delimiter.key.equals("a");
          }
        }
        
        @Component
        public class B implements Stratege {
          @Override
          public void doSomething(Param param) {
        	  // ...
          }
        
          @Override
          public boolean supports(Param delimiter) {
        	  return delimiter.key.equals("b");
          }
        }
        
      • 在Spring启动类头顶增加注解:

        @SpringBootApplication
        @EnablePluginRegistries({Stratege.class})
        public class Application {}
        
      • 于是就可以注入策略对象:

        @RestController
        @RequestMapping("/stratege")
        public class StrategeController {
          @Resource
          private PluginRegistry<Stratege, Param> registry;
        
          @PostMapping("/doSomething")
          public void doStratege(@RequestBody Param param) {
        	  Stratege stratege = registry.getRequiredPluginFor(param);
        	  stratege.doSomething(param);
          }
        }
        
    • 关于插件的运行机制,也是比较简单,Spring的@EnableXXX的原理都是类似的,通过注解,启动Spring时解析注解,注入的容器

    • 总结:Map方式一般是通过对象名来获取bean,插件通过boolean supports(S delimiter)方法作为条件,插件方式灵活一点,但是这个插件由于比较小众,用的人少

  • 相关阅读:
    PHP类(一)-类的实例化
    PHP函数(六)-匿名函数(闭包函数)
    PHP函数(五)-回调函数
    javaIO-字符流
    split 命令
    hadoop的增删改查
    Hadoop的MR
    java的序列化和反序列化
    字符串格式化-String类format方法
    Avro从入门到入土
  • 原文地址:https://www.cnblogs.com/dreamroute/p/16276146.html
Copyright © 2020-2023  润新知