创建一个springboot项目
下一步然后直接finish即可。
引入aop的依赖,通过aop实现自定义注解(不需要指定版本,spring-boot-starter的包会自动匹配版本)
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
创建一个注解类
创建类的时候选择@Annotation
创建完成之后,在类上按一下@就会有你写的这个注解
package com.example.customannotation.common;
import java.lang.annotation.*;
/**
* @desc: 自定义注解
* @author: LiuChang
* @since: 2021/8/31
*
* @Documented 注解信息会被添加到Java文档中
* @Target(ElementType.XXX) 指定注解修饰的范围、类型
* @Retention(RetentionPolicy.XXX) 被注解的注解需要保留多久
* @Inherited – 是否允许子类继承该注解
*/
@Documented
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface CustomAnno {
//ElementType.METHOD 这里是对使用此注解的方法进行aop切面处理
//注解中定义的内容
}
解释一下具体的参数的意义:
@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只在源代码级别保留,编译时就会被忽略 @Retention(RetentionPolicy.CLASS) —— 这种类型的Annotations编译时被保留,在class文件中存在,但JVM将会忽略 @Retention(RetentionPolicy.RUNTIME) —— 这种类型的Annotations将被JVM保留,所以他们能在运行时被JVM或其他使用反射机制的代码所读取和使用. |
创建一个aop,定义切点
针对加了自定义注解的方法进行一些操作,操作主要包括:调用方法前-调用方法后-方法出现异常-方法正常返回等
package com.example.customannotation.common;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
/**
* @desc: 自定义注解的aop
* @author: LiuChang
* @since: 2021/8/31
* @Aspect 一定要有!!!
*/
@Aspect
@Component
public class CustomAspect {
//@Pointcut 需要定义切点的位置 @annotation(xxx) 获取自定义注解对象
//声明一个切点,切点就是我们自定义注解类的位置
@Pointcut("@annotation(com.example.customannotation.common.CustomAnno)")
private void customAnno(){
System.out.println("point Cut");
}
/**
* 一个环绕通知
* @Around()
*/
@Around("customAnno()")
public void advice(ProceedingJoinPoint proceedingJoinPoint) throws Throwable{
System.out.println("Around Begin");
proceedingJoinPoint.proceed();//执行到这里开始走进来的方法体(必须声明)
System.out.println("Around End");
}
//当想获得注解里面的属性,可以直接注入改注解
//方法可以带参数,可以同时设置多个方法用&& @Before 切点执行前
@Before("customAnno()")
public void record(JoinPoint joinPoint) {
System.out.println("Before");
}
// @After切点执行后的操作
@After("customAnno()")
public void after() {
System.out.println("After");
}
}
@Before, 前置通知,方法前执行 @Around, 环绕增强,目标方法所执行前后所执行的一些代码 @AfterReturning, 处理完请求,返回的内容 @AfterThrowing, 目标方法抛出异常后执行 @After 后置通知,方法后执行 |
---|
自定义注解测试
创建一个controller,测试我们的自定义注解是否生效,使用@RestController需要添加web依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
package com.example.customannotation.common;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @desc: 测试自定义注解是否生效
* @author: LiuChang
* @since: 2021/8/31
*/
@RestController
public class TestController {
@CustomAnno
@RequestMapping("/test")
public void getLog(){
System.out.println("调用自定义注解");
}
}
然后使用postman进行访问测试
IDEA 控制台打印的结果:
Around Begin
Before
调用自定义注解
After
Around End
主要就是围绕所被注解的方法进行额外操作。
微信公众号:FluencyHome (程序员部落) 同步更新,欢迎关注,方便随时查看文章。