AOP自定義註解實現指定欄位加密脫敏
阿新 • • 發佈:2022-04-15
目錄
一、自定義註解
解密自定義註解略
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;
}