1. 定义注解
@Inherited@Retention(RetentionPolicy.RUNTIME)@Target(ElementType.METHOD)public @interface CheckAuth {/*** 使用SpEL表达式标识需要需要检查的房间id*/String roomId();/*** SpEL表达式标识需要被检查的用户userId*/String userId();}
2. 解析SpEL表达式的工具方法
public class SpelExpressionUtil {private static final ExpressionParser parser = new SpelExpressionParser();private static final LocalVariableTableParameterNameDiscoverer discoverer = new LocalVariableTableParameterNameDiscoverer();public static <T> T parseSpel(Method targetMethod, Object[] args, String spel, Class<T> paramType) {EvaluationContext context = new StandardEvaluationContext();String[] params = discoverer.getParameterNames(targetMethod);for (int len = 0; len < params.length; len++) {context.setVariable(params[len], args[len]);}Expression expression = parser.parseExpression(spel);return expression.getValue(context, paramType);}}
3. 编写切面
@Slf4j@Component@Aspectpublic class CheckResourceAuthProcessor {@Before(value = "@annotation(com.xxx.yyy.aspect.CheckAuth) && @annotation(c)")public void check(JoinPoint joinPoint, CheckAuth c) {// 获取方法参数值Object[] arguments = joinPoint.getArgs();// 获取methodMethodSignature signature = (MethodSignature) joinPoint.getSignature();Method method = signature.getMethod();// 获取spel表达式String roomIdSpEL = c.roomId();String userIdSpEL = c.userId();// 根据spel表达式获取真正的入参中 需要检查的变量Long roomId = SpelExpressionUtil.parseSpel(method, arguments, roomIdSpEL, Long.class);String userId = SpelExpressionUtil.parseSpel(method, arguments, userIdSpEL, String.class);///...对用户操作是否有权限进行校验}}
4. 使用注解
@CheckAuth(roomId = "#req.roomId", userId = "#operator")public void doSomething(KickOutReq req, String operator) {///...其他业务逻辑}
5. IDEA配置
在IDEA中Spring自带的SpEL表达式显示是有提示的
类似于这种
但是我们自定义的是没有提示的
我们可以加一下IDEA的提示
光标放到SpEL表达式上, Alt+Enter ,弹出, 选择 Inject language
查询spel, 选择
这下我们的IDEA就能够把这个字符串当做SpEL正常的显示了
6. @Language(“SpEL”)
IDEA的配置只能配置自己电脑, 如果你经常换电脑, 那么这个spel的语法由无法正确显示了
如果团队中所有人都使用IDEA进行开发, 这里提供一个方法, 让团队中的所有人都能自动以spel的方式查看
添加依赖
<dependency><groupId>org.jetbrains</groupId><artifactId>annotations</artifactId> <version>13.0</version><scope>provided</scope></dependency>
使用@Language 注解
@Inherited@Retention(RetentionPolicy.RUNTIME)@Target(ElementType.METHOD)public @interface CheckResourceAuth {/*** 使用SpEL表达式标识需要需要检查的房间id*/@Language("SpEL")String roomId();/*** SpEL表达式标识需要被检查的用户userId*/@Language("SpEL")String userId();}
这时候idea不需要做任何配置, 自动就能正常显示spel语法了

