java自定义注解使用一般是Java自定义注解+拦截器或则AOP,使用自定义注解设计框架能使项目减少大量重复代码。
一、什么是注解
以下是百科解释:
Java注解又称Java标注,是JDK5.0版本开始支持加入源代码的特殊语法元数据。
Java语言中的类、方法、变量、参数和包等都可以被标注。和Javadoc不同,Java标注可以通过反射获取标注内容。在编译器生成类文件时,标注可以被嵌入到字节码中。Java虚拟机可以保留标注内容,在运行时可以获取到标注内容。 当然它也支持自定义Java标注。
二、自定义注解所必须了解的几个元注解
@Target:描述了注解修饰的对象范围,取值在 java.lang.annotation.ElementType
- METHOD:用于描述方法
- PACKAGE:用于描述包
- PARAMETER:用于描述方法变量
- TYPE:用于描述类、接口或enum类
@Retention:设定注解保留时间,取值在 java.lang.annotation.RetentionPolicy
- SOURCE:在源文件中有效,编译过程中会被忽略
- CLASS:随源文件一起编译在class文件中,运行时忽略
- RUNTIME:在运行时有效
如下是一个注解案例,自定义注解+aop实现日志的打印。
三、案例
先导入切面所需要的依赖包
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
创建自定义注解@MyLog
1 @Target(ElementType.METHOD)
2 @Retention(RetentionPolicy.RUNTIME)
3 public @interface MyLog {
4
5 }
定义一个切面类,切点正是我们所定义的注解,这样每次使用该注解都会执行切面。
1 @Aspect // 1.表明这是一个切面类
2 @Component
3 public class MyLogAspect {
4
5 // 2. PointCut表示这是一个切点,@annotation表示这个切点切到一个注解上,后面带该注解的全类名
6 // 切面最主要的就是切点,所有的故事都围绕切点发生
7 // logPointCut()代表切点名称
8 @Pointcut("@annotation(me.zebin.demo.annotationdemo.aoplog.MyLog)")
9 public void logPointCut(){};
10
11 // 3. 环绕通知
12 @Around("logPointCut()")
13 public void logAround(ProceedingJoinPoint joinPoint){
14 // 获取方法名称
15 String methodName = joinPoint.getSignature().getName();
16 // 获取入参
17 Object[] param = joinPoint.getArgs();
18
19 StringBuilder sb = new StringBuilder();
20 for(Object o : param){
21 sb.append(o + "; ");
22 }
23 System.out.println("进入[" + methodName + "]方法,参数为:" + sb.toString());
24
25 // 继续执行方法
26 try {
27 joinPoint.proceed();
28 } catch (Throwable throwable) {
29 throwable.printStackTrace();
30 }
31 System.out.println(methodName + "方法执行结束");
32
33 }
34 }
写一个接口测试我们的注解
1 @MyLog
2 @GetMapping("/sourceC/{source_name}")
3 public String sourceC(@PathVariable("source_name") String sourceName){
4 return "你正在访问sourceC资源";
5 }
启动浏览器访问我们的接口
idea中结果显示
四、 总结
到此一个简单的自定义注解就完成了。另外,切面可以根据注解的功能选择环绕、前置、后置。对于本文日志打印最好使用前置的方式。