自定义注解
自定一注解: 一:创建一个如:xyf的注解 1.创建Annotation 或者创建一个类,将class改成@Interface
这样就定义了一个xyf注解
注解默认是可以加在方法,类,属性……上面 若需要定义一个指定位置的注解,需要使用到元注解@Target 如:需要定义一个在方法上的注解
这样定义在类上就回报错
参考文档如下:
@Target:注解的作用目标
@Target(ElementType.TYPE)——接口、类、枚举、注解
@Target(ElementType.FIELD)——字段、枚举的常量
@Target(ElementType.METHOD)——方法
@Target(ElementType.PARAMETER)——方法参数
@Target(ElementType.CONSTRUCTOR) ——构造函数
@Target(ElementType.LOCAL_VARIABLE)——局部变量
@Target(ElementType.ANNOTATION_TYPE)——注解
@Target(ElementType.PACKAGE)——包
@Retention:注解的保留位置
RetentionPolicy.SOURCE:这种类型的Annotations只在源代码级别保留,编译时就会被忽略,在class字节码文件中不包含。
RetentionPolicy.CLASS:这种类型的Annotations编译时被保留,默认的保留策略,在class文件中存在,但JVM将会忽略,运行时无法获得。
RetentionPolicy.RUNTIME:这种类型的Annotations将被JVM保留,所以他们能在运行时被JVM或其他使用反射机制的代码所读取和使用。
@Document:说明该注解将被包含在javadoc中
@Inherited:说明子类可以继承父类中的该注解
我们的注解,默认编译的时候会被忽略 ,所以还需要用到注解@
@Retention(RetentionPolicy.RUNTIME) 1、RetentionPolicy.SOURCE:注解只保留在源文件,当Java文件编译成class文件的时候,注解被遗弃; 2、RetentionPolicy.CLASS:注解被保留到class文件,但jvm加载class文件时候被遗弃,这是默认的生命周期; 3、RetentionPolicy.RUNTIME:注解不仅被保存到class文件中,jvm加载class文件之后,仍然存在;
如果需要定义注解中有属性 如:xyf(value="xxx",notes="xxxx") 需要在注解中写上
这样就可以
如需定义默认值,加上default:
若我们需要定义一个注解实现某种功能,如加上注解,获取注解的value然后打印出来,方法如下: 引入包:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
然后写一个切面 功能写在里面就行了
package com.xpmi.confing;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import java.lang.reflect.Method;
@Aspect
@Component
public class xyfUtil {
@Pointcut("@annotation(com.xpmi.confing.xyf)")
public void xyf() {
}
@Around(value = "xyf()")
public Object print(ProceedingJoinPoint joinPoint) throws Throwable {
// 获取执行方法的类的名称(包名加类名)
/*String className = joinPoint.getTarget().getClass().getName();*/
Class z= joinPoint.getTarget().getClass();
// 获取实例和方法
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Method method = signature.getMethod();
boolean b=z.isAnnotationPresent(xyf.class);
xyf x=method.getAnnotation(xyf.class);
System.out.println(x.value());
System.out.println(b);
// 执行方法获取返回值
Object proceed = joinPoint.proceed();
// 返回,去执行请求的方法
return proceed;
}
}
创建一个对返回结果进行处理的注解:
package com.xpmi.confing;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestBody;
import java.lang.reflect.Method;
@Aspect
@Component
public class xyfUtil {
@Pointcut("@annotation(com.xpmi.confing.xyf)")
public void xyf() {
}
//用于测试
/*@AfterReturning(value = "xyf()",returning = "rvt")
public Object ss(JoinPoint joinPoint, Object rvt){
System.out.println(rvt);
return "---"+rvt;
}*/
@Around(value = "xyf()")
public Object print(ProceedingJoinPoint joinPoint) throws Throwable {
// 获取执行方法的类的名称(包名加类名)
/*String className = joinPoint.getTarget().getClass().getName();*/
Class z= joinPoint.getTarget().getClass();
// 获取实例和方法
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Method method = signature.getMethod();
boolean b=z.isAnnotationPresent(xyf.class);
xyf x=method.getAnnotation(xyf.class);
//获取定义在属性上的value值
/* z.getDeclaredField("value");*/
System.out.println(x.value());
/*System.out.println(b);*/
// 执行方法获取返回值
Object proceed = joinPoint.proceed();
//这个方法是先去运行方法获取返回值--主要是这一步
Object obj = joinPoint.proceed();//调用执行目标方法
obj=obj+"sss";
// 返回,去执行请求的方法
return obj;
}
}
元注解: @Target注解,是专门用来限定某个自定义注解能够被应用在哪些Java元素上面的 @Retention注解,翻译为持久力、保持力。即用来修饰自定义注解的生命力。 注解的生命周期有三个阶段:1、Java源文件阶段;2、编译到class文件阶段;3、运行期阶段。同样使用了RetentionPolicy枚举类型定义了三个阶段 @Documented注解,是被用来指定自定义注解是否能随着被定义的java文件生成到JavaDoc文档当中 @Inherited注解,是指定某个自定义注解如果写在了父类的声明部分,那么子类的声明部分也能自动拥有该注解。@Inherited注解只对那些@Target被定义为ElementType.TYPE的自定义注解起作用。
如果我们要获得的注解是配置在方法上的,那么我们要从Method对象上获取;如果是配置在属性上,就需要从该属性对应的Field对象上去获取,如果是配置在类型上,需要从Class对象上去获取。总之在谁身上,就从谁身上去获取! isAnnotationPresent(Class<? extends Annotation> annotationClass)方法是专门判断该元素上是否配置有某个指定的注解; getAnnotation(Class annotationClass)方法是获取该元素上指定的注解。之后再调用该注解的注解类型元素方法就可以获得配置时的值数据; 反射对象上还有一个方法getAnnotations(),该方法可以获得该对象身上配置的所有的注解。它会返回给我们一个注解数组,需要注意的是该数组的类型是Annotation类型,这个Annotation是一个来自于java.lang.annotation包的接口。
可以参考文档:https://blog.csdn.net/csdn_meng/article/details/90042731
注意:本文归作者所有,未经作者允许,不得转载