• Spring(AOP)


    目录

    一、aop的简介及解决的问题

    二、前置通知

    二、后置通知

    三、环绕通知

    四、异常通知

    五、过滤通知(适配器)


    一、aop的简介及解决的问题

    AOP 即面向切面编程

    主要作用:

            将核心的业务功能与非核心的业务功能进行分离。

            将核心的业务功能写到目标对象中,将非核心的业务功能写到通知中

    专业名词:

            通知、连接点、目标对象、切入点、代理、适配器

    日常开发通常应用的场景:

            事物管理、日志

            事物的开启:前置通知

            事物的提交:后置通知

            事物的回滚:异常通知

    解决的问题:解决了需求的改变,造成了原有没必要改变的代码,需要去改变它;

    比如:书籍的增删改,本身只需要完成增删改的功能即可,这是如果需要添加日志功能,那么需要在原有的代码基础上,去修改添加日志功能,受牵连的方法就三个(add/edit/del)了;

    AOP中关键性概念

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

    目标(Target):被通知(被代理)的对象

    注1:完成具体的业务逻辑

    通知(Advice):在某个特定的连接点上执行的动作,同时Advice也是程序代码的具体实现,例如一个实现日志记录的代码(通知有些书上也称为处理)

    注2:完成切面编程

    代理(Proxy):将通知应用到目标对象后创建的对象(代理=目标+通知),

                 例子:外科医生+护士

    注3:只有代理对象才有AOP功能,而AOP的代码是写在通知的方法里面的

    切入点(Pointcut):多个连接点的集合,定义了通知应该应用到那些连接点。

                     (也将Pointcut理解成一个条件 ,此条件决定了容器在什么情况下将通知和目标组合成代理返回给外部程序)

        

    适配器(Advisor):适配器=通知(Advice)+切入点(Pointcut)

    案例:

    BookBiz

    1. package com.zsx.aop.biz;
    2. public interface BookBiz {
    3.     // 购书
    4.     public boolean buy(String userName, String bookName, Double price);
    5.     // 发表书评
    6.     public void comment(String userName, String comments);
    7. }

    BookBizImpl

    1. package com.zsx.aop.biz.impl;
    2. import com.zsx.aop.biz.BookBiz;
    3. import com.zsx.aop.exception.PriceException;
    4. public class BookBizImpl implements BookBiz {
    5. public BookBizImpl() {
    6. super();
    7. }
    8. public boolean buy(String userName, String bookName, Double price) {
    9. // 通过控制台的输出方式模拟购书
    10. if (null == price || price <= 0) {
    11. throw new PriceException("book price exception");
    12. }
    13. //logDao.add 买书日志
    14. System.out.println(userName + " buy " + bookName + ", spend " + price);
    15. return true;
    16. }
    17. public void comment(String userName, String comments) {
    18. // 通过控制台的输出方式模拟发表书评
    19. System.out.println(userName + " say:" + comments);
    20. }
    21. }

     spring-context.xml

    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. beans>

    Demo

    1. package com.zsx.aop.demo;
    2. import org.springframework.context.support.ClassPathXmlApplicationContext;
    3. import com.zsx.aop.biz.BookBiz;
    4. public class Demo {
    5. @SuppressWarnings("resource")
    6. public static void main(String[] args) {
    7. ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("/spring-context.xml");
    8. BookBiz bean = (BookBiz) context.getBean("bookProxy");
    9. bean.buy("华晨宇", "三国", 12d);
    10. bean.comment("华晨宇", "是是是!!!!");
    11. }
    12. }

     二、前置通知

    MyAdvice

    1. package com.zsx.aop.advice;
    2. import java.lang.reflect.Method;
    3. import java.util.Arrays;
    4. import org.springframework.aop.MethodBeforeAdvice;
    5. /**
    6. * 前置日志
    7. * 买书、评论前加日志
    8. * @author Administrator
    9. *
    10. */
    11. public class MyAdvice 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. }

     spring-context.xml

    1. <bean class="com.zsx.aop.biz.impl.BookBizImpl" id="bookBiz">bean>
    2. <bean class="com.zsx.aop.advice.MyAdvice" id="myBefore">bean>
    3. <bean class="org.springframework.aop.framework.ProxyFactoryBean" id="bookProxy">
    4. <property name="target" ref="bookBiz">property>
    5. <property name="proxyInterfaces">
    6. <list>
    7. <value>com.zsx.aop.biz.BookBizvalue>
    8. list>
    9. property>
    10. <property name="interceptorNames">
    11. <list>
    12. <value>myBeforevalue>
    13. list>
    14. property>
    15. bean>

     运行Demo效果图:

    二、后置通知

    MyAfterAdvice

    1. package com.zsx.aop.advice;
    2. import java.lang.reflect.Method;
    3. import java.util.Arrays;
    4. import org.springframework.aop.AfterReturningAdvice;
    5. import org.springframework.aop.MethodBeforeAdvice;
    6. /**
    7. * 前置日志
    8. * 买书、评论前加日志
    9. * @author Administrator
    10. *
    11. */
    12. public class MyAfterAdvice implements AfterReturningAdvice{
    13. @Override
    14. public void afterReturning(Object arg0, Method arg1, Object[] arg2, Object arg3) throws Throwable {
    15. //目标对象的类名
    16. String clzname=arg3.getClass().getName();
    17. //当前调用的方法是
    18. String methodName=arg1.getName();
    19. //当前调用的方法所传递的参数
    20. String args =Arrays.toString(arg2);
    21. System.out.println("【后置日志】:"+clzname+"."+methodName+"被调用,传递的参数为:"+args+";目标对象方法返回值为:"+arg0);
    22. }
    23. }

      spring-context.xml

    1. <bean class="com.zsx.aop.biz.impl.BookBizImpl" id="bookBiz">bean>
    2. <bean class="com.zsx.aop.advice.MyAdvice" id="myBefore">bean>
    3. <bean class="com.zsx.aop.advice.MyAfterAdvice" id="myAfter">bean>
    4. <bean class="org.springframework.aop.framework.ProxyFactoryBean" id="bookProxy">
    5. <property name="target" ref="bookBiz">property>
    6. <property name="proxyInterfaces">
    7. <list>
    8. <value>com.zsx.aop.biz.BookBizvalue>
    9. list>
    10. property>
    11. <property name="interceptorNames">
    12. <list>
    13. <value>myBeforevalue>
    14. <value>myAftervalue>
    15. list>
    16. property>
    17. bean>

     运行Demo效果图:

     

     

    三、环绕通知

     spring-context.xml

    1. <bean class="com.zsx.aop.biz.impl.BookBizImpl" id="bookBiz">bean>
    2. <bean class="com.zsx.aop.advice.MyAdvice" id="myBefore">bean>
    3. <bean class="com.zsx.aop.advice.MyAfterAdvice" id="myAfter">bean>
    4. <bean class="com.zsx.aop.advice.MyInterAdvice" id="myInter">bean>
    5. <bean class="org.springframework.aop.framework.ProxyFactoryBean" id="bookProxy">
    6. <property name="target" ref="bookBiz">property>
    7. <property name="proxyInterfaces">
    8. <list>
    9. <value>com.zsx.aop.biz.BookBizvalue>
    10. list>
    11. property>
    12. <property name="interceptorNames">
    13. <list>
    14. <value>myBeforevalue>
    15. <value>myAftervalue>
    16. <value>myIntervalue>
    17. list>
    18. property>
    19. bean>

    MyInterAdvice

    1. package com.zsx.aop.advice;
    2. import java.lang.reflect.Method;
    3. import java.util.Arrays;
    4. import org.aopalliance.intercept.MethodInterceptor;
    5. import org.aopalliance.intercept.MethodInvocation;
    6. import org.springframework.cglib.proxy.MethodProxy;
    7. /**
    8. * 环绕通知=前置+后置
    9. *
    10. * @author Administrator
    11. *
    12. */
    13. public class MyInterAdvice implements MethodInterceptor{
    14. @Override
    15. public Object invoke(MethodInvocation arg0) throws Throwable {
    16. //目标对象的类名
    17. String clzname=arg0.getThis().getClass().getName();
    18. //当前调用的方法是
    19. String methodName=arg0.getMethod().getName();
    20. //当前调用的方法所传递的参数
    21. String args =Arrays.toString(arg0.getArguments());
    22. System.out.println("【环绕通知】:"+clzname+"."+methodName+"被调用,传递的参数为:"+args+";目标对象方法返回值为:"+args);
    23. //方法的返回值 执行目标方法
    24. Object rs = arg0.proceed();
    25. System.out.println("【环绕通知】:目标对象方法返回值为:"+rs);
    26. return rs;
    27. }
    28. }

     运行Demo效果图:

    四、异常通知

    MyThrowsAdvice

    1. package com.zsx.aop.advice;
    2. import org.aspectj.lang.annotation.AfterThrowing;
    3. import org.springframework.aop.ThrowsAdvice;
    4. import com.zsx.aop.exception.PriceException;
    5. /**
    6. * 过滤通知
    7. * 相较于前置,后置,环绕通知有一个特大区别
    8. * 前面三大通知都需要实现其中的方法
    9. * 环绕通知则不需要,但方法名是固定的
    10. * @author Administrator
    11. *
    12. */
    13. public class MyThrowsAdvice implements ThrowsAdvice{
    14. public void afterThrowing(PriceException p) {
    15. System.out.println("【异常通知】:当价格发生异常,那么执行此代码");
    16. }
    17. }

     spring-context.xml

    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="com.zsx.aop.biz.impl.BookBizImpl" id="bookBiz">bean>
    9. <bean class="com.zsx.aop.advice.MyAdvice" id="myBefore">bean>
    10. <bean class="com.zsx.aop.advice.MyAfterAdvice" id="myAfter">bean>
    11. <bean class="com.zsx.aop.advice.MyInterAdvice" id="myInter">bean>
    12. <bean class="com.zsx.aop.advice.MyThrowsAdvice" id="myThorw">bean>
    13. <bean class="org.springframework.aop.framework.ProxyFactoryBean" id="bookProxy">
    14. <property name="target" ref="bookBiz">property>
    15. <property name="proxyInterfaces">
    16. <list>
    17. <value>com.zsx.aop.biz.BookBizvalue>
    18. list>
    19. property>
    20. <property name="interceptorNames">
    21. <list>
    22. <value>myBeforevalue>
    23. <value>myAftervalue>
    24. <value>myIntervalue>
    25. <value>myThorwvalue>
    26. list>
    27. property>
    28. bean>
    29. beans>

     运行Demo效果图:

    五、过滤通知(适配器)

      spring-context.xml

    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="com.zsx.aop.biz.impl.BookBizImpl" id="bookBiz">bean>
    9. <bean class="com.zsx.aop.advice.MyAdvice" id="myBefore">bean>
    10. <bean class="com.zsx.aop.advice.MyAfterAdvice" id="myAfter">bean>
    11. <bean class="com.zsx.aop.advice.MyInterAdvice" id="myInter">bean>
    12. <bean class="com.zsx.aop.advice.MyThrowsAdvice" id="myThorw">bean>
    13. <bean class="org.springframework.aop.support.RegexpMethodPointcutAdvisor" id="myAfter2">
    14. <property name="advice" ref="myAfter">property>
    15. <property name="pattern" value=".*buy">property>
    16. bean>
    17. <bean class="org.springframework.aop.framework.ProxyFactoryBean" id="bookProxy">
    18. <property name="target" ref="bookBiz">property>
    19. <property name="proxyInterfaces">
    20. <list>
    21. <value>com.zsx.aop.biz.BookBizvalue>
    22. list>
    23. property>
    24. <property name="interceptorNames">
    25. <list>
    26. <value>myBeforevalue>
    27. <value>myIntervalue>
    28. <value>myThorwvalue>
    29. <value>myAfter2value>
    30. list>
    31. property>
    32. bean>
    33. beans>

     运行Demo效果图:

     

  • 相关阅读:
    Cisco ASA防火墙——远程控制与多安全区域
    全渠道定价、库存决策,混合整数规划建模求解,MNL选择模型,内附代码!
    opengauss数据备份(docker中备份)
    新的QuickScan 2500系列:价格实惠且性能卓越
    第2集丨天才儿童的打油诗的一些思考
    【MyBatis系列】- 什么是MyBatis
    它突然就不好了 ----Go 调用C++异常
    软件为什么单独标注支持IPV6?IPV6和IPV4有什么区别?
    scrapy框架--
    RabbitMq安装过程
  • 原文地址:https://blog.csdn.net/weixin_61523879/article/details/126211518