- 浏览: 131183 次
- 性别:
- 来自: 深圳
文章分类
最新评论
-
可怜的猫:
不懂
AOP实现(三)——Spring 2.0中Pointcut的定义 -
mirikle:
oh sorry, just for testing...
AOP实现(三)——Spring 2.0中Pointcut的定义 -
mirikle:
AOP实现(三)——Spring 2.0中Pointcut的定义 -
every:
垃圾 全TM copy
Derby数据库入门 -
西风的话:
嗯,对初学者很有帮助,正在学习中~~
Derby数据库入门
在Spring1.2或之前的版本中,实现AOP的传统方式就是通过实现Spring的AOP API来定义Advice,并设置代理对象。Spring根据Adivce加入到业务流程的时机的不同,提供了四种不同的Advice:Before Advice、After Advice、Around Advice、Throw Advice。
1、Before Advice
顾名思义,Before Advice会在目标对象的方法执行之前被调用,您可以通过实现org.springframework.aop.MethodBeforeAdvice接口来实现Before Advice的逻辑,接口定义如下:
其中BeforeAdvice继承自Adivce接口,这两者都是标签接口,并没有定义任何具体的方法。before方法会在目标对象的指定方法执行之前被执行,在before方法种,你可以取得指定方法的Method实例、参数列表和目标对象,在before方法执行完后,目标对象上的方法将会执行,除非在before方法种抛出异常。
下面通过例子来说明Before Advice的使用方法。首先定义目标对象所要实现的接口:
接着实现MessageSender接口:
OK,我们的业务代码实现完了,现在如果要在不改变我们的业务代码的前提下,在执行业务代码前要记录一些日志,这时就可以通过实现MethodBeforeAdvice接口来实现,如:
然后再在XML进行如下定义:
这样我们就为MessageSender对象指定了Before Advice对象。在这里,我们分别定义了一个MessageSender对象(messageSenderImpl)和一个Before Advice对象(logBeforeAdvice),并定义了一个org.springframework.aop.framework.ProxyFactoryBean对象(messageSender),FactoryBean或ApplicationContext将使用ProxyFactoryBean来建立代理对象,在这里就是messageSenderImpl建立代理对象。在ProxyFactoryBean的定义中,proxyInterfaces属性指定了要代理的接口;target指定了要建立代理的目标对象;interceptorNames则指定了应用与指定接口上的Advices对象列表,spring将根据列表中定义的顺序在执行目标对象的方法前、后执行Advice中定义的方法。
现在我们写一个程序来验证下:
执行结果:
Log before public abstract void com.savage.simplespring.bean.MessageSender.send(java.lang.String) by LogBeforeAdvice.
Send Message[message] by http.
正如你所看到的,在执行MessageSender的send方法前先执行了LogBeforeAdvice的方法!在这个例子中,记录日志的代码并没有横切到我们的业务代码中,LogBeforeAdvice和HttpMessageSender彼此不知道对方的存在,而且我们的应用程序AdviceDemo对LogBeforeAdvice的存在也是一无所知。假如有一天我们的应用程序不需要再业务代码执行前记录日志了,只需要修改XML文件中的定义,而不用更改AdviceDemo的代码:
2、After Advice
After Advice会在目标对象的方法执行完后执行,你可以通过实现org.springframework.aop.AfterReturingAdvice接口来实现After Advice的逻辑,AfterReturingAdvice接口定义如下:
在afterReturning方法中,你可以获得目标方法执行后的返回值、目标方法对象、目标方法的参数以及目标对象。
继续以上面的例子为例,如果要在MessageSender的send方法执行完后,要再记录日志,那么我们可以先实现AfterReturningAdvice接口:
然后在XML文件中指定LogAfterAdvice的实例:
在前面Before Advice的基础上,我们为MessageSender再指定了一个LogAfterAdvice的服务。运行前面的AdviceDemo,结果如下:
Send Message[message] by http.
Log after public abstract void com.savage.simplespring.bean.MessageSender.send(java.lang.String) by LogAfterAdvice.
3、Around Advice
在上面的LogAfterAdvice例子中,我们通过指定BeforeAdvice和AfterReturingAdvice,在MessageSender的send方法前后执行额外的业务。实际上,如果需要在业务代码执行前后增加额外的服务,你可以直接通过实现org.aopalliance.intercept.MethodInterceptor接口来达到这一目的,MethodInterceptor定义如下:
例如:
正如上面所示,在MethodInterceptor中你得自行决定是否调用MethodInvocation的proceed()方法来执行目标对象上的方法,proceed()方法在执行完后会返回目标对象上方法的执行结果。
MethodInterceptor在XML文件中的定义如下:
Spring在真正执行目标对象的方法前,会执行interceptorNames中执行的Advice,每个Advice在执行完自己的业务后,会调用MethodInvocation的proceed()方法,将执行的主动权移交给下一个Advice,直到没有下一个Advice为止,在执行完目标对象的方法后,Spring会再以相反的顺序一层层的返回。例如:
象上面这个例子,logBeforeAdvice先会被执行,然后执行logAdvice,接着执行logAfterAdvice,最后又返回到了logAdvice。
现在我们把LogAdvice作一下简单的修改,增加一个id属性,用以在后面查看Advice的调用顺序:
同时把XML中的定义改为:
现在再执行AdviceDemo,得到如下结果:
Log before public abstract void com.savage.simplespring.bean.MessageSender.send(java.lang.String) by LogBeforeAdvice.
Log before public abstract void com.savage.simplespring.bean.MessageSender.send(java.lang.String) by LogAdvice[1].
Log before public abstract void com.savage.simplespring.bean.MessageSender.send(java.lang.String) by LogAdvice[2].
Send Message[message] by http.
Log after public abstract void com.savage.simplespring.bean.MessageSender.send(java.lang.String) by LogAdvice[2].
Log after public abstract void com.savage.simplespring.bean.MessageSender.send(java.lang.String) by LogAfterAdvice.
Log after public abstract void com.savage.simplespring.bean.MessageSender.send(java.lang.String) by LogAdvice[1].
4、Throw Advice
如果想要在异常发生时执行某些业务,你可以通过实现org.springframework.aop.ThrowsAdvice接口,这是一个标签接口,没有定义任何方法,你可以在当中为每个你需要处理的异常类定义afterThrowing方法,当程序出现异常时,spring会根据异常的类型调用对应的afterThrowing方法。AfterThrowing的格式如下:
方括号[]中的参数为可选项,但方法中必须有subClassOfThrowable,且必须是Throwable的子类。
Spring在调用完afterThrowing方法后,原先的异常会继续在程序中传播,如果象要终止程序对异常的处理,只能在afterThrowing方法中抛出其他异常。
1、Before Advice
顾名思义,Before Advice会在目标对象的方法执行之前被调用,您可以通过实现org.springframework.aop.MethodBeforeAdvice接口来实现Before Advice的逻辑,接口定义如下:
java 代码
- package org.springframework.aop;
- public interface MethodBeforeAdvice extends BeforeAdvice {
- void before(Method method, Object[] args, Object target) throws Throwable;
- }
其中BeforeAdvice继承自Adivce接口,这两者都是标签接口,并没有定义任何具体的方法。before方法会在目标对象的指定方法执行之前被执行,在before方法种,你可以取得指定方法的Method实例、参数列表和目标对象,在before方法执行完后,目标对象上的方法将会执行,除非在before方法种抛出异常。
下面通过例子来说明Before Advice的使用方法。首先定义目标对象所要实现的接口:
java 代码
- package com.savage.aop
- public interface MessageSender {
- void send(String message);
- }
接着实现MessageSender接口:
java 代码
- package com.savage.aop;
- public class HttpMessageSender implements MessageSender {
- public void send(String message) {
- System.out.println("Send Message[" + message + "] by http.");
- }
- }
OK,我们的业务代码实现完了,现在如果要在不改变我们的业务代码的前提下,在执行业务代码前要记录一些日志,这时就可以通过实现MethodBeforeAdvice接口来实现,如:
java 代码
- package com.savage.aop;
- import java.lang.reflect.Method;
- import org.springframework.aop.framework.MethodBeforeAdvice;
- public class LogBeforeAdvice implements MethodAdvice {
- public void before(Method method, Object[] args, Object target) throws Throwable {
- System.out.println("Log before " + method + " by LogBeforeAdvice.");
- }
- }
然后再在XML进行如下定义:
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"
- xsi:schemaLocation="http://www.springframework.org/schema/beans
- http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
- <bean id="messageSenderImpl" class="com.savage.aop.HttpMessageSender"></bean>
- <bean id="logBeforeAdvice" class="com.savage.aop.LogBeforeAdvice"></bean>
- <bean id="messageSender" class="org.springframework.aop.framework.ProxyFactoryBean">
- <property name="proxyInterfaces" value="com.savage.aop.MessageSender"/>
- <property name="target" ref="messageSenderImpl"/>
- <property name="interceptorNames">
- <list>
- <value>logBeforeAdvice</value>
- </list>
- </property>
- </bean>
- </beans>
这样我们就为MessageSender对象指定了Before Advice对象。在这里,我们分别定义了一个MessageSender对象(messageSenderImpl)和一个Before Advice对象(logBeforeAdvice),并定义了一个org.springframework.aop.framework.ProxyFactoryBean对象(messageSender),FactoryBean或ApplicationContext将使用ProxyFactoryBean来建立代理对象,在这里就是messageSenderImpl建立代理对象。在ProxyFactoryBean的定义中,proxyInterfaces属性指定了要代理的接口;target指定了要建立代理的目标对象;interceptorNames则指定了应用与指定接口上的Advices对象列表,spring将根据列表中定义的顺序在执行目标对象的方法前、后执行Advice中定义的方法。
现在我们写一个程序来验证下:
java 代码
- package com.savage.aop;
- import org.springframework.context.ApplicationContext;
- import org.springframework.context.support.ClassPathXmlApplication;
- public class AdviceDemo {
- public void main(String[] args) {
- ApplicationContext context = new ClassPathXmlApplicationContext("beans-config.xml");
- MessageSender sender = (MessageSender)context.getBean("messageSender");
- sender.send("message");
- }
- }
执行结果:
Log before public abstract void com.savage.simplespring.bean.MessageSender.send(java.lang.String) by LogBeforeAdvice.
Send Message[message] by http.
正如你所看到的,在执行MessageSender的send方法前先执行了LogBeforeAdvice的方法!在这个例子中,记录日志的代码并没有横切到我们的业务代码中,LogBeforeAdvice和HttpMessageSender彼此不知道对方的存在,而且我们的应用程序AdviceDemo对LogBeforeAdvice的存在也是一无所知。假如有一天我们的应用程序不需要再业务代码执行前记录日志了,只需要修改XML文件中的定义,而不用更改AdviceDemo的代码:
xml 代码
- <bean id="messageSender" class="com.savage.aop.HttpMessageSender"><!---->bean>
2、After Advice
After Advice会在目标对象的方法执行完后执行,你可以通过实现org.springframework.aop.AfterReturingAdvice接口来实现After Advice的逻辑,AfterReturingAdvice接口定义如下:
java 代码
- package org.springframework.aop;
- public interface AfterReturningAdvice {
- void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable;
- }
在afterReturning方法中,你可以获得目标方法执行后的返回值、目标方法对象、目标方法的参数以及目标对象。
继续以上面的例子为例,如果要在MessageSender的send方法执行完后,要再记录日志,那么我们可以先实现AfterReturningAdvice接口:
java 代码
- package com.savage.aop;
- import org.springframework.aop;
- public LogAfterAdvice implements AfterReturningAdvice {
- public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {
- System.out.println("Log after " + method + " by LogAfterAdvice.");
- }
- }
然后在XML文件中指定LogAfterAdvice的实例:
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"
- xsi:schemaLocation="http://www.springframework.org/schema/beans
- http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
- <bean id="messageSenderImpl" class="com.savage.aop.HttpMessageSender"></bean>
- <bean id="logBeforeAdvice" class="com.savage.aop.LogBeforeAdvice"></bean>
- <bean id="messageSender" class="org.springframework.aop.framework.ProxyFactoryBean">
- <property name="proxyInterfaces" value="com.savage.aop.MessageSender"/>
- <property name="target" ref="messageSenderImpl"/>
- <property name="interceptorNames">
- <list>
- <value>logAfterAdvice</value>
- </list>
- </property>
- </bean>
- </beans>
在前面Before Advice的基础上,我们为MessageSender再指定了一个LogAfterAdvice的服务。运行前面的AdviceDemo,结果如下:
Send Message[message] by http.
Log after public abstract void com.savage.simplespring.bean.MessageSender.send(java.lang.String) by LogAfterAdvice.
3、Around Advice
在上面的LogAfterAdvice例子中,我们通过指定BeforeAdvice和AfterReturingAdvice,在MessageSender的send方法前后执行额外的业务。实际上,如果需要在业务代码执行前后增加额外的服务,你可以直接通过实现org.aopalliance.intercept.MethodInterceptor接口来达到这一目的,MethodInterceptor定义如下:
java 代码
- package org.aopalliance.intercept;
- public interface MethodInterceptor {
- public Object invoke(MethodInvocation methodInvocation) throws Throwable;
- }
例如:
java 代码
- package com.savage.aop;
- import org.aopalliance.intercept.MethodInterceptor;
- import org.aopalliance.intercept.MethodInvocation;
- public class LogAdvice implements MethodInterceptor {
- public Object invoke(MethodInvocation methodInvocation) throws Throwable {
- System.out.println("Log before " + methodInvocation.getMethod() + " by LogAdvice.");
- Object retValue = methodInvocation.proceed();
- System.out.println("Log after " + methodInvocation.getMethod() + " by LogAdvice.");
- return retValue;
- }
- }
正如上面所示,在MethodInterceptor中你得自行决定是否调用MethodInvocation的proceed()方法来执行目标对象上的方法,proceed()方法在执行完后会返回目标对象上方法的执行结果。
MethodInterceptor在XML文件中的定义如下:
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"
- xsi:schemaLocation="http://www.springframework.org/schema/beans
- http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
- <bean id="messageSenderImpl" class="com.savage.aop.HttpMessageSender"></bean>
- <bean id="logAdvice" class="com.savage.aop.LogAdvice"></bean>
- <bean id="messageSender" class="org.springframework.aop.framework.ProxyFactoryBean">
- <property id="proxyInterfaces" value="com.savage.aop.MessageSender"/>
- <property id="target" ref="messageSenderImpl"/>
- <property id="interceptorNames">
- <list>
- <value>logAdvice</value>
- </list>
- </property>
- </bean>
- </beans>
Spring在真正执行目标对象的方法前,会执行interceptorNames中执行的Advice,每个Advice在执行完自己的业务后,会调用MethodInvocation的proceed()方法,将执行的主动权移交给下一个Advice,直到没有下一个Advice为止,在执行完目标对象的方法后,Spring会再以相反的顺序一层层的返回。例如:
xml 代码
- <bean id="messageSender" class="org.springframework.aop.framework.ProxyFactoryBean">
- <property id="proxyInterfaces" value="com.savage.aop.MessageSender"/>
- <property id="target" ref="messageSenderImpl"/>
- <property id="interceptorNames">
- <list>
- <value>logBeforeAdvice</value>
- <value>logAdvice</value>
- <value>logAfterAdvice</value>
- </list>
- </property>
- </bean>
象上面这个例子,logBeforeAdvice先会被执行,然后执行logAdvice,接着执行logAfterAdvice,最后又返回到了logAdvice。
现在我们把LogAdvice作一下简单的修改,增加一个id属性,用以在后面查看Advice的调用顺序:
java 代码
- package com.savage.aop;
- import org.aopalliance.intercept.MethodInterceptor;
- import org.aopalliance.intercept.MethodInvocation;
- public class LogAdvice implements MethodInterceptor {
- private static int INSTANCE_NUM = 0;
- private int id;
- public LogAdvice() {
- id = ++INSTANCE_NUM;
- }
- public Object invoke(MethodInvocation methodInvocation) throws Throwable {
- System.out.println("Log before " + methodInvocation.getMethod() + " by LogAdvice[" + id + "].");
- Object retValue = methodInvocation.proceed();
- System.out.println("Log after " + methodInvocation.getMethod() + " by LogAdvice[" + id + "].");
- return retValue;
- }
- }
同时把XML中的定义改为:
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"
- xsi:schemaLocation="http://www.springframework.org/schema/beans
- http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
- <bean id="messageSenderImpl" class="com.savage.aop.HttpMessageSender"></bean>
- <bean id="logBeforeAdvice" class="com.savage.aop.LogBeforeAdvice"></bean>
- <bean id="logAfterAdvice" class="com.savage.aop.LogAfterAdvice"></bean>
- <bean id="logAdvice1" class="com.savage.aop.LogAdvice"></bean>
- <bean id="logAdvice2" class="com.savage.aop.LogAdvice"></bean>
- <bean id="messageSender" class="org.springframework.aop.framework.ProxyFactoryBean">
- <property id="proxyInterfaces" value="com.savage.aop.MessageSender"/>
- <property id="target" ref="messageSenderImpl"/>
- <property id="interceptorNames">
- <list>
- <value>logBeforeAdvice</value>
- <value>logAdvice1</value>
- <value>logAfterAdvice</value>
- <value>logAdvice2</value>
- </list>
- </property>
- </bean>
- </beans>
现在再执行AdviceDemo,得到如下结果:
Log before public abstract void com.savage.simplespring.bean.MessageSender.send(java.lang.String) by LogBeforeAdvice.
Log before public abstract void com.savage.simplespring.bean.MessageSender.send(java.lang.String) by LogAdvice[1].
Log before public abstract void com.savage.simplespring.bean.MessageSender.send(java.lang.String) by LogAdvice[2].
Send Message[message] by http.
Log after public abstract void com.savage.simplespring.bean.MessageSender.send(java.lang.String) by LogAdvice[2].
Log after public abstract void com.savage.simplespring.bean.MessageSender.send(java.lang.String) by LogAfterAdvice.
Log after public abstract void com.savage.simplespring.bean.MessageSender.send(java.lang.String) by LogAdvice[1].
4、Throw Advice
如果想要在异常发生时执行某些业务,你可以通过实现org.springframework.aop.ThrowsAdvice接口,这是一个标签接口,没有定义任何方法,你可以在当中为每个你需要处理的异常类定义afterThrowing方法,当程序出现异常时,spring会根据异常的类型调用对应的afterThrowing方法。AfterThrowing的格式如下:
java 代码
- afterThrowing([Method],[args],[target],subClassOfThrowable);
方括号[]中的参数为可选项,但方法中必须有subClassOfThrowable,且必须是Throwable的子类。
Spring在调用完afterThrowing方法后,原先的异常会继续在程序中传播,如果象要终止程序对异常的处理,只能在afterThrowing方法中抛出其他异常。
发表评论
-
JDBC的支持——DataSource的配置
2008-02-28 23:00 3016Spring中DataSource的注入方法: 1) 在进行单 ... -
Bean基本管理的小细节
2008-01-25 00:31 1616Spring使用BeanFactory、Application ... -
ApplicationContext的初始化
2008-01-25 00:18 6087以ClassPathXmlApplicationConte ... -
Spring的最佳入门手册:Spring in action
2008-01-13 09:02 1727对于Spring的初学者来说,《Spring in actio ... -
AOP实现(三)——Spring 2.0中Pointcut的定义
2007-11-17 11:04 22629在Spring 2.0中,Pointcut的定义包括两 ... -
AOP实现(二)——Spring 2.0中的AOP实现
2007-11-16 08:02 7918在Spring 2.0中,除了传统的通过实现AOP A ... -
Bean的生命周期
2007-11-06 08:37 1696一个Bean从建立到销毁,会经历几个阶段,如果使用Be ...
相关推荐
在Spring框架中,AOP(面向切面编程)是一种强大的设计模式,用于处理系统中的横切关注点,如日志、事务管理等。本篇主要探讨如何在AOP的Advice方法中获取目标方法的参数。 首先,理解AOP的基本概念至关重要。在...
Spring AOP(面向切面编程)是Spring框架的重要组成部分,它提供了一种模块化和声明式的方式来实现横切关注点,如日志、事务管理、性能监控等。本入门案例将帮助你理解并掌握Spring AOP的基本概念和使用方法。 在...
Spring AOP 是一种面向切面编程的技术,它允许我们在不修改源代码的情况下,对应用程序的特定部分(如方法调用)进行增强。在 Spring 中,AOP 的实现主要依赖于代理模式,有两种代理方式:JDK 动态代理和 CGLIB 动态...
AspectJ是AOP的一个具体实现,它是Xerox PARC开发的,提供了描述切面的语法,并能将切面织入Java源代码中,而不影响其可移植性。AspectJ也有配套的IDE支持,便于集成到其他Java开发环境中。 虽然AOP目前的应用范围...
"9Spring AOP 盗梦空间之四——Around"这个标题暗示我们将深入探讨Spring AOP中的一个关键概念——环绕通知(Around Advice)。环绕通知是Spring AOP中功能最全面的通知类型,它提供了对方法执行前、执行后以及异常...
在本篇博文中,我们将深入探讨Spring AOP(面向切面编程)中的一个重要概念——AfterReturning通知,这是Spring框架提供的一种强大的功能,允许我们在方法成功执行并返回后执行额外的操作。我们将通过源码分析和实际...
首先,我们要了解AOP的核心概念——切面(Aspect)、通知(Advice)、连接点(Join Point)、切入点(Pointcut)和织入(Weaving)。切面是关注点的模块化,如日志或事务管理;通知是在特定连接点执行的行为;连接点...
在Java开发领域,Spring框架是不可或缺的一部分,它提供了许多强大的功能,其中AOP(面向切面编程)是其重要特性之一。AOP允许开发者将关注点分离,使得业务逻辑代码与系统服务如日志、事务管理等可以独立处理,提高...
"spring-aop-jar"这个主题涉及到Spring框架中的核心组件之一——Spring AOP。这里我们将深入探讨Spring AOP、相关jar文件以及它们在实际开发中的作用。 首先,我们来看一下提供的文件: 1. aopalliance.jar:这是一...
标题提到的"Spring 使用AspectJ 实现 AOP之前置通知小例子",指的是利用AspectJ在Spring中实现AOP的一种特定类型的通知——前置通知(Before advice)。前置通知在目标方法执行之前运行,但不会阻止方法的执行。这种...
AspectJ是一个强大的、成熟的AOP框架,它支持静态和动态编织,并提供了自己的语言扩展——AspectJ语言,用于声明切面和通知(advice)。AspectJ Weaver是其核心组件,能够在类加载时或运行时将切面与应用程序代码...
本篇文章将探讨Spring框架中的一个重要特性——AOP(面向切面编程)。AOP为开发者提供了在不修改源代码的情况下,对程序进行功能增强的能力,使得我们可以更方便地处理如日志记录、事务管理、权限控制等横切关注点。...
ByteBuddy是Java的一个库,用于在运行时创建和修改Java类和接口,它是创建Java代理或者实现AOP(面向切面编程)框架的理想工具。在本项目"基于Bytebuddy的Java Agent AOP框架.zip"中,我们将探讨如何使用ByteBuddy...
然后,我们可以定义一个切面(Aspect),它包含通知(Advice)——即在特定连接点执行的代码。通知可以是前置通知(Before)、后置通知(After)、返回后通知(After Returning)、异常后通知(After Throwing)和...
《深入解析Spring AOP框架——以spring-aop.jar为例》 Spring AOP,全称Aspect Oriented Programming(面向切面编程),是Spring框架的核心部分之一,它为Java开发者提供了强大的面向切面的编程能力。本文将围绕...
本例中,我们关注的是如何利用Spring AOP配置一个简单的切面,该切面在`DukePerformer`类的`perform`方法执行前后,插入观众的行为,如找座位、关手机、鼓掌以及不满意的反应。通过这种方式,我们将这些行为抽象为...
对于案例中的问题——重复的事务控制代码,可以使用AOP技术通过动态代理的方式解决: - **思路**:创建代理对象,在执行业务逻辑时增加事务支持。 - **实现步骤**:选择合适的代理机制,比如JDK动态代理或CGLib。 #...