在SpringBoot中优雅地实现策略模式
·
1、创建注解
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Component
public @interface StrategyFlag {
//标识
String value();
}
/**
* 策略方法
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface StrategyHandler {
}
2、定义交换器
/**
* 转换器
*/
public interface StrategyRunner {
//根据注册标识调用相对应的方法
void run(String flag);
}
3、配置类
@Configuration
public class StrategyConfig implements ApplicationContextAware {
private ApplicationContext applicationContext;
@Bean
public StrategyRunner strategyRunner() {
Map<String, Object> strategyClass = applicationContext.getBeansWithAnnotation(StrategyFlag.class);
// 策略处理函数
Map<String, Function<Void, Void>> strategyHandlers = new HashMap<>();
for (Object s : strategyClass.values()) {
// 获取策略标识
String flag = s.getClass().getAnnotation(StrategyFlag.class).value();
for (Method m : s.getClass().getMethods()) {
// 如果方法标注了StrategyHandler注解,则封装成可调用对象加入strategyHandlers
if(m.isAnnotationPresent(StrategyHandler.class)){
strategyHandlers.put(flag, ignored -> {
try {
m.invoke(s);
return null;
} catch (Exception e) {
throw new RuntimeException(e);
}
});
break;
}
}
}
return flag -> strategyHandlers.get(flag).apply(null);
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
}
4、实现
@StrategyFlag("s1")
public class Strategy1 {
@StrategyHandler
public void handleStrategy1() {
System.out.println("strategy 1");
}
}
@StrategyFlag("s2")
public class Strategy2 {
@StrategyHandler
public void handleStrategy2() {
System.out.println("strategy 2");
}
}
@RestController
@RequestMapping("/hello")
public class HelloController {
@Autowired
private StrategyRunner strategyRunner;
@RequestMapping("/")
public String hello(){
strategyRunner.run("s1");
strategyRunner.run("s2");
return "hello";
}
}
问题:每个策略都要创建一个类,如果一个类想要多个方法执行不同的策略则会比较受限,并且现在没有返回值
优化:
1、修改 @StrategyHandler
/**
* 该注解作用为每个方法对应标识
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface StrategyHandler {
// 标识
String value();
}
2、修改交换器
/**
* 转换器
*/
public interface StrategyRunner {
//根据注册标识调用相对应的方法。修改返回值类型为object
Object run(String flag);
}
3、修改配置类
@Configuration
public class StrategyConfig implements ApplicationContextAware {
private ApplicationContext applicationContext;
@Bean
public StrategyRunner strategyRunner() {
Map<String, Object> strategyClass = applicationContext.getBeansWithAnnotation(StrategyFlag.class);
// 策略处理函数,返回值类型为Object
Map<String, Function<Void, Object>> strategyHandlers = new HashMap<>();
for (Object s : strategyClass.values()) {
// 获取策略标识
String flag = s.getClass().getAnnotation(StrategyFlag.class).value();
for (Method m : s.getClass().getMethods()) {
// 如果方法标注了StrategyHandler注解,则封装成可调用对象加入strategyHandlers
if(m.isAnnotationPresent(StrategyHandler.class)){
//获取方法上面的标识
String value = m.getAnnotation(StrategyHandler.class).value();
//将策略表示和相对应的方法放在一起
strategyHandlers.put(value, ignored -> {
try {
return m.invoke(s);
} catch (Exception e) {
throw new RuntimeException(e);
}
});
}
}
}
return flag -> strategyHandlers.get(flag).apply(null);
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
}
3、实现
@StrategyFlag("s1")
public class Demo {
@StrategyHandler("alipay")
public String alipay() {
System.out.println("alipay");
return "helloAliPay";
}
@StrategyHandler("payple")
public void payple() {
System.out.println("payple");
}
}
@StrategyFlag("t1")
public class Test {
@StrategyHandler("boxingMatch")
public void jump() {
System.out.println("拳击");
}
@StrategyHandler("wrestlingCompetition")
public void payple() {
System.out.println("摔跤");
}
}
@RestController
@RequestMapping("/hello")
public class HelloController {
@Autowired
private StrategyRunner strategyRunner;
@RequestMapping("/")
public String hello(){
System.out.println(strategyRunner.run("alipay"));
strategyRunner.run("payple");
strategyRunner.run("boxingMatch");
strategyRunner.run("wrestlingCompetition");
return "hello";
}
}
更多推荐


所有评论(0)