0
点赞
收藏
分享

微信扫一扫

springboot 集成aop面向切面编程

云上笔记 2021-09-21 阅读 102
springboot

aop的应用场景

像spring的申明式事务、spring缓存实现、权限管理、多数据源、数据库读写分离、统计请求执行时间、系统日志等可用aop的方式实现。利于解耦

aop的相关概念

springboot集成aop功能

引入依赖
        <!--引入AOP依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>
定义目标切入点

通常是类的方法。这里使用controller中的一个方法

package com.springboot.study.demo1.controller;
import com.baomidou.mybatisplus.extension.api.R;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
 /**
 *@description: AopController 
 *@author: yinkai
 *@create: 2020/2/25 9:51
 */
@RestController
@RequestMapping("/aop")
public class AopController {
    /**
     *@description: AopController 
     *@author: yinkai
     *@create: 2020/2/27 11:55
     */
    @RequestMapping("/testAop")
    public R testAop(){

        System.out.println("执行业务逻辑");
        return R.ok("ok");
    }
}
定义切面类
package com.springboot.study.demo1.aop;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
/**
 * @desc: 定义切面
 * @author: yinkai
 **/
@Aspect
@Component
public class BrokerAspect {

    /**
     * 定义切入点,切入点为com.springboot.study.demo1.controller.AopController中的所有函数
     *通过@Pointcut注解声明频繁使用的切点表达式
     */
    @Pointcut("execution(public * com.springboot.study.demo1.controller.AopController.*(..)))")
    public void BrokerAspect(){

    }

    /**
     * @description  前置通知
     */
    @Before("BrokerAspect()")
    public void doBeforeFunction(){
        System.out.println("前置通知执行!");
    }

    /**
     * @description  后置通知
     */
    @After("BrokerAspect()")
    public void doAfterFunction(){
        System.out.println("后置通知执行!");
    }

    /**
     * @description  返回通知
     */
    @AfterReturning("BrokerAspect()")
    public void doAfterReturningFunction(){
        System.out.println("返回通知执行!");
    }

    /**
     * @description  异常通知
     */
    @AfterThrowing("BrokerAspect()")
    public void doAfterThrowingFunction(){
        System.out.println("异常通知执行!");
    }

}

配置完毕后运行工程,访问 url,http://localhost:8080/test/aop/testAop 调用切点方法testAop()
看看控制台

使用环绕通知

环绕通知功能强大,包括了前置通知,返回通知 和 异常通知的功能

修改切面类,添加方法


   
    /**
     * @description  使用环绕通知
     */
    @Around("BrokerAspect()")
    public void doAroundFunction(ProceedingJoinPoint point){
        try{
            System.out.println("环绕通知: 前置");
            R proceed = (R) point.proceed();
            System.out.println(proceed);
            System.out.println("环绕通知: 后置");
        }
        catch(Throwable e){
            System.out.println("环绕通知: 出现异常");
        }
    }

如果出现异常,则异常通知代替了后置通知。后置通知不会被执行


切点表达式说明

通知方法中得到目标方法的参数

目标方法修改,添加 int cs 参数

    @RequestMapping("/testAop")
    public R testAop(int cs){

        System.out.println("执行业务逻辑");
        return R.ok("ok");
    }

通知方法中如何得到目标方法testAop()的参数 int cs?

方法1:

定义切入点处修改

    @Pointcut("execution(public * com.springboot.study.demo1.controller.AopController.*(int)) && args(cs))")
    public void BrokerAspect(int cs){

    }

通知方法修改

    /**
     * @description  使用环绕通知
     */
    @Around("BrokerAspect(cs)")
    public void doAroundFunction(ProceedingJoinPoint point,int cs) throws Throwable {
            System.out.println("获得参数cs==>"+cs);
            R proceed = (R) point.proceed();
            System.out.println(proceed);
    }

修改完毕后,重启工程。访问 http://localhost:8080/test/aop/testAop?cs=123

方法2:

 /**
     * @description 使用环绕通知
     */
    @Around("BrokerAspect()")
    public Object doAroundFunction(ProceedingJoinPoint point) throws Throwable {
        Object target = point.getTarget().getClass().getName();
        System.out.println("调用者==>" + target);
        //通过joinPoint.getArgs()获取Args参数
        Object[] args = point.getArgs();//2.传参
        for (int i = 0; i < args.length; i++) {
            System.out.println("参数==>" + args[i]);

        }
        return point.proceed();
    }
举报

相关推荐

0 条评论