一、自定義注解
解密自定義注解略
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;
}