最近大概的学习了一下 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 GC Hexo IDEA IPA JavaScript jsDeliver JS樱花特效 JVM Linux markdown Maven MyBatis MyBatis-plus MySQL Pictures Sakura SEO shadowrocket Spring Boot Spring Cloud Spring Cloud Alibaba SpringMVC SSR Thymeleaf V2ray Vue Web WebSocket Wechat Social WordPress Yoast SEO 代理 分页 图床 小幸运 苹果iOS国外账号 苹果IOS账号