diff --git a/CommonSwitch/.idea/.gitignore b/CommonSwitch/.idea/.gitignore
new file mode 100644
index 0000000..13566b8
--- /dev/null
+++ b/CommonSwitch/.idea/.gitignore
@@ -0,0 +1,8 @@
+# Default ignored files
+/shelf/
+/workspace.xml
+# Editor-based HTTP Client requests
+/httpRequests/
+# Datasource local storage ignored files
+/dataSources/
+/dataSources.local.xml
diff --git a/CommonSwitch/.idea/CommonSwitch.iml b/CommonSwitch/.idea/CommonSwitch.iml
new file mode 100644
index 0000000..6054576
--- /dev/null
+++ b/CommonSwitch/.idea/CommonSwitch.iml
@@ -0,0 +1,6 @@
+
+
+ * 通用开关注解 0 关 1 开 + * 程序员蜗牛 + *
+ */ +@Target({ElementType.METHOD}) // 作用在方法上 +@Retention(RetentionPolicy.RUNTIME) // 运行时起作用 +public @interface ServiceSwitch { + + /** + * 业务开关的key(不同key代表不同功效的开关) + * {@link Constant.ConfigCode} + */ + String switchKey(); + + // 提示信息,默认值可在使用注解时自行定义。 + String message() default "当前请求人数过多,请稍后重试。"; +} diff --git a/CommonSwitch/CommonSwitch/src/main/java/com/woniu/commonswitch/aop/ServiceSwitchAOP.java b/CommonSwitch/CommonSwitch/src/main/java/com/woniu/commonswitch/aop/ServiceSwitchAOP.java new file mode 100644 index 0000000..74a2e43 --- /dev/null +++ b/CommonSwitch/CommonSwitch/src/main/java/com/woniu/commonswitch/aop/ServiceSwitchAOP.java @@ -0,0 +1,86 @@ +package com.woniu.commonswitch.aop; + +import com.woniu.commonswitch.annotation.ServiceSwitch; +import com.woniu.commonswitch.constant.Constant; +import com.woniu.commonswitch.exception.BusinessException; +import com.woniu.commonswitch.util.Result; +import lombok.AllArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.annotation.Around; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.annotation.Pointcut; +import org.aspectj.lang.reflect.MethodSignature; +import org.springframework.data.redis.core.StringRedisTemplate; +import org.springframework.http.HttpStatus; +import org.springframework.stereotype.Component; + +import java.lang.reflect.Method; + +/** + *+ * 教你一招 SpringBoot + 自定义注解 + AOP 打造通用开关 + * 程序员蜗牛 + *
+ */ +@Aspect +@Component +@Slf4j +@AllArgsConstructor +public class ServiceSwitchAOP { + + private final StringRedisTemplate redisTemplate; + + /** + * 定义切点,使用了@ServiceSwitch注解的类或方法都拦截 + */ + @Pointcut("@annotation(com.woniu.commonswitch.annotation.ServiceSwitch)") + public void pointcut() { + } + + @Around("pointcut()") + public Object around(ProceedingJoinPoint point) { + + // 获取被代理的方法的参数 + Object[] args = point.getArgs(); + // 获取被代理的对象 + Object target = point.getTarget(); + // 获取通知签名 + MethodSignature signature = (MethodSignature) point.getSignature(); + + try { + + // 获取被代理的方法 + Method method = target.getClass().getMethod(signature.getName(), signature.getParameterTypes()); + // 获取方法上的注解 + ServiceSwitch annotation = method.getAnnotation(ServiceSwitch.class); + + // 核心业务逻辑 + if (annotation != null) { + + String switchKey = annotation.switchKey(); + String message = annotation.message(); + + /* + 获取配置项说明 + 这里有两种方式:1、配置加在Redis,查询时从Redis获取; + 2、配置加在数据库,查询时从表获取。(MySQL单表查询其实很快,配置表其实也没多少数据) + 我在工作中的做法: 直接放到数据字典里 同时加上缓存提高查询性能。 + */ + + // 这里我直接从redis中取,使用中大家可以按照意愿自行修改。 + String configVal = redisTemplate.opsForValue().get(switchKey); + if (Constant.SWITCHCLOSE.equals(configVal)) { + // 开关关闭,则返回提示。 + return new Result<>(HttpStatus.FORBIDDEN.value(), message); + } + } + + // 放行 + return point.proceed(args); + + } catch (Throwable e) { + throw new BusinessException(e.getMessage(), e); + } + } +} diff --git a/CommonSwitch/CommonSwitch/src/main/java/com/woniu/commonswitch/constant/Constant.java b/CommonSwitch/CommonSwitch/src/main/java/com/woniu/commonswitch/constant/Constant.java new file mode 100644 index 0000000..5b645cb --- /dev/null +++ b/CommonSwitch/CommonSwitch/src/main/java/com/woniu/commonswitch/constant/Constant.java @@ -0,0 +1,30 @@ +package com.woniu.commonswitch.constant; + +/** + *+ * 常量类 + * 程序员蜗牛 + *
+ * + */ +public class Constant { + + /** + * (0:关,1:开) + */ + public static final String SWITCHCLOSE = "0"; + + // .... 其他业务相关的常量 .... + + // 配置相关的常量 + public static class ConfigCode { + + // 挂号支付开关(0:关,1:开) + public static final String REG_PAY_SWITCH = "reg_pay_switch"; + // 门诊支付开关(0:关,1:开) + public static final String CLINIC_PAY_SWITCH = "clinic_pay_switch"; + + // 其他业务相关的配置常量 + // .... + } +} diff --git a/CommonSwitch/CommonSwitch/src/main/java/com/woniu/commonswitch/controller/RegController.java b/CommonSwitch/CommonSwitch/src/main/java/com/woniu/commonswitch/controller/RegController.java new file mode 100644 index 0000000..d49df9f --- /dev/null +++ b/CommonSwitch/CommonSwitch/src/main/java/com/woniu/commonswitch/controller/RegController.java @@ -0,0 +1,28 @@ +package com.woniu.commonswitch.controller; + +import com.woniu.commonswitch.service.RegService; +import com.woniu.commonswitch.util.Result; +import lombok.AllArgsConstructor; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +/** + *+ * 程序员蜗牛 + * 教你一招 SpringBoot + 自定义注解 + AOP 打造通用开关 + *
+ */ +@RestController +@RequestMapping("/api/reg") +@AllArgsConstructor +public class RegController { + + private final RegService regService; + + @GetMapping("/createOrder") + public Result createOrder() { + + return regService.createOrder(); + } +} diff --git a/CommonSwitch/CommonSwitch/src/main/java/com/woniu/commonswitch/exception/BusinessException.java b/CommonSwitch/CommonSwitch/src/main/java/com/woniu/commonswitch/exception/BusinessException.java new file mode 100644 index 0000000..7331b4c --- /dev/null +++ b/CommonSwitch/CommonSwitch/src/main/java/com/woniu/commonswitch/exception/BusinessException.java @@ -0,0 +1,22 @@ +package com.woniu.commonswitch.exception; + +/** + *+ * 自定义业务异常 + * 程序员蜗牛 + *
+ */ +public class BusinessException extends RuntimeException { + + public BusinessException() { + super(); + } + + public BusinessException(String errMsg) { + super(errMsg); + } + + public BusinessException(String errMsg, Throwable throwable) { + super(errMsg, throwable); + } +} diff --git a/CommonSwitch/CommonSwitch/src/main/java/com/woniu/commonswitch/service/RegService.java b/CommonSwitch/CommonSwitch/src/main/java/com/woniu/commonswitch/service/RegService.java new file mode 100644 index 0000000..04dadec --- /dev/null +++ b/CommonSwitch/CommonSwitch/src/main/java/com/woniu/commonswitch/service/RegService.java @@ -0,0 +1,22 @@ +package com.woniu.commonswitch.service; + +import com.woniu.commonswitch.annotation.ServiceSwitch; +import com.woniu.commonswitch.constant.Constant; +import com.woniu.commonswitch.util.Result; +import org.springframework.http.HttpStatus; +import org.springframework.stereotype.Service; + +@Service +public class RegService { + + /** + * 下单 + */ + @ServiceSwitch(switchKey = Constant.ConfigCode.REG_PAY_SWITCH) + public Result createOrder() { + + // 具体下单业务逻辑省略.... + + return new Result(HttpStatus.OK.value(), "挂号下单成功"); + } +} diff --git a/CommonSwitch/CommonSwitch/src/main/java/com/woniu/commonswitch/util/Result.java b/CommonSwitch/CommonSwitch/src/main/java/com/woniu/commonswitch/util/Result.java new file mode 100644 index 0000000..dc5fd7e --- /dev/null +++ b/CommonSwitch/CommonSwitch/src/main/java/com/woniu/commonswitch/util/Result.java @@ -0,0 +1,48 @@ +package com.woniu.commonswitch.util; + +/** + *+ * 响应对象封装 + *
+ */ +public class Result