元注解时定义注解的注解,是Java提供的用于定义注解的基本注解
注解说明@Retention是注解类,实现声明类Class,声明类别Category,声明扩展Extension@Target放在自定义注解上的上边,表明该注解可以使用的范围@Inherited允许子类继承父类的注解,在子类中可以获取使用父类注解@Documented表明这个注解是由Javadoc记录的@interface用来定义注释类型1.@Target 该注解的作用是告诉Java将自定义的注解放在什么地方,比如类、方法、构造器、变量上等。它的值是一个枚举类型,有如下属性值。
属性含义ElementType.CONSTUCTOR用于描述构造器ElementType.FIELD用于描述成员变量、对象、属性(包括enum实例)ElementType.LOCAL_VARIABLE用于描述局部变量ElementType.METHOD用于描述方法ElementType.PACKAGE用于描述包ElementType.PARAMETER用于描述参数ElementType.TYPE用于描述类、接口(包括注解类型)或enum声明2.@Retention 该注解用于说明自定义注解的生命周期,在注解中有三个生命周期
生命周期含义RententionPolicy.RUNTIME始终不会丢弃,运行期也保留该注解,可以使用发射机制读取该注解的信息。自定义的注解通常使用这种方法RetentionPolicy.CLASS类加载时丢弃,默认是这种方式RetentionPolicy.SOURCE编译阶段丢弃,自定义注解在编译结束之后就不在有意义,所以它们不会写入字节码。@Override和@SuppressWarnings都属于这类注解3.@Inherited 该注解是一个标记注解,表明被标注的类型是可以被继承的。如果一个使用了@Inherited修饰的Annotation类型被用于一个Class,则这个Annotation将被用于该Class的子类。
4.Documented 该注解表示是否将注解信息添加在Java文档中
5 @Interface 该注解用来声明一个注解,其中的每一个方法实际上是声明了一个配置参数。方法的名称就是参数的名称,返回值类型就是参数的类型。可以通过default来声明参数的默认值。
定义注解格式
public @interface 注解名 {定义体}实验结果:打开网址,网页内容为空
http://localhost:8080/lishizheng控制台输出如下结果
TestAnnotation 参数: 测试Annotation参数 测试自定义注解项目结构 0添加依赖 pom.xml 由于使用AOP方式,需要添加如下依赖
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> </dependency>1.创建自定义注解类
MyTestAnnotation.java 代码解释
使用@Target注解标注作用范围使用@Retention注解标注生命周期使用@Documented将注解信息添加在Java文档中 package com.example.demo; import org.springframework.stereotype.Component; import java.lang.annotation.*; @Target({ElementType.METHOD,ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented @Component public @interface MyTestAnnotation { String value(); }2.实现业务逻辑 以AOP方式实现业务逻辑 TestAnnotationAspect.java
package com.example.demo; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.*; import org.aspectj.lang.reflect.MethodSignature; import org.omg.PortableInterceptor.SYSTEM_EXCEPTION; import org.springframework.stereotype.Component; import java.lang.invoke.MethodHandle; import java.lang.reflect.Method; @Aspect @Component public class TestAnnotationAspect { //拦截被MyTestAnnotation注解的方法;如果需要拦截指定包指定规则名称的方法,则可以使用表达式execution(...) @Pointcut("@annotation(com.example.demo.MyTestAnnotation)") public void myAnnotationPointCut(){ } @Before("myAnnotationPointCut()") public void before(JoinPoint joinPoint)throws Throwable{ MethodSignature sign=(MethodSignature) joinPoint.getSignature(); Method method=sign.getMethod(); MyTestAnnotation annotation=method.getAnnotation(MyTestAnnotation.class); //获取注解参数 System.out.println("TestAnnotation 参数: "+annotation.value()); } }3.使用自定义注解 在需要使用的地方使用自定义注解,直接添加注解名
TestController.java
package com.example.demo; import org.springframework.context.annotation.EnableAspectJAutoProxy; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import java.util.ArrayList; import java.util.List; @RestController @EnableAspectJAutoProxy public class TestController { @RequestMapping("/lishizheng") @MyTestAnnotation("测试Annotation参数") public void testAnnnotation(){ System.out.println("测试自定义注解"); } }