代码背景

为了实现不同模块下业务代码拥有统一的权限校验框架,尽量在不动业务代码的情况下同时做到横向越权和纵向越权

代码目的

自定义注解+AOP:目的是为了减少权限代码对业务代码的入侵,做到业务代码与权限校验代码的解耦,同时使所有模块能够拥有统一的权限校验注解,避免各个模块使用不同的权限实现方式。
策略模式:使用策略模式是为了将各个模块的权限校验代码独立出来,做到各个模块之间的权限代码互不影响,做到解耦。
在这里插入图片描述

代码实现

1.抽象接口

将权限校验器抽象为一个接口,各个模块的权限校验代码实现该接口当中的方法

public interface Validator {
    /**
     * 权限校验方法
     *
     * @return 权限校验结果
     */
    boolean authCheckFunc(HashMap<String,String> map);
}

2.实现类

默认实现类

import java.util.HashMap;

public class DefaultValidator implements Validator{
    public boolean authCheckFunc(HashMap<String, String> map) {
        // 这里面是具体实现方法
        System.out.println("这是默认校验器 DefaultValidator");
        return true;
    }
}

其余不同模块实现类

import java.util.HashMap;

public class AuthValidatorOne implements Validator{

    public boolean authCheckFunc(HashMap<String, String> map) {
        System.out.println("这是第1个校验器 AuthValidatorOne");
        return true;
    }
}

第二个模块的实现类

import java.util.HashMap;

public class AuthValidatorTwo implements Validator{
    public boolean authCheckFunc(HashMap<String, String> map) {
        System.out.println("这是第2个校验器 AuthValidatorTwo");
        return true;
    }
}

如果后续还有其他模块只需要继续新增校验器,并且实现校验接口就可以了。

3.自定义注解

自定义注解当中的值放需要进行运行的校验器数组,需要运行那些模块的校验器,就在注解当中放对应的校验器,如果不放,就运行默认的校验器。

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface AuthCheck {
    Class<? extends Validator>[] validators() default {DefaultValidator.class};
}

4.aop代码

在aop当中解析自定义注解当中的校验器,然后进行运行校验器。
最终越权校验可以在aop当中获取最终的结果,也可以在各自的校验器当中进行越权拦截。

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.util.HashMap;

@Aspect
@Component
public class AuthProcessAop {
    @Pointcut("@annotation(AuthCheck)")
    public void authCheck(){}

    @Before("AuthProcessAop.authCheck()")
    public void fliter(JoinPoint joinPoint) {
        try {
            String methodName = joinPoint.getSignature().getName();
            Class<?> clazz = joinPoint.getTarget().getClass();
            Class<?>[] par = ((MethodSignature) joinPoint.getSignature()).getParameterTypes();
            Method method = clazz.getMethod(methodName, par);
            AuthCheck annotation = method.getAnnotation(AuthCheck.class);
            for (Class<? extends Validator> validator : annotation.validators()) {
                // 如果为了效率可以用多线程来进行执行校验器方法
                Validator instance = validator.newInstance();
                instance.authCheckFunc(new HashMap<String, String>());
            }
        } catch (Exception e) {
            System.out.println("这里进行异常处理");
        }
    }
}

5.测试代码及结果

@AuthCheck(validators = {AuthValidatorOne.class, AuthValidatorTwo.class})
    public void test() {
        System.out.println("这时需要被测试的方法");
    }

在这里插入图片描述

更多推荐