Spring_7_AOP之Advice应用

本文内容纲要:Spring_7_AOP之Advice应用

Spring学习(21)--- AOP之Advice应用(上) 出处:http://www.cnblogs.com/JsonShare

前置通知(Before advice)在某个连接点(join point)之前执行的通知,但不能阻止连接点前的执行(除非它抛出异常)
返回后通知(After returning advice)在某个连接点(join point)正常完成后执行的通知
抛出异常后通知(After throwing advice)在方法抛出异常退出时执行的通知
后通知(After(finally) advice)当某个连接点退出的时候执行的通知(无论是正常返回还是异常退出)
环绕通知(Around advice)包围一个连接点(join point)的通知

导入需要的包:aspectjweaver.jar、aopalliance-1.0.jar

(一)Before Advice

例子:

新建两个类:

package com.aop.schema;

/**

*

* 切面类

*

*/

public class MyAspect {

public void before(){

System.out.println("MyAspect.before");

}

}

package com.aop.schema;

/**

*

* 业务类

*

*/

public class ApsectBiz {

public void biz(){

System.out.println("ApsectBiz.biz");

}

}

XML配置:

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

<beans xmlns="http://www.springframework.org/schema/beans"

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-4.1.xsd

http://www.springframework.org/schema/context

http://www.springframework.org/schema/context/spring-context-4.1.xsd

http://www.springframework.org/schema/aop

http://www.springframework.org/schema/aop/spring-aop-4.1.xsd">

<bean id="myAspect" class="com.aop.schema.MyAspect"></bean>

<bean id="apsectBiz" class="com.aop.schema.ApsectBiz"></bean>

<aop:config>

<aop:aspect id="myAspectAOP" ref="myAspect">

<aop:pointcut id="myPointcut" expression="execution(* com.aop.schema.ApsectBiz.*(..))" />

<aop:before method="before" pointcut-ref="myPointcut"/>

</aop:aspect>

</aop:config>

</beans>

单元测试:

package com.aop.schema;

import org.junit.Test;

import org.springframework.context.ApplicationContext;

import org.springframework.context.support.ClassPathXmlApplicationContext;

public class UnitTest {

@Test

public void test(){

ApplicationContext context = new ClassPathXmlApplicationContext("classpath:spring-aop.xml");

ApsectBiz biz = (ApsectBiz)context.getBean("apsectBiz");

biz.biz();

}

}

结果:

七月 09, 2015 10:30:24 下午 org.springframework.context.support.AbstractApplicationContext prepareRefresh

INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@31b3c607: startup date [Thu Jul 09 22:30:24 CST 2015]; root of context hierarchy

七月 09, 2015 10:30:24 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions

INFO: Loading XML bean definitions from class path resource [spring-aop.xml]

MyAspect.before

ApsectBiz.biz

PS:ApsectBiz.biz是业务方法,在它之前,执行了前置通知MyAspect.before,符合想要的结果

(二)After returning advice

例子:

修改一下切面类MyAspect(添加afterreturning方法):

package com.aop.schema;

/**

*

* 切面类

*

*/

public class MyAspect {

public void before(){

System.out.println("MyAspect.before");

}

public void afterreturning(){

System.out.println("MyAspect.afterreturning");

}

}

XML配置修改为:

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

<beans xmlns="http://www.springframework.org/schema/beans"

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-4.1.xsd

http://www.springframework.org/schema/context

http://www.springframework.org/schema/context/spring-context-4.1.xsd

http://www.springframework.org/schema/aop

http://www.springframework.org/schema/aop/spring-aop-4.1.xsd">

<bean id="myAspect" class="com.aop.schema.MyAspect"></bean>

<bean id="apsectBiz" class="com.aop.schema.ApsectBiz"></bean>

<aop:config>

<aop:aspect id="myAspectAOP" ref="myAspect">

<aop:pointcut id="myPointcut" expression="execution(* com.aop.schema.ApsectBiz.*(..))" />

<aop:before method="before" pointcut-ref="myPointcut"/>

<aop:after-returning method="afterreturning" pointcut-ref="myPointcut"/>

</aop:aspect>

</aop:config>

</beans>

单元测试同上:

结果:

七月 09, 2015 10:38:41 下午 org.springframework.context.support.AbstractApplicationContext prepareRefresh

INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@31b3c607: startup date [Thu Jul 09 22:38:41 CST 2015]; root of context hierarchy

七月 09, 2015 10:38:41 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions

INFO: Loading XML bean definitions from class path resource [spring-aop.xml]

MyAspect.before

ApsectBiz.biz

MyAspect.afterreturning

(三)After throwing advice

说明:使用throwing属性来指定可被传递的异常的参数名称

例子:

修改一下切面类MyAspect(添加afterthrowing方法):

package com.aop.schema;

/**

*

* 切面类

*

*/

public class MyAspect {

public void before(){

System.out.println("MyAspect.before");

}

public void afterreturning(){

System.out.println("MyAspect.afterreturning");

}

public void afterthrowing(){

System.out.println("MyAspect.afterthrowing");

}

}

修改业务类ApsectBiz(抛出一个异常):

package com.aop.schema;

/**

*

* 业务类

*

*/

public class ApsectBiz {

public void biz(){

System.out.println("ApsectBiz.biz");

throw new RuntimeException(); //故意抛出异常

}

}

XML配置:

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

<beans xmlns="http://www.springframework.org/schema/beans"

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-4.1.xsd

http://www.springframework.org/schema/context

http://www.springframework.org/schema/context/spring-context-4.1.xsd

http://www.springframework.org/schema/aop

http://www.springframework.org/schema/aop/spring-aop-4.1.xsd">

<bean id="myAspect" class="com.aop.schema.MyAspect"></bean>

<bean id="apsectBiz" class="com.aop.schema.ApsectBiz"></bean>

<aop:config>

<aop:aspect id="myAspectAOP" ref="myAspect">

<aop:pointcut id="myPointcut" expression="execution(* com.aop.schema.ApsectBiz.*(..))" />

<aop:before method="before" pointcut-ref="myPointcut"/>

<aop:after-returning method="afterreturning" pointcut-ref="myPointcut"/>

<aop:after-throwing method="afterthrowing" pointcut-ref="myPointcut"/>

</aop:aspect>

</aop:config>

</beans>

单元测试同上:

测试结果:

七月 09, 2015 10:47:46 下午 org.springframework.context.support.AbstractApplicationContext prepareRefresh

INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@31b3c607: startup date [Thu Jul 09 22:47:46 CST 2015]; root of context hierarchy

七月 09, 2015 10:47:46 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions

INFO: Loading XML bean definitions from class path resource [spring-aop.xml]

MyAspect.before

ApsectBiz.biz

MyAspect.afterthrowing

PS:有没有发现有什么问题? MyAspect.afterreturning没有了,biz()中抛出异常,biz()方法没有正常返回,所以MyAspect.afterreturning没有了。

(四)After(finally) advice

修改一下切面类MyAspect(添加after方法):

package com.aop.schema;

/**

*

* 切面类

*

*/

public class MyAspect {

public void before(){

System.out.println("MyAspect.before");

}

public void afterreturning(){

System.out.println("MyAspect.afterreturning");

}

public void afterthrowing(){

System.out.println("MyAspect.afterthrowing");

}

public void after(){

System.out.println("MyAspect.after");

}

}

XML配置:

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

<beans xmlns="http://www.springframework.org/schema/beans"

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-4.1.xsd

http://www.springframework.org/schema/context

http://www.springframework.org/schema/context/spring-context-4.1.xsd

http://www.springframework.org/schema/aop

http://www.springframework.org/schema/aop/spring-aop-4.1.xsd">

<bean id="myAspect" class="com.aop.schema.MyAspect"></bean>

<bean id="apsectBiz" class="com.aop.schema.ApsectBiz"></bean>

<aop:config>

<aop:aspect id="myAspectAOP" ref="myAspect">

<aop:pointcut id="myPointcut" expression="execution(* com.aop.schema.ApsectBiz.*(..))" />

<aop:before method="before" pointcut-ref="myPointcut"/>

<aop:after-returning method="afterreturning" pointcut-ref="myPointcut"/>

<aop:after-throwing method="afterthrowing" pointcut-ref="myPointcut"/>

<aop:after method="after" pointcut-ref="myPointcut"/>

</aop:aspect>

</aop:config>

</beans>

单元测试同上:

结果:

七月 09, 2015 10:56:10 下午 org.springframework.context.support.AbstractApplicationContext prepareRefresh

INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@31b3c607: startup date [Thu Jul 09 22:56:10 CST 2015]; root of context hierarchy

七月 09, 2015 10:56:10 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions

INFO: Loading XML bean definitions from class path resource [spring-aop.xml]

MyAspect.before

ApsectBiz.biz

MyAspect.afterthrowing

MyAspect.after

(五)Around advice

注意:通知方法的第一个参数必ProceedingJoinPoint类型

例子:

修改一下切面类MyAspect(添加around方法):

package com.aop.schema;

import org.aspectj.lang.ProceedingJoinPoint;

/**

*

* 切面类

*

*/

public class MyAspect {

public void before(){

System.out.println("MyAspect.before");

}

public void afterreturning(){

System.out.println("MyAspect.afterreturning");

}

public void afterthrowing(){

System.out.println("MyAspect.afterthrowing");

}

public void after(){

System.out.println("MyAspect.after");

}

public void around(ProceedingJoinPoint pjp) throws Throwable{

System.out.println("MyAspect.around_1");

Object obj=pjp.proceed();

System.out.println("MyAspect.around_2");

}

}

XML配置:

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

<beans xmlns="http://www.springframework.org/schema/beans"

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-4.1.xsd

http://www.springframework.org/schema/context

http://www.springframework.org/schema/context/spring-context-4.1.xsd

http://www.springframework.org/schema/aop

http://www.springframework.org/schema/aop/spring-aop-4.1.xsd">

<bean id="myAspect" class="com.aop.schema.MyAspect"></bean>

<bean id="apsectBiz" class="com.aop.schema.ApsectBiz"></bean>

<aop:config>

<aop:aspect id="myAspectAOP" ref="myAspect">

<aop:pointcut id="myPointcut" expression="execution(* com.aop.schema.ApsectBiz.*(..))" />

<aop:before method="before" pointcut-ref="myPointcut"/>

<aop:after-returning method="afterreturning" pointcut-ref="myPointcut"/>

<aop:after-throwing method="afterthrowing" pointcut-ref="myPointcut"/>

<aop:after method="after" pointcut-ref="myPointcut"/>

<aop:around method="around" pointcut-ref="myPointcut"/>

</aop:aspect>

</aop:config>

</beans>

单元测试同上:

结果:

七月 09, 2015 11:15:20 下午 org.springframework.context.support.AbstractApplicationContext prepareRefresh

INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@31b3c607: startup date [Thu Jul 09 23:15:20 CST 2015]; root of context hierarchy

七月 09, 2015 11:15:20 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions

INFO: Loading XML bean definitions from class path resource [spring-aop.xml]

MyAspect.before

MyAspect.around_1

ApsectBiz.biz

java.lang.RuntimeException

at com.aop.schema.ApsectBiz.biz(ApsectBiz.java:11)

at com.aop.schema.ApsectBiz$$FastClassBySpringCGLIB$$ae10254d.invoke(<generated>)

at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)

at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:717)

at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)

at org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint.proceed(MethodInvocationProceedingJoinPoint.java:85)

at com.aop.schema.MyAspect.around(MyAspect.java:31)

at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)

at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)

at java.lang.reflect.Method.invoke(Unknown Source)

at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs(AbstractAspectJAdvice.java:621)

at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethod(AbstractAspectJAdvice.java:610)

at org.springframework.aop.aspectj.AspectJAroundAdvice.invoke(AspectJAroundAdvice.java:68)

at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)

at org.springframework.aop.aspectj.AspectJAfterAdvice.invoke(AspectJAfterAdvice.java:43)

at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)

at org.springframework.aop.aspectj.AspectJAfterThrowingAdvice.invoke(AspectJAfterThrowingAdvice.java:58)

at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)

at org.springframework.aop.framework.adapter.AfterReturningAdviceInterceptor.invoke(AfterReturningAdviceInterceptor.java:52)

at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)

at org.springframework.aop.framework.adapter.MethodBeforeAdviceInterceptor.invoke(MethodBeforeAdviceInterceptor.java:52)

at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)

at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)

at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)

at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:653)

at com.aop.schema.ApsectBiz$$EnhancerBySpringCGLIB$$1fbf7bae.biz(<generated>)

at com.aop.schema.UnitTest.test(UnitTest.java:13)

at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)

at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)

at java.lang.reflect.Method.invoke(Unknown Source)

at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)

at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)

at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)

at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)

at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)

at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)

at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)

at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)

at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)

at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)

at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)

at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)

at org.junit.runners.ParentRunner.run(ParentRunner.java:309)

at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)

at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)

at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)

at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)

at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)

at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)

MyAspect.after

MyAspect.afterreturning

View Code

PS:有异常,仔细看,原来是around(ProceedingJoinPoint pjp)的try catch捕捉到了biz()抛出的异常,现在把异常注释掉(try catch里面怎么处理异常?这里要看具体的业务需要,这里先注释掉)

package com.aop.schema;

/**

*

* 业务类

*

*/

public class ApsectBiz {

public void biz(){

System.out.println("ApsectBiz.biz");

//throw new RuntimeException(); //故意抛出异常

}

}

测试结果:

七月 09, 2015 11:18:17 下午 org.springframework.context.support.AbstractApplicationContext prepareRefresh

INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@31b3c607: startup date [Thu Jul 09 23:18:17 CST 2015]; root of context hierarchy

七月 09, 2015 11:18:17 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions

INFO: Loading XML bean definitions from class path resource [spring-aop.xml]

MyAspect.before

MyAspect.around_1

ApsectBiz.biz

MyAspect.around_2

MyAspect.after

MyAspect.afterreturning

Spring学习(22)--- AOP之Advice应用(下)

(六)Advice parameters(advice带参数的情况)

例子:

修改MyAspect(添加around_init方法):

1 package com.aop.schema;

2

3 import org.aspectj.lang.ProceedingJoinPoint;

4

5 /**

6 *

7 * 切面类

8 *

9 */

10 public class MyAspect {

11

12 public void before(){

13 System.out.println("MyAspect.before");

14 }

15

16 public void afterreturning(){

17 System.out.println("MyAspect.afterreturning");

18 }

19

20 public void afterthrowing(){

21 System.out.println("MyAspect.afterthrowing");

22 }

23

24 public void after(){

25 System.out.println("MyAspect.after");

26 }

27

28 public void around(ProceedingJoinPoint pjp) {

29 try {

30 System.out.println("MyAspect.around_1");

31 Object obj=pjp.proceed();

32 System.out.println("MyAspect.around_2");

33 } catch (Throwable e) {

34 e.printStackTrace();

35 }

36 }

37

38 public void around_init(ProceedingJoinPoint pjp,String name,int age) {

39 System.out.println(name+" "+age);

40 try {

41 System.out.println("MyAspect.around_1");

42 Object obj=pjp.proceed();

43 System.out.println("MyAspect.around_2");

44 } catch (Throwable e) {

45 e.printStackTrace();

46 }

47 }

48 }

修改ApsectBiz类(添加init方法):

1 package com.aop.schema;

2 /**

3 *

4 * 业务类

5 *

6 */

7 public class ApsectBiz {

8

9 public void biz(){

10 System.out.println("ApsectBiz.biz");

11 //throw new RuntimeException(); //故意抛出异常

12 }

13

14 public void init(String name,int age){

15 System.out.println("ApsectBiz.init : "+ name +" " +age);

16 }

17 }

XML配置:

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

2 <beans xmlns="http://www.springframework.org/schema/beans"

3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

4 xmlns:aop="http://www.springframework.org/schema/aop"

5 xmlns:context="http://www.springframework.org/schema/context"

6 xsi:schemaLocation="http://www.springframework.org/schema/beans

7 http://www.springframework.org/schema/beans/spring-beans-4.1.xsd

8 http://www.springframework.org/schema/context

9 http://www.springframework.org/schema/context/spring-context-4.1.xsd

10 http://www.springframework.org/schema/aop

11 http://www.springframework.org/schema/aop/spring-aop-4.1.xsd">

12

13 <bean id="myAspect" class="com.aop.schema.MyAspect"></bean>

14

15 <bean id="apsectBiz" class="com.aop.schema.ApsectBiz"></bean>

16

17 <aop:config>

18 <aop:aspect id="myAspectAOP" ref="myAspect">

19 <!-- 先注释掉,便于观察结果

20 <aop:pointcut id="myPointcut" expression="execution(* com.aop.schema.ApsectBiz.*(..))" />

21 <aop:before method="before" pointcut-ref="myPointcut"/>

22 <aop:after-returning method="afterreturning" pointcut-ref="myPointcut"/>

23 <aop:after-throwing method="afterthrowing" pointcut-ref="myPointcut"/>

24 <aop:after method="after" pointcut-ref="myPointcut"/>

25 <aop:around method="around" pointcut-ref="myPointcut"/>

26 -->

27

28 <aop:around method="around_init" pointcut="execution(* com.aop.schema.ApsectBiz.init(String,int)) and args(name,age)"/>

29 </aop:aspect>

30 </aop:config>

31

32 </beans>

单元测试:

package com.aop.schema;

import org.junit.Test;

import org.springframework.context.ApplicationContext;

import org.springframework.context.support.ClassPathXmlApplicationContext;

public class UnitTest {

@Test

public void test(){

ApplicationContext context = new ClassPathXmlApplicationContext("classpath:spring-aop.xml");

ApsectBiz biz = (ApsectBiz)context.getBean("apsectBiz");

biz.init("Json",25);

}

}

结果:

七月 09, 2015 11:48:42 下午 org.springframework.context.support.AbstractApplicationContext prepareRefresh

INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@118e0f0f: startup date [Thu Jul 09 23:48:42 CST 2015]; root of context hierarchy

七月 09, 2015 11:48:42 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions

INFO: Loading XML bean definitions from class path resource [spring-aop.xml]

Json 25

MyAspect.around_1

ApsectBiz.init : Json 25

MyAspect.around_2

本文内容总结:Spring_7_AOP之Advice应用

原文链接:https://www.cnblogs.com/charles999/p/6650013.html

以上是 Spring_7_AOP之Advice应用 的全部内容, 来源链接: utcz.com/z/362894.html

回到顶部