• Spring-----AOP面向切面


    AOP(Aspect Oriented Programming ) 面向切面 编程 种编程范式,指导开发者如何组织程序 结构
    -- OOP(Object Oriented Programming) 面向对象编程
    作用:在不惊动原始设计的基础上为其进行功能增强
    Spring 理念:无入侵式 / 无侵入式

    本讲解基于全注解开发 

    AOP也是一种思想,做的是解耦操作,把一系列的重复操作提取出来,更方便更改。尤其是做外卖的日志操作。

     入门案例一:在接口执行前输出当前系统时间:对update进行增强

     

     注意我专门写了一个SpringConfig类进行全注解开发,这是一个配置类

     第三个注解@EnableAspectJAutoProxy  是告诉Spring识别切面类

     切面类:

    1. @Component
    2. @Aspect
    3. public class MyAdvice {
    4. //随便定义一个无参无方法体的方法
    5. //设置切入点
    6. @Pointcut("execution(void com.gsdx.dao.BookDao.update())")
    7. private void pt(){}
    8. //设置在切入点前执行
    9. @Before("pt()")
    10. public void method(){
    11. System.out.println(System.currentTimeMillis());
    12. }
    13. }

    测试类

    1. public class App
    2. {
    3. public static void main( String[] args )
    4. {
    5. ApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class);
    6. BookDao bookDao = ctx.getBean(BookDao.class);
    7. bookDao.update();
    8. }
    9. }

    测试结果

     update执行前,当前时间已经输出了


    AOP工作流程

     代理对象简单理解的话就是继承了BookDaoImpl,然后在方法执行前执行abefore方法,这是片面的理解


    通知类型

    前置 通知 @Before
    后置 通知 @After
    环绕 通知(重点 @Around
    返回后 通知(了解 @AfterReturning
    抛出异常后 通知 (了解 @AfterThrowing

    我们就来讲一下环绕通知

    @Around("pt()")
    public Object around(ProceedingJoinPoint pjp) throws Throwable {
       
    System.out.println("around before advice ...");
       
    Object ret = pjp.proceed();
       
    System.out.println("around after advice ...");
       
    return ret;
    }

    这是BookDao中有返回参数的写法,返回Object,里面要用到ProceedingJoinPoint类

     


    案例2测量业务层接口万次执行效率

    简单的说就是测量业务层某接口执行前后的时间,我们肯定要用到around环绕通知

    @Around("ProjectAdvice.servicePt()")
    public void runSpeed(ProceedingJoinPoint pjp) throws Throwable {
       
    //获取执行签名信息
       
    Signature signature = pjp.getSignature();
       
    //通过签名获取执行类型(接口名)
       
    String className = signature.getDeclaringTypeName();
       
    //通过签名获取执行操作名称(方法名)
       
    String methodName = signature.getName();
        long start = System.currentTimeMillis();
       
    for (int i = 0; i < 10000; i++) {
            pjp.proceed();
        }

        long end = System.currentTimeMillis();
       
    System.out.println("万次执行:"+className+"."+methodName+"--->"+(end-start)+"ms");
    }

    pjp.proceed表示的是去执行接口中的方法


     案例3:百度网盘密码数据兼容处理

    案例先知:AOP通知获取数据

    这里获取的是接口中方法的形参的值 

    @Around("pt()")
    public Object around(ProceedingJoinPoint pjp) throws Throwable {
       
    Object[] args = pjp.getArgs();
       
    System.out.println(Arrays.toString(args));
       
    Object ret = pjp.proceed();
       
    return ret;
    }

     思路是通过环绕通知,先对url,password进行处理,再执行pjp.proceed();

    1. @Repository
    2. public class ResourcesDaoImpl implements ResourcesDao {
    3. public boolean readResources(String url, String password) {
    4. System.out.println(password.length());
    5. //模拟校验
    6. return password.equals("root");
    7. }
    8. }

     

    1. @Component
    2. @Aspect
    3. public class DataAdvice {
    4. @Pointcut("execution(boolean com.itheima.service.*Service.*(*,*))")
    5. private void servicePt(){}
    6. @Around("DataAdvice.servicePt()")
    7. public Object trimStr(ProceedingJoinPoint pjp) throws Throwable {
    8. Object[] args = pjp.getArgs();
    9. for (int i = 0; i < args.length; i++) {
    10. //判断参数是不是字符串
    11. if(args[i].getClass().equals(String.class)){
    12. args[i] = args[i].toString().trim();
    13. }
    14. }
    15. Object ret = pjp.proceed(args);
    16. return ret;
    17. }
    18. }

  • 相关阅读:
    17.1 隐藏执行CMD命令
    【Linux】之Jumpserver堡垒机的部署/搭建
    springboot基于WEB的高校文档打印系统毕业设计源码101004
    算法篇 滑动窗口 leetcode 长度最小的子数组
    我们将「基础设施」看成是自身的角色和定位的时候
    安卓APP webview加载H5 之间通信
    用.bat文件做Airtest脚本的多设备批量运行
    2331. 计算布尔二叉树的值-深度优先遍历
    【集训DAY N】简单数学【数学】
    Spring中的Cache缓存机制
  • 原文地址:https://blog.csdn.net/qq_47518713/article/details/126228143