首页 > 编程语言 > 详细

springboot#aop

时间:2020-01-19 17:42:39      阅读:84      评论:0      收藏:0      [点我收藏+]

一, 目标:

自定义注解,完成通过自定义注解注释类方法,实现被自定义注解注释的方法执行特定aop逻辑,实现对被注释方法的功能增强。

比如可以开发一个自定义日志记录的注解,在需要记录日志的方法上使用注解,去记录方法的名称,传入的参数,执行的结果,把这些信息记录到日志文件。

 

二,实现:

1. 添加依赖

技术分享图片
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>
View Code

 

2. 自定义注解

技术分享图片
public @interface TestAnnotation {
}
View Code

 

3. 编写注解处理器,注解处理器中有通过aop对注解注释的方法的逻辑增强。

技术分享图片
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class TestAnnotationHandler {
    @Pointcut("@annotation(com.haonan.tt.annotation.TestAnnotation)")
    public void jPoint() {
    }

    @Before("jPoint()")
    public void before(JoinPoint jp) {
        System.out.println("------------before--------------------");
    }

    /**
     * 具体返回值,按照业务需求来做
     *
     * @param joinPoint
     * @throws Throwable
     */
    @Around("jPoint()")
    public void doAround(ProceedingJoinPoint joinPoint) throws Throwable {
        System.out.println("进入切面");
        joinPoint.proceed();
        System.out.println("离开切面");
    }

    @After("jPoint()")
    public void after(JoinPoint jp) {
        System.out.println("------------after--------------------");
    }
}
View Code

 

4. 使用自定义注解

技术分享图片
@RestController
public class UserController {

    @Autowired
    private UserService userService;

    @TestAnnotation
    @GetMapping("/")
    public void hello() {
        // logic
    }
}
View Code

 

 

5. 后话

在进行切面编程的过程中,至少涉及到切点,和切面,这两个概念,

切面 = 切点 + 一些通用的增强逻辑,比如上述代码中的:

@Before("jPoint()")
@Around("jPoint()")
@After("jPoint()")

这三个注解修饰的方法就是切面,切面可以对切点的逻辑进行增强,

换言之,切面修改了切点的业务逻辑。在spring中,最为常见的切点就是方法,即method,一个个函数,但显然这里的切点是注解,即annotation。

 

切点,通常是一个函数,即方法,一个类的成员函数,但是在springboot中,切注解的更为常见。可以通过:@Pointcut 这个注解定义一个切点,

定义好的切点,可以被多个切面使用。如本文中示例那样。也可以不单独定义如 @Before("jPoint()") == @Before("@annotation(com.haonan.tt.annotation.TestAnnotation)") 。

 

另外,可以通过execution表达式定义切点,然后在 @Before ,@Around, @After中直接使用。

技术分享图片
execution(
    modifiers-pattern?      // 访问修饰符 public private 等,?问号表示可以省略
    ret-type-pattern        // 返回值类型正则模式,* 表示任意返回类型
    declaring-type-pattern? // 方法所在类的全路径名称正则模式,可以使用通配符,当然?问号表示可以省略
    name-pattern(param-pattern) // 方法名称的正则模式,以及括号内的参数正则模式,参数正则模式通常写 .. 表示任意参数
    throws-pattern?             // 抛出异常的正则模式,?问号表示可以省略
) 

// 方法所在类的全路径名称正则模式 与 方法名称的正则模式 之间同点.进行连接

//表示匹配所有方法 
execution(* *(..)) 

//表示匹配com. example.controller中所有的public方法  
execution(public * com.example.controller.*(..))  

//表示匹配com. example.controller包及其子包下的所有方法
execution(* com.example.controller..*.*(..))  
View Code

springboot#aop

原文:https://www.cnblogs.com/luohaonan/p/12214515.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!