• Maven之aop框架


    目录

    一、Aop认识

    1.作用:

    2.AOP中关键性概念 

    二、Aop运用

    前置通知

     后置通知

      环绕通知

    异常通知      

     过滤通知(适配器)        


    一、Aop认识


       ------ AOP即面向切面编程

    AOP(Aspect-OrientedProgramming,面向切面编程),可以说是OOP(Object-Oriented Programing,面向对象编程)的补充和完善。

    1.作用:

                   想象下面的场景,开发中在多个模块间有某段重复的代码,我们通常是怎么处理的?显然,没有人会靠“复制粘贴”吧。在传统的面向过程编程中,我们也会将这段代码,抽象成一个方法,然后在需要的地方分别调用这个方法,这样当这段代码需要修改时,我们只需要改变这个方法就可以了。然而需求总是变化的,有一天,新增了一个需求,需要再多出做修改,我们需要再抽象出一个方法,然后再在需要的地方分别调用这个方法,又或者我们不需要这个方法了,我们还是得删除掉每一处调用该方法的地方。实际上涉及到多个地方具有相同的修改的问题我们都可以通过 AOP 来解决。

    2.AOP中关键性概念 


    连接点(Joinpoint):程序执行过程中明确的点,如方法的调用,或者异常的抛出.

    目标(Target):被通知(被代理)的对象
    注1:完成具体的业务逻辑

    通知(Advice):在某个特定的连接点上执行的动作,同时Advice也是程序代码的具体实现,例如一个实现日志记录的代码(通知有些书上也称为处理)
    注2:完成切面编程 -----非核心业务

    代理(Proxy):将通知应用到目标对象后创建的对象(代理=目标+通知),
                 例子:外科医生+护士
    注3:只有代理对象才有AOP功能,而AOP的代码是写在通知的方法里面的

    切入点(Pointcut):多个连接点的集合,定义了通知应该应用到那些连接点。
                     (也将Pointcut理解成一个条件 ,此条件决定了容器在什么情况下将通知和目标组合成代理返回给外部程序)
        
    适配器(Advisor):适配器=通知(Advice)+切入点(Pointcut)
     


    二、Aop运用

     以书籍管理为例

    用前篇博客项目为基础,准备工作

    添加以下代码

    BookBiz 

    package com.zking.aop.biz;

    public interface BookBiz {
        // 购书
        public boolean buy(String userName, String bookName, Double price);

        // 发表书评
        public void comment(String userName, String comments);
    }
     

     BookBizImpl

    package impl;

    import com.zking.aop.biz.BookBiz;

    import exception.PriceException;

    public class BookBizImpl implements BookBiz {

        public BookBizImpl() {
            super();
        }

        public boolean buy(String userName, String bookName, Double price) {
            // 通过控制台的输出方式模拟购书
            if (null == price || price <= 0) {
                throw new PriceException("book price exception");
            }
            System.out.println(userName + " buy " + bookName + ", spend " + price);
            return true;
        }

        public void comment(String userName, String comments) {
            // 通过控制台的输出方式模拟发表书评
            System.out.println(userName + " say:" + comments);
        }

    }
     

     PriceException

    package exception;

    public class PriceException extends RuntimeException {

        public PriceException() {
            super();
        }

        public PriceException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
            super(message, cause, enableSuppression, writableStackTrace);
        }

        public PriceException(String message, Throwable cause) {
            super(message, cause);
        }

        public PriceException(String message) {
            super(message);
        }

        public PriceException(Throwable cause) {
            super(cause);
        }
        
    }
     

    前置通知

       实现org.springframework.aop.MethodBeforeAdvice接口
            买书、评论前加系统日志

    1. package com.zking.aop.advice;
    2. import java.lang.reflect.Method;
    3. import java.util.Arrays;
    4. import org.springframework.aop.MethodBeforeAdvice;
    5. import org.springframework.aop.framework.ProxyFactory;
    6. import org.springframework.aop.framework.ProxyFactoryBean;
    7. /**前置通知
    8. * @author lucy
    9. *
    10. */
    11. public class MyMethodBeforeAdvice implements MethodBeforeAdvice{
    12. @Override
    13. public void before(Method arg0, Object[] arg1, Object arg2) throws Throwable {
    14. //目标对象类名
    15. String clzName=arg2.getClass().getName();
    16. //当前调用方法
    17. String methodName=arg0.getName();
    18. //当前调用方法所传参数
    19. String args=Arrays.toString(arg1);
    20. System.out.println("系统日志:"+clzName+"."+methodName+"被调用,传递的参数是:"+args);
    21. }
    22. }

    1. <beans xmlns="http://www.springframework.org/schema/beans"
    2. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    3. xmlns:aop="http://www.springframework.org/schema/aop"
    4. xmlns:context="http://www.springframework.org/schema/context"
    5. xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
    6. http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
    7. http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd">
    8. <bean class="impl.UserBizImpl1" id="userBiz">bean>
    9. <bean class="com.zking.web.UserAction" id="userAction">
    10. <property name="userbiz" ref="userBiz">property>
    11. <property name="age" value="23">property>
    12. <property name="name" value="占星师">property>
    13. <property name="hobby" >
    14. <list>
    15. <value>rapvalue>
    16. <value>画画value>
    17. <value>看沉香value>
    18. list>
    19. property>
    20. bean>
    21. <bean class="com.zking.web.OrderAction" id="orderAction">
    22. <property name="userbiz" ref="userBiz">property>
    23. <constructor-arg name="age" value="14">constructor-arg>
    24. <constructor-arg name="name" value="小小">constructor-arg>
    25. <constructor-arg name="hobby" >
    26. <list>
    27. <value>rapvalue>
    28. <value>画画value>
    29. <value>看沉香value>
    30. list>
    31. constructor-arg>
    32. bean>
    33. <bean class="impl.BookBizImpl" id="bookBiz">bean>
    34. <bean class="com.zking.aop.advice.MyMethodBeforeAdvice" id="myBefore">bean>
    35. <bean class="org.springframework.aop.framework.ProxyFactoryBean" id="bookProxy">
    36. <property name="target" ref="bookBiz">property>
    37. <property name="proxyInterfaces">
    38. <list>
    39. <value>com.zking.aop.biz.BookBizvalue>
    40. list>
    41. property>
    42. <property name="interceptorNames">
    43. <list>
    44. <value>com.zking.aop.biz.BookBizvalue>
    45. list>
    46. property>
    47. bean>
    48. beans>


         测试类

    package com.zking.aop.test;

    import org.springframework.context.support.ClassPathXmlApplicationContext;

    import com.zking.aop.biz.BookBiz;

    public class demo1 {
            
        @SuppressWarnings("resource")
        public static void main(String[] args) {
             ClassPathXmlApplicationContext context    =new ClassPathXmlApplicationContext("/spring-context.xml");
             BookBiz bean=(BookBiz) context.getBean("bookBiz");
    //        BookBiz bean=(BookBiz) context.getBean("bookProxy");
            bean.buy("小a", "琉璃", 56d);
            bean.comment("小a", "对战神更向往了");
        
        
        }
        
    }
     

    效果图

            后置通知


            实现org.springframework.aop.AfterReturningAdvice接口
            买书返利(存在bug)

    1. package com.zking.aop.advice;
    2. import java.lang.reflect.Method;
    3. import java.util.Arrays;
    4. import org.springframework.aop.AfterReturningAdvice;
    5. public class MyAfterReturnAdvice implements AfterReturningAdvice {
    6. @Override
    7. public void afterReturning(Object arg0, Method arg1, Object[] arg2, Object arg3) throws Throwable {
    8. //目标对象类名
    9. String clzName=arg3.getClass().getName();
    10. //当前调用方法
    11. String methodName=arg1.getName();
    12. //当前调用方法所传参数
    13. String args=Arrays.toString(arg2);
    14. System.out.println("买书返利:"+clzName+"."+methodName+"被调用,传递的参数是:"+args);
    15. }
    16. }


        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:aop="http://www.springframework.org/schema/aop"
        xmlns:context="http://www.springframework.org/schema/context"
        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
            http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd">
            
        
        
        
        
        
        
        
        
        
        rap
        画画
        看沉香
        

        
        

        

        
        
        
        
        
        
        
        rap
        画画
        看沉香
        

        

        

        
        
        
        

       
        

        
        
        
        
        
        
        
            com.zking.aop.biz.BookBiz
        

        

        
        
        
            myBefore
            myAfter
        

        

        

        

        

     测试类

    package com.zking.aop.test;

    import org.springframework.context.support.ClassPathXmlApplicationContext;

    import com.zking.aop.biz.BookBiz;

    public class demo1 {
            
        @SuppressWarnings("resource")
        public static void main(String[] args) {
             ClassPathXmlApplicationContext context    =new ClassPathXmlApplicationContext("/spring-context.xml");
    //         BookBiz bean=(BookBiz) context.getBean("bookBiz");
            BookBiz bean=(BookBiz) context.getBean("bookProxy");
            bean.buy("小a", "琉璃", 56d);
            bean.comment("小a", "对战神更向往了");
        
        }
        
    }
     

     效果图

     

            环绕通知


            org.aopalliance.intercept.MethodInterceptor
            类似拦截器,会包括切入点,目标类前后都会执行代码。

    package com.zking.aop.advice;

    import java.util.Arrays;

    import org.aopalliance.intercept.MethodInterceptor;
    import org.aopalliance.intercept.MethodInvocation;

    /**环绕通知=前置通知+后置通知
     * @author LUCY
     *
     */
    public class MyMethodInterceptor implements MethodInterceptor {

        @Override
        public Object invoke(MethodInvocation arg0) throws Throwable {
                    //目标对象类名
                    String clzName=arg0.getClass().getName();
                    //当前调用方法
                    String methodName=arg0.getMethod().getName();
                    //当前调用方法所传参数
                    String args=Arrays.toString(arg0.getArguments());
                    System.out.println("环绕通知:"+clzName+"."+methodName+"被调用,传递的参数是:"+args);
                    
                    //方法返回值 执行目标方法buy
                    Object rs=arg0.proceed();
                    System.out.println("环绕通知:目标对象方法返回值是"+rs);
                    
                    
            
            return rs;
        }

    }
     

     
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:aop="http://www.springframework.org/schema/aop"
        xmlns:context="http://www.springframework.org/schema/context"
        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
            http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd">
            
        
        
        
        
        
        
        
        
        
        rap
        画画
        看沉香
        

        
        

        

        
        
        
        
        
        
        
        rap
        画画
        看沉香
        

        

        

        
        
        
        
        
        
        
        

        
        
        
        
        
        
        
        
            com.zking.aop.biz.BookBiz
        

        

        
        
        
            myBefore
            myAfter
            myMethod
        

        

        
        

     
        

    测试

    package com.zking.aop.test;

    import org.springframework.context.support.ClassPathXmlApplicationContext;

    import com.zking.aop.biz.BookBiz;

    public class demo1 {
            
        @SuppressWarnings("resource")
        public static void main(String[] args) {
             ClassPathXmlApplicationContext context    =new ClassPathXmlApplicationContext("/spring-context.xml");
    //         BookBiz bean=(BookBiz) context.getBean("bookBiz");
            BookBiz bean=(BookBiz) context.getBean("bookProxy");
            bean.buy("小a", "琉璃", 56d);
            bean.comment("小a", "对战神更向往了");
       
        
        }
        
    }
     

     

    效果图

    异常通知
          

     org.springframework.aop.ThrowsAdvice
            出现异常执行系统提示,然后进行处理。价格异常为例


        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:aop="http://www.springframework.org/schema/aop"
        xmlns:context="http://www.springframework.org/schema/context"
        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
            http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd">
            
        
        
        
        
        
        
        
        
        
        rap
        画画
        看沉香
        

        
        

        

        
        
        
        
        
        
        
        rap
        画画
        看沉香
        

        

        

        
        
        
        
        
        
        
        
        
        
        
        

        
        
        
        
        
        
        
            com.zking.aop.biz.BookBiz
        

        

        
        
        
            myBefore
            myAfter
            myMethod
            myThrow
        

        

        
        


     

    package com.zking.aop.advice;

    import org.springframework.aop.ThrowsAdvice;

    /**
     * 异常通知:
     * 与前置通知,后置通知,环绕通知对比的最大区别
     * 前面三个通知都需要实现其中的方法
     * 环绕通知就不需要,但是他的方法是固定的
     * @author lucy
     *
     */
    public class MyThrowAdvice  implements ThrowsAdvice{
            public void after(PriceException p) {//错误示范
                System.out.println("异常通知:当价格发生改变,那么执行此处代码块");
            }
     

        
    }

    package com.zking.aop.test;

    import org.springframework.context.support.ClassPathXmlApplicationContext;

    import com.zking.aop.biz.BookBiz;

    public class demo1 {
            
        @SuppressWarnings("resource")
        public static void main(String[] args) {
             ClassPathXmlApplicationContext context    =new ClassPathXmlApplicationContext("/spring-context.xml");
    //         BookBiz bean=(BookBiz) context.getBean("bookBiz");
            BookBiz bean=(BookBiz) context.getBean("bookProxy");
            bean.buy("小a", "琉璃", -56d);//测试价格低于0
            bean.comment("小a", "对战神更向往了");
        
        
        
        }
        
    }
     

    错误效果图

     把方法名改正后

    package com.zking.aop.advice;

    import org.springframework.aop.ThrowsAdvice;

    import exception.PriceException;

    /**
     * 过滤通知:
     * 与前置通知,后置通知,环绕通知对比的最大区别
     * 前面三个通知都需要实现其中的方法
     * 过滤通知就不需要,但是他的方法是固定的
     * @author lucy
     *
     */
    public class MyThrowAdvice  implements ThrowsAdvice{
            public void afterThrowing(PriceException p) {
                System.out.println("异常通知:当价格发生改变,那么执行此处代码块");
            }
      

    }
     

    正确效果图


         


     过滤通知(适配器)        

    org.springframework.aop.support.RegexpMethodPointcutAdvisor
            处理买书返利的bug
            


        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:aop="http://www.springframework.org/schema/aop"
        xmlns:context="http://www.springframework.org/schema/context"
        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
            http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd">
            
        
        
        
        
        
        
        
        
        
        rap
        画画
        看沉香
        

        
        

        

        
        
        
        
        
        
        
        rap
        画画
        看沉香
        

        

        

        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        

        
        
        
        
        
        
        
        
        
            com.zking.aop.biz.BookBiz
        

        

        
        
        
            myBefore
            
            myafterPlus

            myMethod
            myThrow
        

        

        
        


     

    效果图


  • 相关阅读:
    开发中遇到的一个bug
    通过YOLO5训练自己的数据集(以交通标志牌数据集TT100k为例)
    Linux 内存性能指标
    Linux shell编程学习笔记51: cat /proc/cpuinfo:查看CPU详细信息
    leetcode427. 建立四叉树(java)
    MNE绘制自定义通道位置及名字的脑地形图
    六爻排盘神机
    撸了一个 Feign 增强包 V2.0 升级版
    ChatGPT重磅升级:可以看图、听声音、说话啦!
    一文带你了解【抽象类和接口】
  • 原文地址:https://blog.csdn.net/qq_66924116/article/details/126208876