最近大概的学习了一下 Spring Boot AOP 入门 相关的知识,一开始对这个其实也不太懂,在B站和网上看了很多资料,有了一点点自己的理解。在这里写博客记录一下,顺便把遇到的一些问题也写下来。

1.什么是AOP?

百度一下

这种在运行时,动态地将代码切入到类的指定方法、指定位置上的编程思想就是面向切面的编程。

AOP是Spring提供的关键特性之一。AOP即面向切面编程,是OOP编程的有效补充。

使用AOP技术,可以将一些系统性相关的编程工作,独立提取出来,独立实现,然后通过切面切入进系统。

从而避免了在业务逻辑的代码中混入很多的系统相关的逻辑——比如权限管理,事物管理,日志记录等等。

这些系统性的编程工作都可以独立编码实现,然后通过AOP技术切入进系统即可。从而达到了 将不同的关注点分离出来的效果

我自己的理解

个人理解:aop(面向切面编程)就是在OOP(面向对象)编程过程需要将一些与我们业务代码无关的 例如操作日志 等代码使用aop的方法分离出来,降低代码的耦合性,易于代码的维护。

2.AOP相关概念

  1. Aspect :切面,切入系统的一个切面。比如事务管理是一个切面,权限管理也是一个切面;
  2. Join point :连接点,也就是可以进行横向切入的位置;
  3. Advice :通知,切面在某个连接点执行的操作(分为: Before advice , After returning advice , After throwing advice , After (finally) advice , Around advice );
  4. Pointcut :切点,符合切点表达式的连接点,也就是真正被切入的地方;

3.日志操作示例

传统方法

先看一下service下面的UserService

@Transactional
@Service
public class UserService {
    @Autowired
    UserMapper userMapper;

     public  List<User> queryAllUser(){
        return  userMapper.selectList(null);
    }
}

假如我们要在控制台输出一个service下面queryAllUser方法执行的时间,一般可能会使用下面的方法:

@Slf4j
@Controller
public class UserController {
    @Autowired
    private UserService userService;

    @RequestMapping(value = "/",method = RequestMethod.GET)
    @ResponseBody
    public List<User> queryAllUser(){
        long startTime = System.currentTimeMillis();
        List<User> users =userService.queryAllUser();
        long endTime = System.currentTimeMillis();
        log.info("[service]---[queryAllUser]---[方法]---执行时间:"+(endTime-startTime));
        return users;
    }
}

但是如果所有的操作都要这样去,日志的代码全部写在业务逻辑代码里面。这二者本来是没有关系的,而且也不利于代码的维护。下面来看看用aop如何实现:

AOP实现

引入依赖

<dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjrt</artifactId>
    <version>1.8.7</version> </dependency>
<dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjweaver</artifactId>
    <version>1.8.7</version>
</dependency>

另外说一下,这里不需要再单独引入spring-boot-starter-aop 依赖,现在spring boot已经有默认的aop依赖,如果引入很可能导致版本冲突。

新建Aspect类

新建一个IndexAspect切面类,并编写下面的代码

@Component
@Aspect
@Slf4j
public class IndexAspect {
    //execution 切点表达式
    @Pointcut("execution(* live.yremp.aop.service..*.queryAllUser(..))")
    private void queryALlServicePointCut(){

    }
    @Before("live.yremp.aop.aspect.IndexAspect.queryALlServicePointCut()")
    private void beforeQueryAllUserService(){
        log.info("[service]---[queryAllUser]---[方法]--->开始执行");
    }

    @After("live.yremp.aop.aspect.IndexAspect.queryALlServicePointCut()")
    private  void afterQueryAllUserService(){
        log.info("[service]---[queryAllUser]---[方法]--->执行结束");
    }

    @Around("live.yremp.aop.aspect.IndexAspect.queryALlServicePointCut()")
    private Object aroundQueryAllUserService(ProceedingJoinPoint point){
        long startTime = System.currentTimeMillis();
        Object proceed =null;
        try{
            proceed = point.proceed();
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }
        long endTime = System.currentTimeMillis();
        log.info("[service]---[queryAllUser]---[方法]---执行时间:"+(endTime-startTime));
        return proceed;
    }
}

首先需要给这个切面类加上 @Component 、 @Aspect 注解,简单的介绍一下这个代码:

@Aspect切面注解
@Pointcut切点注解
@Before、@Around、@After增强类型

运行效果

AspectJ的Execution表达式

本来想写一下的,但是发现比较多,就先给一下Execution表达式的结构:

execution(<修饰符模式>? <返回类型模式> <方法名模式>(<参数模式>) <异常模式>?) 

详细的我也去查了一下,这里直接给出链接,【传送门】 ,讲的比较详细。Spring Boot AOP 入门就到处结束,后面有时间我也会继续学习并且更新博客。

标签云

ajax AOP Bootstrap cdn Chevereto CSS Docker Editormd Hexo IDEA JavaScript jsDeliver JS樱花特效 Linux markdown Maven MyBatis MyBatis-plus MySQL Pictures Sakura SEO Spring Boot SpringMVC SSR Thymeleaf V2ray Vue Web WebSocket Wechat Social WordPress Yoast SEO 代理 分页 图床 小幸运