学不动了就进厂|

无情歌神

园龄:6年9个月粉丝:3关注:1

AOP自定义注解实现指定字段加密脱敏

一、自定义注解

解密自定义注解略

1.方法上注解

@Documented
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface CryptMethod {
}

2.字段上注解

@Documented
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface CryptData {
}

自定义注解解析

  • 1.@Documented:注解类型信息会被 JavaDoc 工具提取到帮助文档中。
  • 2.@Target:指定一个注解的使用范围,value 是 java.lang.annotation.ElementType 枚举类型的数组
名称 说明
CONSTRUCTOR 用于构造方法
FIELD 用于成员变量(包括枚举常量)
LOCAL_VARIABLE 用于局部变量
METHOD 用于方法
PACKAGE 用于包
PARAMETER 用于类型参数(JDK 1.8新增)
TYPE 用于类、接口(包括注解类型)或 enum 声明
  • 3.@Retention:用于描述注解的生命周期,也就是该注解被保留的时间长短 value 是 java.lang.annotation.RetentionPolicy枚举类型的数组
名称 说明 使用
SOURCE 在源文件中有效 检查性的操作
CLASS 在 class 文件中有效 编译时进行预处理操作
RUNTIME 在运行时有效 运行时去动态获取注解信息

SOURCE < CLASS < RUNTIME

  • 4.@Inherited:使用被该注解修饰的注解的Class类,其子类拥有该注解
  • 5.@Repeatable:在需要对同一种注解多次使用时,使用此注解修饰
  • 6.@Order:优先级,Ordered枚举默认为LOWEST_PRECEDENCE还有HIGHEST_PRECEDENCE

二、构造AOP逻辑

@Aspect
@Component
@Log4j2
public class CryptAop {
    @Pointcut("@annotation(com.example.demo.annotation.crypt.CryptMethod)")
    public void cryptPointCut(){
    }

    @Pointcut("@annotation(com.example.demo.annotation.crypt.EnCryptMethod)")
    public void encryptPointCut(){
    }

    @Around("cryptPointCut()")
    public Object around(ProceedingJoinPoint joinPoint){
        Object responseObj = null;
        try {
            responseObj = joinPoint.proceed();
            Field[] fields = responseObj.getClass().getDeclaredFields();
            log.info(fields.length);
            for (Field field : fields) {
                log.info(field.getName());
                if (field.isAnnotationPresent(CryptData.class)){
                    if (!field.isAccessible()){
                        field.setAccessible(true);
                    }
                    Object o = field.get(responseObj);
                    System.out.println("获取的字段值"+ JSONObject.toJSONString(o));
                    field.set(responseObj, "加密啦");
                }
            }
        } catch (Throwable e) {
            e.printStackTrace();
        }
        return responseObj;
    }

    @Around("encryptPointCut()")
    public Object encrypt(ProceedingJoinPoint joinPoint){
        Object responseObj = null;
        try {
            responseObj = joinPoint.proceed();
            Field[] fields = responseObj.getClass().getDeclaredFields();
            log.info(fields.length);
            for (Field field : fields) {
                log.info(field.getName());
                if (field.isAnnotationPresent(EnCryptData.class)){
                    if (!field.isAccessible()){
                        field.setAccessible(true);
                    }
                    Object o = field.get(responseObj);
                    System.out.println("获取的字段值"+ JSONObject.toJSONString(o));
                    field.set(responseObj, "解密啦");
                }
            }
        } catch (Throwable e) {
            e.printStackTrace();
        }
        return responseObj;
    }
}

三、调用方法

@Service
public class PersonServiceImpl implements PersonService {
    @Override
    @CryptMethod
    public Person setNewPerson() {
        Person person = new Person();
        person.setPhoneNumber("110");
        return person;
    }

    @Override
    @EnCryptMethod
    public Person getPerson() {
        Person person = new Person();
        person.setPhoneNumber("110");
        return person;
    }
}

四、实体类

@Data
public class Person implements Serializable {
    private static final long serialVersionUID = 6496689746718741955L;
    //id
    private Integer id;
    //姓名
    private String name;
    //手机号
    @CryptData
    @EnCryptData
    private String phoneNumber;
}

本文作者:无情歌神

本文链接:https://www.cnblogs.com/zjq97/p/16091494.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   无情歌神  阅读(1008)  评论(2编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
展开