乐趣区

关于spring:聊聊如何利用spring插件来实现策略模式

前言

偶尔的机会发现 spring 有个 spring-plugin,官网对它的介绍是

Spring Plugin provides a more pragmatic approach to plugin development by providing the core flexibility of having plugin implementations extending a core system’s functionality but of course not delivering core OSGi features like dynamic class loading or runtime installation and deployment of plugins. Although Spring Plugin thus is not nearly as powerful as OSGi, it serves a poor man’s requirements to build a modular extensible application.

粗心就是 Spring 插件提供了一种更实用的插件开发方法,它提供了插件实现扩大外围零碎性能的外围灵活性,但当然不提供外围 OSGi 性能,如动静类加载或运行时装置和部署插件。只管 Spring 插件因而不如 OSGi 弱小,但它满足了富人构建模块化 可扩大 应用程序的需要。

本文就来聊下如何应用 spring 插件来实现策略模式

应用 spring-plugin 插件实现策略模式步骤

1、在我的项目中的 pom 引入 spring-plugin

 <dependency>
            <groupId>org.springframework.plugin</groupId>
            <artifactId>spring-plugin-core</artifactId>
            <version>2.0.0.RELEASE<version>
        </dependency>

注: springboot 2.2 以下版本 默认曾经集成 spring-plugin-core,因而无需指定版本号。不过集成的版本号比拟低,而且局部办法与高版本不兼容

2、定义一个实体类,这个实体类后边插件绑定插件类型会用到

@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class SmsRequest implements Serializable {

    private Map<String,Object> metaDatas;

    private String to;

    private String message;

    private SmsType smsType;


}

3、定义插件实现 org.springframework.plugin.core.Plugin 接口

public interface SmsPlugin extends Plugin<SmsRequest> {SmsResponse sendSms(SmsRequest smsRequest);


}

4、配置激活插件

@EnablePluginRegistries(SmsPlugin.class)
@Configuration
public class SmsPluginActiveConfig {

}

5、定义插件的具体实现类

@Component
public class AliyunSmsPlugin implements SmsPlugin {
    @Override
    public SmsResponse sendSms(SmsRequest smsRequest) {System.out.println("来自阿里云短信:" + smsRequest);
        return SmsResponse.builder()
                .code("200").message("发送胜利")
                .success(true).result("阿里云短信的回执").build();}

    @Override
    public boolean supports(SmsRequest smsRequest) {return SmsType.ALIYUN == smsRequest.getSmsType();
    }
}

注:该具体插件必须是 spring 的 bean

6、插件应用

在业务我的项目注入

@Autowired
private PluginRegistry<SmsPlugin,SmsRequest> pluginRegistry;

通用调用 pluginRegistry.getPluginFor 办法拿到具体插件

示例

@RequiredArgsConstructor
public class SmsService {


    private final PluginRegistry<SmsPlugin,SmsRequest> pluginRegistry;


    public SmsResponse sendSms(SmsRequest smsRequest){Optional<SmsPlugin> smsPlugin = pluginRegistry.getPluginFor(smsRequest);
        return smsPlugin.orElseThrow(() -> new SmsException("Sms plugin is not binder with type :【" + smsRequest.getSmsType() + "】"))
                .sendSms(smsRequest);


    }
}

7、测试

 @Test
    public void testAliyunSms(){SmsRequest smsRequest = SmsRequest.builder()
                .message("模仿应用阿里云短信发送")
                .to("136000000001")
                .smsType(SmsType.ALIYUN)
                .build();

        SmsResponse smsResponse = smsService.sendSms(smsRequest);
        Assert.assertTrue(smsResponse.isSuccess());
        System.out.println(smsResponse);

    }

总结

本文次要通过一个模仿短信发送的示例,演示如何通过 spring-plugin 来实现策略模式。如果咱们对扩展性有要求除了 spi,咱们也能够思考应用 spring-plugin。不过基于 spring-plugin 扩大时,要留神具体的插件实现类要为 spring 的 bean,不然插件会找不到

更多具体例子能够查看官网

https://github.com/spring-projects/spring-plugin

demo 链接

https://github.com/lyb-geek/springboot-learning/tree/master/springboot-springplugin-strategy

退出移动版