`
ry.china
  • 浏览: 137208 次
  • 性别: Icon_minigender_1
  • 来自: 重庆
社区版块
存档分类
最新评论

一个用Spring AOP实现异常处理和记录程序执行时间的实例

    博客分类:
  • java
阅读更多

原创   5.11 一个用Spring AOP实现异常处理和记录程序执行时间的实例 收藏

<script type="text/javascript"> document.body.oncopy = function() { if (window.clipboardData) { setTimeout(function() { var text = clipboardData.getData(&quot;text&quot;); if (text &amp;&amp; text.length&gt;300) { text = text + &quot;\r\n\n本文来自CSDN博客,转载请标明出处:&quot; + location.href; clipboardData.setData(&quot;text&quot;, text); } }, 100); } } </script><script type="text/javascript">function StorePage(){d=document;t=d.selection?(d.selection.type!='None'?d.selection.createRange().text:''):(d.getSelection?d.getSelection():'');void(keyit=window.open('http://www.365key.com/storeit.aspx?t='+escape(d.title)+'&amp;u='+escape(d.location.href)+'&amp;c='+escape(t),'keyit','scrollbars=no,width=475,height=575,left=75,top=20,status=no,resizable=yes'));keyit.focus();}</script>

5.11  一个用Spring AOP实现异常处理和记录程序执行时间的实例

虽然前面也给出了Spring AOP的一些实例,但因为主要目的是为了介绍Spring的知识点,不一定会很完整,下面笔者就通过一个完整的用Spring AOP实现异常处理和记录程序执行时间的实例来展示使用Spring AOP的整个过程。

5.11.1  异常处理和记录程序执行时间的实例简介

这个实例主要用于在一个系统的所有方法执行过程中出现异常时,把异常信息都记录下来,另外记录每个方法的执行时间。用两个业务逻辑来说明上述功能,这两个业务逻辑首先使用Spring AOP的自动代理功能,然后一个用Java的动态代理,一个用CGLIB代理。

实现思路是:仍然使用前面所建的Java工程 myApp,首先定义负责异常处理的Advice为ExceptionHandler.java,定义记录程序执行时间的Advice为 TimeHandler.java,接着定义业务逻辑接口LogicInterface.java,编写实现业务逻辑接口的类Logic1.java,该 业务逻辑在Spring AOP中使用Java的动态代理,编写另一个业务逻辑Logic2.java不实现业务逻辑接口,该业务逻辑在Spring AOP中使用CGLIB代理,然后使用自动代理定义配置文件config.xml,最后编写测试程序TestAop.java,执行它并查看输出结果。下 面就一步一步来实现这个实例。

5.11.2  定义负责异常处理的Advice为ExceptionHandler.java

在myApp工程的com.gc.action包中 新建ExceptionHandler.java,该类主要负责当程序执行过程中出现异常时,把异常信息都记录下来。而Spring提供的通知类型中 Throw通知可以实现这个功能,因此这里使用Throw通知类型来实现Advice,类ExceptionHandler必须实现 ThrowsAdvice接口,重写afterThrowing()方法。ThrowsAdvice.java的示例代码如下:

//******* ExceptionHandler.java**************

package com.gc.action;

import java.lang.reflect.Method;

import org.apache.log4j.Level;

import org.apache.log4j.Logger;

import org.springframework.aop.ThrowsAdvice;

//使用Throw通知类型来实现Advice

public class ExceptionHandler implements ThrowsAdvice{

         private Logger logger = Logger.getLogger(this.getClass().getName());

    //重写afterThrowing()方法

    public void afterThrowing(Method method, Object[ ] args, Object target, Throwable subclass) throws Throwable {

                   logger.log(Level.INFO, args[0] + " 执行 " + method.getName() + " 时有异常抛出...." + subclass);

   }

}

代码说明:

  ●       必须重写afterThrowing()方法。

  ●       当程序有异常发生时,就会输出“×××执行×××方法时有异常抛出”和具体异常的记录信息。

5.11.3  定义记录程序执行时间的Advice为TimeHandler.java

在myApp工程的com.gc.action包中 新建TimeHandler.java,该类主要负责记录每个方法的执行时间,而Spring提供的通知类型中Around通知可以实现这个功能,因此这 里使用Around通知类型来实现Advice,类TimeHandler必须实现MethodInterceptor接口,重写invoke()方法。 TimeHandler.java的示例代码如下:

//******* TimeHandler.java**************

package com.gc.action;

import org.aopalliance.intercept.MethodInterceptor;

import org.aopalliance.intercept.MethodInvocation;

import org.apache.log4j.Level;

import org.apache.log4j.Logger;

//类TimeHandler必须实现MethodInterceptor接口

public class TimeHandler implements MethodInterceptor{

         private Logger logger = Logger.getLogger(this.getClass().getName());

    //重写invoke()方法

    public Object invoke(MethodInvocation methodInvocation) throws Throwable {

                   long procTime = System.currentTimeMillis();

                   logger.log(Level.INFO, methodInvocation.getArguments()[0] + " 开始执行 " + methodInvocation.getMethod() + " 方法"); 

        try {

          Object result = methodInvocation.proceed();

          return result;

        }

        finally {

                            //计算执行时间

procTime = System.currentTimeMillis() - procTime;

                            logger.log(Level.INFO, methodInvocation.getArguments()[0] + " 执行 " + methodInvocation.getMethod() + " 方法结束");

                            logger.log(Level.INFO, "执行 " + methodInvocation.getMethod().getName() + " 方法共用了 " + procTime + "毫秒");

        }

   }

}

代码说明:

  ●       必须重写invoke()方法。

  ●       当有方法执行时,就会输出“×××在什么时间开始执行×××方法”、“×××在什么时间执行×××方法结束”和“执行×××方法共用了×××毫秒”的记录信息。

5.11.4  定义业务逻辑接口LogicInterface.java

在myApp工程的com.gc.impl包中新建接口LogicInterface.java,该接口主要用来实现使用Spring AOP的动态代理机制,在这个接口里共定义了3个方法——新增、修改和删除。LogicInterface.java的示例代码如下:

//******* LogicInterface.java**************

package com.gc.impl;

//该接口主要用来实现使用Spring AOP的动态代理机制

public interface LogicInterface {

         public void doInsert(String name);

         public void doUpdate(String name);

         public void doDelete(String name);

}

5.11.5  编写实现业务逻辑接口的类Logic1.java

在myApp工程的com.gc.action包中 新建业务逻辑类Logic1.java,该类主要负责具体的业务逻辑,这个类实现了前面定义的接口LogicInterface,并重写了接口 LogicInterface定义的3个方法——新增、修改和删除,用来实现使用Spring AOP的动态代理机制,并在删除方法里增加一个“i = i / 0”,用来模拟异常的发生。Logic1.java的示例代码如下:

//******* Logic1.java**************

package com.gc.action;

import com.gc.impl.LogicInterface;

//实现这个接口

public class Logic1 implements LogicInterface{

         //负责新增

         public void doInsert(String name){

                   System.out.println("执行具体负责新增的业务逻辑…");

                   for (int i = 0; i < 100000000; i++) {

                            //模拟执行时间

                   }

         }

         //负责修改

         public void doUpdate(String name){

                   System.out.println("执行具体负责修改的业务逻辑…");

                   for (int i = 0; i < 200000000; i++) {

                            //模拟执行时间

                   }

         }

         //负责删除

         public void doDelete(String name){

                   System.out.println("执行具体负责删除的业务逻辑…");

                   for (int i = 0; i < 300000000; i++) {

                            i = i / 0;//模拟异常发生

                   }

         }

}

5.11.6  编写一个不实现业务逻辑接口的类Logic2.java

在myApp工程的com.gc.action包中 新建业务逻辑类Logic2.java,该类主要负责具体的业务逻辑——新增、修改和删除,这个类不实现前面定义的接口LogicInterface,用 来实现使用Spring AOP的CGLIB代理机制,并在删除方法里增加一个“i = i / 0”,用来模拟异常的发生。Logic2.java的示例代码如下:

//******* Logic2.java**************

package com.gc.action;

//该类采用CGLIB代理机制

public class Logic2 {

         //负责新增

         public void doInsert(String name){

                   System.out.println("执行具体负责新增的业务逻辑…");

                   for (int i = 0; i < 100000000; i++) {

                            //模拟执行时间

                   }

         }

//负责修改

         public void doUpdate(String name){

                   System.out.println("执行具体负责修改的业务逻辑…");

                   for (int i = 0; i < 200000000; i++) {

                            //模拟执行时间

                   }

         }

//负责删除

         public void doDelete(String name){

                   System.out.println("执行具体负责删除的业务逻辑…");

                   for (int i = 0; i < 300000000; i++) {

                            i = i / 0;//模拟异常发生

                   }

         }

}

5.11.7  使用自动代理定义配置文件config.xml

在myApp根目录下,新建一个Spring的配置文件exception_config.xml,主要用来使用Spring的自动代理功能,代理本系统所有的程序。exception_config.xml的示例代码如下:

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"

 "http://www.springframework.org/dtd/spring-beans.dtd">

<beans>

  <bean id="logic1" class="com.gc.action.Logic1"/>

  <bean id="logic2" class="com.gc.action.Logic2"/>

  <!--设定为自动代理-->

  <bean id="autoProxyCreator" class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"/>

  <!--负责记录有异常发生时的信息-->

  <bean id="exceptionHandler" class="com.gc.action.ExceptionHandler"/>

 

  <bean id="exceptionHandlereAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">

        <property name="advice">

            <ref bean="exceptionHandler"/>

        </property>

                   <!--对指定类的任何方法有效-->

        <property name="patterns">

            <value>.*.*</value>

        </property>

  </bean>

  <!--负责记录方法的记录时间-->

  <bean id="timeHandler" class="com.gc.action.TimeHandler"/>

  <bean id="timeHandlerAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">

        <property name="advice">

            <ref bean="timeHandler"/>

        </property>

                   <!--对指定类的任何方法有效-->

        <property name="patterns">

            <value>.*.*</value>

        </property>

    </bean>

</beans>

5.11.8  编写测试类Logic1的程序TestAop.java

在myApp工程的com.gc.test包中新建测试类TestAop.java,该类主要负责对前面程序的测试和演示,这里先编写对业务逻辑Logic1.java的演示。TestAop.java的示例代码如下:

//******* TestAop.java**************

package com.gc.test;

import org.springframework.context.ApplicationContext;

import org.springframework.context.support.FileSystemXmlApplicationContext;

import com.gc.impl.LogicInterface;

public class TestAop {

         public static void main(String[] args) throws InstantiationException, IllegalAccessException, ClassNotFoundException {

                   //通过ApplicationContext获取配置文档

                   ApplicationContext actx=new FileSystemXmlApplicationContext("exception_config.xml");

                   LogicInterface logic = (LogicInterface)actx.getBean("logic1");

                   //模拟执行新增、修改、删除方法

                   try {

                            logic.doInsert("张三");

                            logic.doUpdate("李四");

                            logic.doDelete("王五");

                   } catch (Exception ex) {

                   }

         }

}

5.11.9  输出自动代理时类Logic1异常处理和记录程序执行时间的信息

运行测试程序,即可看到记录Logic1.java中每个方法执行时间和在删除方法里捕获的异常的信息,如图5.16所示。

图5.16  记录Logic1.java中每个方法执行时间和在删除方法里捕获的异常信息

5.11.10  编写测试类Logic2的程序TestAop.java

上面主要是针对业务逻辑Logic1.java的测 试,所以在记录的信息中,类名显示的是Logic1实现的接口LogicInterface的名称,对于业务逻辑Logic2.java的测试,需要修改 测试代码TestAop.java。TestAop.java的示例代码如下:

//******* TestAop.java**************

package com.gc.test;

import org.springframework.context.ApplicationContext;

import org.springframework.context.support.FileSystemXmlApplicationContext;

import com.gc.action.Logic2;

public class TestAop {

         public static void main(String[ ] args) throws InstantiationException, IllegalAccessException, ClassNotFoundException {

//通过ApplicationContext获取配置文档

                   ApplicationContext actx=new FileSystemXmlApplicationContext("exception_config.xml");

                   Logic2 logic2 = (Logic2)actx.getBean("logic2");

                   //模拟执行新增、修改和删除方法

                   try {

                            logic2.doInsert("张三");

                            logic2.doUpdate("李四");

                            logic2.doDelete("王五");

                   } catch (Exception ex) {

 

                   }

         }

}

5.11.11  输出自动代理时类Logic2异常处理和记录程序执行时间的信息

运行测试程序,即可看到记录Logic2.java中每个方法执行时间和在删除方法里捕获的异常的信息,如图5.17所示。

图5.17  记录Logic2.java中每个方法执行时间和在删除方法里捕获的异常信息

上面主要是针对业务逻辑Logic2.java的测试,所以在记录的信息中,类名显示的是Logic2的名称。这是使用接口和不使用接口时显示信息的主要区别。

以上示例使用的是Spring AOP的自动代理,那对于使用Spring AOP的动态代理和CGLIB代理来说,应该怎么实现呢?下面就来讲解使用ProxyFactoryBean实现动态代理和CGLIB代理。

5.11.12  使用ProxyFactoryBean代理定义配置文件config.xml

改写Spring的配置文件 exception_config.xml,主要用来使用Spring的ProxyFactoryBean代理功能,对Logic1.java只记录程序 执行时间,不捕获发生的异常,对Logic2.java只捕获发生的异常,不记录程序执行时间,去掉前面的自动代理。 exception_config.xml的示例代码如下:

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"

 "http://www.springframework.org/dtd/spring-beans.dtd">

<beans>

  <bean id="logic1" class="com.gc.action.Logic1"/>

  <bean id="logic2" class="com.gc.action.Logic2"/>

  <!--设定为自动代理-->

  <!--负责记录有异常发生时的信息-->

  <bean id="exceptionHandler" class="com.gc.action.ExceptionHandler"/>

 

  <bean id="exceptionHandlereAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">

        <property name="advice">

            <ref bean="exceptionHandler"/>

        </property>

<!--对指定类的任何方法有效-->

        <property name="patterns">

            <value>.*.*</value>

        </property>

  </bean>

  <!--负责记录方法的记录时间-->

  <bean id="timeHandler" class="com.gc.action.TimeHandler"/>

  <bean id="timeHandlerAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">

        <property name="advice">

            <ref bean="timeHandler"/>

        </property>

        <!--对指定类的任何方法有效-->

        <property name="patterns">

            <value>.*.*</value>

        </property>

</bean>

<bean id="logic1Proxy" class="org.springframework.aop.framework.ProxyFactoryBean">

        <property name="proxyInterfaces">

            <value>com.gc.impl.LogicInterface</value>

        </property>

        <property name="target">

            <ref bean="logic1"/>

        </property>

<!--指定代理类-->

        <property name="interceptorNames">

            <list>

                <value>timeHandlerAdvisor</value>

            </list>

        </property>

    </bean>

    <bean id="logic2Proxy" class="org.springframework.aop.framework.ProxyFactoryBean">

        <property name="proxyTargetClass">

            <value>true</value>

        </property>

        <property name="target">

            <ref bean="logic2"/>

        </property>

<!--指定代理类-->

        <property name="interceptorNames">

            <list>

                <value>exceptionHandler</value>

            </list>

        </property>

    </bean>

</beans>

5.11.13  编写测试类Logic1的程序TestAop.java

这里先改写对业务逻辑Logic1.java的演示。TestAop.java的示例代码如下:

//******* TestAop.java**************

package com.gc.test;

import org.springframework.context.ApplicationContext;

import org.springframework.context.support.FileSystemXmlApplicationContext;

import com.gc.impl.LogicInterface;

public class TestAop {

         public static void main(String[ ] args) throws InstantiationException, IllegalAccessException, ClassNotFoundException {

//通过ApplicationContext获取配置文档

                   ApplicationContext actx=new FileSystemXmlApplicationContext("exception_config.xml");

                   LogicInterface logic = (LogicInterface)actx.getBean("logic1Proxy");

//模拟执行新增、修改和删除方法

                   try {

                            logic.doInsert("张三");

                            logic.doUpdate("李四");

                            logic.doDelete("王五");

                   } catch (Exception ex) {

 

                   }

         }

}

5.11.14  输出ProxyFactoryBean代理时类Logic1记录程序执行时间的信息

运行测试程序,即可看到记录Logic1.java中每个方法执行时间的信息,如图5.18所示。

图5.18  记录Logic1.java中每个方法执行时间的信息

5.11.15  编写测试类Logic2的程序TestAop.java

上面主要是针对业务逻辑Logic1.java的测 试,所以在记录的信息中,只显示了每个方法的执行时间,而没有捕获删除方法抛出的异常信息,对于业务逻辑Logic2.java的测试,使其只捕获删除方 法抛出的信息,而不记录每个方法执行的时间,需要修改测试代码TestAop.java。TestAop.java的示例代码如下:

//******* TestAop.java**************

package com.gc.test;

import org.springframework.context.ApplicationContext;

import org.springframework.context.support.FileSystemXmlApplicationContext;

import com.gc.action.Logic2;

public class TestAop {

         public static void main(String[ ] args) throws InstantiationException, IllegalAccessException, ClassNotFoundException {

//通过ApplicationContext获取配置文档

                   ApplicationContext actx=new FileSystemXmlApplicationContext("exception_config.xml");

                   Logic2 logic2 = (Logic2)actx.getBean("logic2Proxy ");

                   //模拟执行新增、修改和删除方法

                   logic2.doInsert("张三");

                   logic2.doUpdate("李四");

                   logic2.doDelete("王五");

         }

}

5.11.16  输出ProxyFactoryBean代理时类Logic2异常处理的信息

运行测试程序,即可看到记录Logic2.java中在删除方法里捕获的异常的信息,如图5.19所示。

图5.19  记录Logic2.java中在删除方法里捕获的异常信息

上面主要是针对业务逻辑Logic2.java的测试,所以在记录的信息中,只捕获删除方法抛出的异常信息,而不记录每个方法执行的时间。

 

5.12  小    结

本章首先从AOP的基本思想讲起,接着对Java的动态代理机制进行了讲解,然后讲解了AOP的3个重要概念,又使用不同的通知分别实现了日志输出的示例,最后通过一个完整的实例使读者更全面地了解了Spring中的AOP。

因为AOP在技术和思想上都还没有完全成熟,如果大量地应用AOP可能会有一定的负面作用,可能会达不到开发者的初衷,使得代码更难以理解。因此,要适度地使用AOP。

总的来说,AOP编程的实质就是:业务逻辑不再实现横切关注点,而是由单独的类来封装。当业务逻辑需要用到封装的横切关注点时,AOP会自动把封装的横切关注点插入到具体的业务逻辑中。

分享到:
评论

相关推荐

    Spring AOP 日志管理 实例

    Spring AOP 日志管理 实例LoggingThrowsAdvice.java

    spring aop 实现源代码--xml and annotation(带lib包)

    在这里,我们分别定义了一个MessageSender对象(messageSenderImpl)和一个Before Advice对象(logBeforeAdvice),并定义了一个 org.springframework.aop.framework.ProxyFactoryBean对象(messageSender),...

    spring aop学习实例

    包内是aop入门的一些小例子。包括java代码和其中用到的xml文件。一个子包(如aop包)里有一个可执行应用程序。

    Spring4—AOP编程

    aop写一个简单的计算器:(1)日志功能:在程序执行期间追踪正在发生的活动(打印出调用的方法,以及参数的参数值);(2)验证功能:希望计算器只能处理正数的运算,当有负数参与运算时,给出提示说明。 利用简单的...

    java 实现AOP

     JDK1.2以后提供了动态代理的支持,程序员通过实现java.lang.reflect.InvocationHandler接口提供一个执行处理器,然后通过java.lang.reflect.Proxy得到一个代理对象,通过这个代理对象来执行商业方法,在商业方法被...

    Spring面试题

    AOP从程序运行角度考虑程序的结构,提取业务处理过程的切面,oop是静态的抽象,aop是动态的抽象, 是对应用执行过程中的步骤进行抽象,,从而获得步骤之间的逻辑划分。 aop框架具有的两个特征: 1.各个步骤之间...

    如何在Spring Boot中使用@AfterReturning注解

    我们通过一个图书管理系统的实例演示了@AfterReturning的使用方式,并在成功查询图书时记录了查询的时间和返回的结果。 AOP的强大之处在于它允许我们在不修改原有业务逻辑代码的情况下,将横切关注点(如日志记录、...

    spring.net中文手册在线版

    Spring.NET是一个应用程序框架,其目的是协助开发人员创建企业级的.NET应用程序。它提供了很多方面的功能,比如依赖注入、面向方面编程(AOP)、数据访问抽象及ASP.NET扩展等等。Spring.NET以Java版的Spring框架为...

    如何在Spring Boot中使用@Before注解

    Spring Boot是一个流行的Java开发框架,它提供了一种方便的方式来构建高效的、可扩展的企业级应用程序。Aspect-Oriented Programming(AOP)是Spring Boot框架中的一个重要组成部分,它允许开发者通过将横切关注点...

    Spring中文帮助文档

    9.5.2. 第一个例子 9.5.3. 回滚 9.5.4. 为不同的bean配置不同的事务语义 9.5.5. &lt;tx:advice/&gt; 有关的设置 9.5.6. 使用 @Transactional 9.5.7. 事务传播 9.5.8. 通知事务操作 9.5.9. 结合AspectJ使用 @...

    Spring API

    9.5.2. 第一个例子 9.5.3. 回滚 9.5.4. 为不同的bean配置不同的事务语义 9.5.5. &lt;tx:advice/&gt; 有关的设置 9.5.6. 使用 @Transactional 9.5.7. 事务传播 9.5.8. 通知事务操作 9.5.9. 结合AspectJ使用 @...

    Spring.3.x企业应用开发实战(完整版).part2

    Spring3.0是Spring在积蓄了3年之久后,隆重推出的一个重大升级版本,进一步加强了Spring作为Java领域第一开源平台的翘楚地位。  Spring3.0引入了众多Java开发者翘首以盼的新功能和新特性,如OXM、校验及格式化框架...

    java面试题

    当应用程序在对象上调用了一个需要花费很长时间来执行的方法,并且不希望让程序等待方法的返回时,就应该使用异步。在很多情况下采用异步往往更有效率。 数据库三大范式? 答:1:确保每列都是不可分割的原子值 2...

    Spring攻略(第二版 中文高清版).part1

    14.1 用Spring Portlet MVC开发一个简单的Portlet 544 14.1.1 问题 544 14.1.2 解决方案 545 14.1.3 工作原理 546 14.2 将Portlet请求映射到处理程序 553 14.2.1 问题 553 14.2.2 解决方案 553 14.2.3...

    Spring.net框架

    我们的第一个例子主要用于说明程序的基本构造,并且作为一个反面典型,引出为什么要解耦,以及如何下手。在这个例子中,我们将创建三个程序集,分别是MainApp.exe、HelloGenerator.dll以及SayHello.dll。它们之间的...

    Spring3.x企业应用开发实战(完整版) part1

    Spring3.0是Spring在积蓄了3年之久后,隆重推出的一个重大升级版本,进一步加强了Spring作为Java领域第一开源平台的翘楚地位。  Spring3.0引入了众多Java开发者翘首以盼的新功能和新特性,如OXM、校验及格式化框架...

    Spring攻略(第二版 中文高清版).part2

    14.1 用Spring Portlet MVC开发一个简单的Portlet 544 14.1.1 问题 544 14.1.2 解决方案 545 14.1.3 工作原理 546 14.2 将Portlet请求映射到处理程序 553 14.2.1 问题 553 14.2.2 解决方案 553 14.2.3...

    45 Spring中多个AOP如何协调执行?慕课专栏(1)1

    背景通过前面的章节,我们知道在程序开发中 AOP 主要用来解决一些系统层面上的问题,Struts2 的拦截器设计就是基于 AOP 的思想,是个比较经典的例子。总

    第24次课-1 Spring与Hibernate的整合

    通常,程序中采用实现HibernateCallback的匿名内部类来获取HibernateCallback的实例,方法doInHibernate()就是Spring执行的持久化操作。 24.3 Spring对Hibernate的简化 24.3.5 HibernateDaoSupport Spring为与...

    Spring Boot学习入门之AOP处理请求详解

    AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术,下面这篇文章主要给大家介绍了关于Spring Boot学习入门之AOP处理请求的相关资料,...

Global site tag (gtag.js) - Google Analytics