编写项目通用jar或者模块时,有时候需要开发部分接口或者配置来给按需求进行扩展
有看到钩子函数设计思路但是需要修改使用端的代码,在这里显然是不合适的。基于大部分项目都是基于spring开发,这里提供一个基于spring的方法思路。
先认识一下几个注解
spring为我们提供了**@Conditional**注解
继而延伸到子注解**@ConditionalOnMissingBean**。
eg: 假如限流组件模块有一个限流key的生成策略,其中有需要根据当前请求用户获取一个用户的key,模块提供默认实现,有特定需求则需要用户重写。
抽象接口
public interface LimitKeyHandler {
/**
* 获取用户唯一key
* @return
*/
String getUserKey();
/**
* 获取 ip
* @return
*/
String getIpKey();
}
默认实现
/**
* @author hby
* 2020/7/28 - 10:26.
**/
public class DefaultLimitKeyHandler implements LimitKeyHandler{
/**
* 使用用户为key 必须重写
* 否则抛出异常
* @return
*/
@Override
public String getUserKey() {
throw new RateLimitInvocationException();
}
@Override
public String getIpKey() {
return RequestUtils.getReqIp();
}
}
启动类配置
/**
* @author hby
* 2020/7/25 - 10:11
* 自动装配类
**/
@Configuration
@ConditionalOnProperty(prefix = Constant.PREFIX, name = "enable", havingValue = "true", matchIfMissing = true)
@AutoConfigureAfter(RedisAutoConfiguration.class)
@EnableConfigurationProperties(RateLimitConfig.class)
@Import({RedisConfiguration.class, CacheConfiguration.class, RepeatLimitConfiguration.class})
public class RateLimitAutoConfiguration {
@Bean
@ConditionalOnMissingBean(value = LimitKeyHandler.class)
public LimitKeyHandler stringRandomGenerator() {
return new DefaultLimitKeyHandler();
}
}
以上是模块代码内容
在需要接入的项目则可以通过继承LimitKeyHandler类,@Component,并重写LimitKeyHandler方法,将自己的业务实现注入,从而实现功能替换。
@Component
public class myLimitKeyHandler implements LimitKeyHandler {
@Override
public String getUserKey() {
return "hby";
}
@Override
public String getIpKey() {
return "10.82.111.111";
}
}
由此即可实现,代码有示例项目:分布式锁、限流组件