浅谈 SpringBoot 中的 AOP

2018-09-12  本文已影响42人  三分灰

什么是 AOP

AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。

以上来自百度百科

SpringBoot 中 AOP 的使用

在使用之前,我们需要引入一些必要的依赖

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

spring-boot-starter-aop 即为 SpringBoot 使用 AOP 所需的依赖

新建一个切面类

package com.example.aopdemo.aspect;

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

/**
 * @author: shadow
 * @date: 18-9-10
 * @time: 上午11:33
 */
@Aspect
@Component
public class MyAspect {

    @Pointcut("within(com.example.aopdemo.service.*)")
    public void point(){}

    @Before("point()")
    public void before(){
        System.out.println("####before####");
    }

}

@Aspect 表示当前类是一个切面类,@Pointcut 用来声明一个切点,这里表示拦截 com.example.aopdemo.service 包下所有类的方法,@Before 定义你在所拦截的方法执行前要织入的逻辑。

我们在 com.example.aopdemo.service 包下有一个类 UserService

package com.example.aopdemo.service;

import org.springframework.stereotype.Service;

@Service
public class UserService {

    public void add(){
        System.out.println("UserService add");
    }

    public void del(){
        System.out.println("UserService del");
    }

    public void mod(){
        System.out.println("UserService mod");
    }

    public void get(){
        System.out.println("UserService get");
    }

}

当我们调用该类中的任意一个方法时,在方法执行前都将执行我们织入的逻辑。

####before####
UserService add
####before####
UserService del
####before####
UserService get
####before####
UserService mod

这里只是简单的打印一句话,事实上,还可以进行更多的操作。

一些常用的切点定义

/*参数匹配*/
//匹配任何以find开头且只有一个Long类型参数的方法
@Pointcut("execution(* *..find*(Long))")
public void pointA(){}

//匹配任何只有一个Long类型参数的方法
@Pointcut("args(Long)")
public void pointB(){}

//匹配任何以find开头且第一个参数类型为Long的方法
@Pointcut("execution(* *..find*(Long,..))")
public void pointC(){}

//匹配任何第一个参数为Long类型的方法
@Pointcut("args(Long,..)")
public void pointD(){}

/*对象匹配*/
//匹配被Spring托管的Bean loggerService
@Pointcut("bean(loggerService)")
public void point(){}

/*包匹配*/
//匹配service包下所有方法
@Pointcut("within(com.example.aopdemo.service.*)")
public void point(){}

//匹配service包及其子包下所有方法
@Pointcut("within(com.example.aopdemo.service..sub.*)")
public void point(){}

织入逻辑的定义还有 @After 方法执行后,@Around 方法执行前和执行后。

上一篇下一篇

猜你喜欢

热点阅读