路由:请求标识→匹配 Service→调用 process 方法
通过自定义注解 @BusinessServiceMapping
标记具体业务 Service,注解值(如 DC 代表客户、ORD
代表订单)与请求参数中的业务标识关联;再通过 Spring 容器扫描 + 策略模式,实现 “请求标识→匹配 Service→调用 process 方法” 的自动路由,避免硬编码分支判断。
根据条件动态选择执行,解耦 “选择逻辑” 和 “业务实现”
自定义注解:@BusinessServiceMapping
(标记业务 Service)
import org.springframework.stereotype.Component; import java.lang.annotation.*;/*** 自定义业务Service映射注解:标记Service对应的业务标识(如DC=客户、ORD=订单)*/ @Target({ElementType.TYPE}) // 仅用于类(Service实现类) @Retention(RetentionPolicy.RUNTIME) // 运行时保留,便于反射获取 @Documented @Component // 让Spring自动扫描该注解标记的类 public @interface BusinessServiceMapping {/*** 业务标识(如DC=客户、ORD=订单),支持多标识(如一个Service处理多个相关业务)*/String[] value();/*** 业务描述(可选,用于文档说明)*/String desc() default ""; }
2. 业务 Service 接口:BusinessProcessService
(定义统一方法)
import com.yourproject.dto.BusinessRequestDTO; import com.yourproject.dto.BusinessResponseDTO;/*** 业务Service统一接口:所有业务Service需实现此接口*/ public interface BusinessProcessService {/*** 统一业务处理方法* @param requestDTO 业务请求参数(封装请求标识、业务数据等)* @return 业务处理结果*/BusinessResponseDTO process(BusinessRequestDTO requestDTO);/*** 获取当前Service支持的业务标识(与@BusinessServiceMapping的value对应,便于校验)*/String[] getSupportBusinessCodes(); }
3. 业务请求 / 响应 DTO:封装参数与结果
// 业务请求DTO:请求需携带业务标识(如dc、ord) public class BusinessRequestDTO {/*** 业务标识(与@BusinessServiceMapping的value对应,如DC=客户、ORD=订单)*/private String businessCode;/*** 具体业务数据(JSON字符串,根据业务类型解析)*/private String businessData;// getter + setter }// 业务响应DTO:统一返回格式 public class BusinessResponseDTO {/*** 处理状态(SUCCESS/FAIL)*/private String status;/*** 响应消息*/private String message;/*** 业务结果数据(JSON字符串)*/private String resultData;// 静态工厂方法:简化创建public static BusinessResponseDTO success(String message, String resultData) {BusinessResponseDTO dto = new BusinessResponseDTO();dto.setStatus("SUCCESS");dto.setMessage(message);dto.setResultData(resultData);return dto;}public static BusinessResponseDTO fail(String message) {BusinessResponseDTO dto = new BusinessResponseDTO();dto.setStatus("FAIL");dto.setMessage(message);return dto;}// getter + setter }
4. 业务 Service 实现类(示例:客户 Service + 订单 Service)
// 示例1:客户业务Service(标识DC) @BusinessServiceMapping(value = "DC", // 业务标识:DC=客户desc = "客户相关业务处理(新增/编辑/查询客户)" ) public class CustomerBusinessService implements BusinessProcessService {@Overridepublic BusinessResponseDTO process(BusinessRequestDTO requestDTO) {// 1. 解析客户业务数据(requestDTO.getBusinessData()为JSON字符串)String customerData = requestDTO.getBusinessData();// 示例:假设业务数据是客户新增参数(实际项目用JSON工具解析为实体类)// CustomerAddDTO addDTO = JSON.parseObject(customerData, CustomerAddDTO.class);// 2. 处理客户业务逻辑(如调用DAO新增客户)System.out.println("客户Service处理业务,数据:" + customerData);// 3. 返回结果return BusinessResponseDTO.success("客户业务处理成功", "{\"customerId\":1001,\"status\":\"ACTIVE\"}");}@Overridepublic String[] getSupportBusinessCodes() {// 与@BusinessServiceMapping的value保持一致(便于校验)return new String[]{"DC"};} }// 示例2:订单业务Service(标识ORD) @BusinessServiceMapping(value = "ORD", // 业务标识:ORD=订单desc = "订单相关业务处理(创建订单/取消订单)" ) public class OrderBusinessService implements BusinessProcessService {@Overridepublic BusinessResponseDTO process(BusinessRequestDTO requestDTO) {// 订单业务逻辑处理(类似客户Service)String orderData = requestDTO.getBusinessData();System.out.println("订单Service处理业务,数据:" + orderData);return BusinessResponseDTO.success("订单业务处理成功", "{\"orderId\":2001,\"orderStatus\":\"PAID\"}");}@Overridepublic String[] getSupportBusinessCodes() {return new String[]{"ORD"};} }
5. 路由服务:BusinessServiceRouter
(核心:匹配请求与 Service)
import org.springframework.beans.BeansException; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.stereotype.Component; import java.util.HashMap; import java.util.Map;/*** 业务Service路由:根据请求的businessCode匹配对应的Service*/ @Component public class BusinessServiceRouter implements ApplicationContextAware {/*** 业务标识→Service的映射缓存(key:businessCode,value:对应的BusinessProcessService)*/private final Map<String, BusinessProcessService> businessServiceMap = new HashMap<>();/*** Spring启动时,扫描所有带@BusinessServiceMapping的Service,初始化映射*/@Overridepublic void setApplicationContext(ApplicationContext applicationContext) throws BeansException {// 1. 扫描Spring容器中所有实现BusinessProcessService接口的BeanMap<String, BusinessProcessService> serviceBeans = applicationContext.getBeansOfType(BusinessProcessService.class);// 2. 遍历Service,解析@BusinessServiceMapping注解,建立映射for (BusinessProcessService service : serviceBeans.values()) {BusinessServiceMapping mapping = service.getClass().getAnnotation(BusinessServiceMapping.class);if (mapping == null) {continue; // 跳过未标记注解的Service }// 3. 为每个业务标识绑定Service(支持一个Service对应多个标识)for (String businessCode : mapping.value()) {if (businessServiceMap.containsKey(businessCode)) {throw new RuntimeException("业务标识[" + businessCode + "]重复绑定Service,请检查@BusinessServiceMapping注解");}businessServiceMap.put(businessCode, service);System.out.println("业务标识[" + businessCode + "]绑定Service:" + service.getClass().getSimpleName());}}// 4. 打印映射结果(便于调试)System.out.println("业务Service映射初始化完成,共" + businessServiceMap.size() + "个标识:" + businessServiceMap.keySet());}/*** 核心方法:根据业务标识获取对应的Service* @param businessCode 业务标识(如DC、ORD)* @return 匹配的BusinessProcessService* @throws RuntimeException 无匹配Service时抛出异常*/public BusinessProcessService getServiceByBusinessCode(String businessCode) {BusinessProcessService service = businessServiceMap.get(businessCode);if (service == null) {throw new RuntimeException("未找到业务标识[" + businessCode + "]对应的Service,请检查配置");}return service;}/*** 统一业务处理入口:路由到对应Service并调用process方法*/public BusinessResponseDTO routeAndProcess(BusinessRequestDTO requestDTO) {if (requestDTO == null || requestDTO.getBusinessCode() == null) {return BusinessResponseDTO.fail("请求参数错误:businessCode不能为空");}try {// 1. 根据businessCode获取ServiceBusinessProcessService service = getServiceByBusinessCode(requestDTO.getBusinessCode());// 2. 调用Service的process方法处理业务return service.process(requestDTO);} catch (RuntimeException e) {// 3. 捕获异常,返回统一错误格式return BusinessResponseDTO.fail("业务处理失败:" + e.getMessage());}} }
6. 控制层:BusinessController
(接收请求,调用路由服务)
import com.yourproject.dto.BusinessRequestDTO; import com.yourproject.dto.BusinessResponseDTO; import com.yourproject.service.BusinessServiceRouter; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController;/*** 统一业务入口Controller:所有业务请求通过此接口进入,由路由服务分发*/ @RestController @RequestMapping("/api/business") public class BusinessController {@Autowiredprivate BusinessServiceRouter businessServiceRouter;/*** 统一业务处理接口* @param requestDTO 业务请求(包含businessCode和业务数据)* @return 业务处理结果*/@PostMapping("/process")public BusinessResponseDTO processBusiness(@RequestBody BusinessRequestDTO requestDTO) {// 直接委托路由服务处理,无需硬编码分支return businessServiceRouter.routeAndProcess(requestDTO);} }
三、核心流程说明
四、扩展与优势
五、依赖与配置
import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.ComponentScan;@SpringBootApplication // 若Service在com.yourproject.service包下,默认会扫描,无需额外配置;若路径不同需添加: // @ComponentScan(basePackages = {"com.yourproject.controller", "com.yourproject.service"}) public class BusinessApplication {public static void main(String[] args) {SpringApplication.run(BusinessApplication.class, args);} }