欢迎光临
我们一直在努力

Spring Boot 最佳实践:构造器注入+策略工厂,让你的代码更健壮、更可测

一次讲透:Spring Boot 中如何用构造器注入构建无懈可击的策略工厂

    • 1.定义策略接口
    • 2.定义自定义枚举
    • 2.定义策略实现类
    • 3.定义策略工厂【本次博文核心】

1.定义策略接口

/**
* 定义对外开放策略接口
*/

public interface BizStrategy {
/**
* 执行具体业务逻辑
* @param request 已解析的请求根对象
* @return 处理后的响应对象(或原始对象、或字符串,根据业务需要修改)
*/

String executeRequest(Request request);

/**
* 返回策略对应的类型
* @return
*/

String getType();
}

2.定义自定义枚举

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface BizTypeAnnotation {
/**
* 服务编码
*/

String serviceCode();
/**
* 服务场景
*/

String serviceScene();
/**
* 描述
*/

String description() default "";
}

2.定义策略实现类

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.util.LinkedHashMap;
import java.util.List;
import java.util.stream.Collectors;

/**
* 策略1<br/>
*/

@Slf4j
@BizTypeAnnotation(serviceCode = "20261314",serviceScene = "08",description = "策略1")
@Component
public class Strategy01 implements BizStrategy{
@Autowired
private AppServices appServices;
/**
* 执行具体业务逻辑
* @param request 已解析的请求根对象
* @return 处理后的响应对象(或原始对象、或字符串,根据业务需要修改)
*/

@Override
public String executeRequest(Request request) {
log.info("策略1executeRequest:{}",request);

return "";
}

@Override
public String getType() {
return "01";
}
}

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.util.LinkedHashMap;
import java.util.List;
import java.util.stream.Collectors;

/**
* 策略1<br/>
*/

@Slf4j
@BizTypeAnnotation(serviceCode = "20261315",serviceScene = "09",description = "策略2")
@Component
public class Strategy02 implements BizStrategy{
@Autowired
private AppServices appServices;
/**
* 执行具体业务逻辑
* @param request 已解析的请求根对象
* @return 处理后的响应对象(或原始对象、或字符串,根据业务需要修改)
*/

@Override
public String executeRequest(Request request) {
log.info("策略2executeRequest:{}",request);

return "";
}

@Override
public String getType() {
return "02";
}
}

3.定义策略工厂【本次博文核心】

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
* 策略工厂
* <pre>
* Spring Boot 构造器注入 + 策略工厂 = 通过构造器将 Map<String, 策略接口> 或 List<策略接口> 注入工厂,
* 利用 Spring 的自动收集能力完成策略注册,再暴露一个根据 key 查找策略的方法。 非常完美的设计
* 还可以这么做{@code
* //strategyMap 中的key 默认是如果有指定Bean的名称就使用Bean的名称,如@Component("bizStrategyFactory")
* //如果没有指定,默认就是Bean类名【但是第一个字母小写】,如类名是BizStrategyFactory,key就是"bizStrategyFactory"字符串
* //注意:使用strategyMap作为构造参数,key就不能自定义,推荐使用List<策略接口>+自己构建strategyMap+自定义注解或getType()作为自定义key
* @Autowired
* public BizStrategyFactory(Map<String,BizStrategy> strategyMap){
* }
* </pre>
*/

@Component
public class BizStrategyFactory {
private final Map<String,BizStrategy> strategyMap =new HashMap<>();

/**
* //通过构造器注入所有策略实现
* //Spring 会自动找到所有实现了BizStrategy接口的策略Bean,然后注入进来
* @param strategyList
*/

@Autowired
public BizStrategyFactory(List<BizStrategy> strategyList){
for (BizStrategy strategy : strategyList) {
BizTypeAnnotation annotation = strategy.getClass().getAnnotation(BizTypeAnnotation.class);
if (annotation != null) {
String key = annotation.serviceCode() + "_" + annotation.serviceScene();
strategyMap.put(key,strategy);
}
}
}

public Map<String, BizStrategy> getStrategyMap() {
return strategyMap;
}

/**
* 获取指定策略
* @param serviceCode
* @param serviceScene
* @return
*/

public BizStrategy getBizStrategy(String serviceCode,String serviceScene){
String key = serviceCode + "_" + serviceScene;
BizStrategy bizStrategy = strategyMap.get(key);
if (bizStrategy == null) {
throw new RuntimeException("未找到对应的策略业务处理器"+key);
}
return bizStrategy;
}
}

赞(0)
未经允许不得转载:171主机测评 » Spring Boot 最佳实践:构造器注入+策略工厂,让你的代码更健壮、更可测
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址