Spring Boot使用AOP的正确姿势

一、为什么需要面向切面编程?

面向工具编程(OOP)的利益是显而易见的,瑕玷也同样显著。当需要为多个不具有继续关系的工具添加一个公共的方式的时刻,例如日志纪录、性能监控等,若是接纳面向工具编程的方式,需要在每个工具内里都添加相同的方式,这样就产生了较大的重复工作量和大量的重复代码,不利于维护。面向切面编程(AOP)是面向工具编程的弥补,简朴来说就是统一处置某一“切面”的问题的编程头脑。若是使用AOP的方式举行日志的纪录和处置,所有的日志代码都集中于一处,不需要再每个方式内里都去添加,极大减少了重复代码。

二、Spring AOP术语

Spring Boot使用AOP的正确姿势

通知(Advice)包含了需要用于多个应用工具的横切行为,完全听不懂,没关系,通俗一点说就是界说了“什么时刻”和“做什么”。

连接点(Join Point)是程序执行历程中能够应用通知的所有点。

切点(Poincut)是界说了在“什么地方”举行切入,哪些连接点会获得通知。显然,切点一定是连接点。

切面(Aspect)是通知和切点的连系。通知和切点配合界说了切面的全部内容——是什么,何时,何地完乐成效。

引入(Introduction)允许我们向现有的类中添加新方式或者属性。

织入(Weaving)是把切面应用到目的工具并建立新的署理工具的历程,分为编译期织入、类加载期织入和运行期织入。

三、Spring Boot AOP实战

3.1 引入依赖

Spring Boot使用AOP需要添加spring-boot-starter-aop依赖,如下:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-aop</artifactId>
</dependency>

不需要再添加aspectjweaver的依赖了,由于spring-boot-starter-aop包含了aspectjweaver,而且版本是较新的版本,若是在添加老版本(如1.5.4)启动会报错。
Spring Boot使用AOP的正确姿势

3.2 编写用于阻挡的bean

直接界说一个controller,代码如下:

@RestController
public class AopController {

    @RequestMapping("/hello")
    public String sayHello(){
        System.out.println("hello");
        return "hello";
    }
}

3.3 界说切面

Spring接纳@AspectJ注解对POJO举行标注,该注解解释该类不仅仅是一个POJO,照样一个切面。切面是切点和通知的连系,那么界说一个切面就需要编写切点和通知。在代码中,只需要添加@Aspect注解即可。

3.3.1 界说切点

切点是通过@Pointcut注解和切点表达式界说的。

@Pointcut注解可以在一个切面内界说可重用的切点。

深入探究JVM之对象创建及分配策略

由于Spring切面粒度最小是到达方式级别,而execution表达式可以用于明确指定方式返回类型,类名,方式名和参数名等与方式相关的部件,而且现实中,大部分需要使用AOP的营业场景也只需要到达方式级别即可,因而execution表达式的使用是最为普遍的。如图是execution表达式的语法:

execution示意在方式执行的时刻触发。以“”开头,解释方式返回值类型为随便类型。然后是全限制的类名和方式名,“”可以示意随便类和随便方式。对于方式参数列表,可以使用“..”示意参数为随便类型。若是需要多个表达式,可以使用“&&”、“||”和“!”完成与、或、非的操作。

Spring Boot使用AOP的正确姿势

3.3.2 界说通知

通知有五种类型,划分是:

前置通知(@Before):在目的方式挪用之前挪用通知

后置通知(@After):在目的方式完成之后挪用通知

围绕通知(@Around):在被通知的方式挪用之前和挪用之后执行自界说的方式

返回通知(@AfterReturning):在目的方式乐成执行之后挪用通知

异常通知(@AfterThrowing):在目的方式抛出异常之后挪用通知

代码中界说了三种类型的通知,使用@Before注解标识前置通知,打印“beforeAdvice…”,使用@After注解标识后置通知,打印“AfterAdvice…”,使用@Around注解标识围绕通知,在方式执行前和执行之后划分打印“before”和“after”。这样一个切面就界说好了,代码如下:

@Aspect
@Component
public class AopAdvice {

    @Pointcut("execution (* com.shangguan.aop.controller.*.*(..))")
    public void test() {

    }

    @Before("test()")
    public void beforeAdvice() {
        System.out.println("beforeAdvice...");
    }

    @After("test()")
    public void afterAdvice() {
        System.out.println("afterAdvice...");
    }

    @Around("test()")
    public void aroundAdvice(ProceedingJoinPoint proceedingJoinPoint) {
        System.out.println("before");
        try {
            proceedingJoinPoint.proceed();
        } catch (Throwable t) {
            t.printStackTrace();
        }
        System.out.println("after");
    }

}

3.4 启动测试

完成之后的代码结构如图所示:

Spring Boot使用AOP的正确姿势

运行AopApplication,在浏览器接见http://localhost:8080/hello,不出意外,控制台输出如图所示:

Spring Boot使用AOP的正确姿势

原创文章,作者:28qn新闻网,如若转载,请注明出处:http://www.28qn.com/archives/24869.html