“它的目标不是提供最完善的AOP实现(虽然Spring AOP非常强大);而是要提供AOP实现与Spring IoC的紧密集成,以便帮助解决企业应用中的常见问题。”
Spring Framework参考文档
- 通知(Advice):如何将before通知、afterReturning通知和afterThrowing通知声明为bean。
- 切入点(Pointcut):如何声明静态切入点逻辑以将XML Spring Bean Configuration文件中的所有内容联系在一起。
- Advisor:关联切入点定义与通知bean的方式。
“一般而言,Spring并不是预描述的。虽然使用好的实践非常容易,但是它避免强制推行一种特定的方法。”
Spring Framework参考文档
public interface IBusinessLogic { public void foo(); } public class BusinessLogic implements IBusinessLogic { public void foo() { System.out.println( "Inside BusinessLogic.foo()"); } }
import org.springframework.context.ApplicationContext; import org.springframework.context.support.FileSystemXmlApplicationContext; public class MainApplication { public static void main(String [] args) { // Read the configuration file ApplicationContext ctx = new FileSystemXmlApplicationContext( "springconfig.xml"); //Instantiate an object IBusinessLogic testObject = (IBusinessLogic) ctx.getBean("businesslogicbean"); // Execute the public // method of the bean testObject.foo(); } }
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd"> <beans> <!-- Bean configuration --> <bean id="businesslogicbean" class="org.springframework.aop.framework.ProxyFactoryBean"> <property name="proxyInterfaces"> <value>IBusinessLogic</value> </property> <property name="target"> <ref local="beanTarget"/> </property> </bean> <!-- Bean Classes --> <bean id="beanTarget" class="BusinessLogic"/> </beans>
图1.没有对BusinessLogic bean应用方面时的顺序图
可能最基本的方面就是方法跟踪方面了。这可能是您找得到的最简单的方面了,因此它是研究新的AOP实现的一个很好的起点。
import java.lang.reflect.Method; import org.springframework.aop. MethodBeforeAdvice; public class TracingBeforeAdvice implements MethodBeforeAdvice { public void before(Method m, Object[] args, Object target) throws Throwable { System.out.println( "Hello world! (by " + this.getClass().getName() + ")"); } }
import java.lang.reflect.Method; import org.springframework.aop.AfterReturningAdvice; public class TracingAfterAdvice implements AfterReturningAdvice { public void afterReturning(Object object, Method m, Object[] args, Object target) throws Throwable { System.out.println( "Hello world! (by " + this.getClass().getName() + ")"); } }
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd"> <beans> <!-- Bean configuration --> <bean id="businesslogicbean" class="org.springframework.aop.framework.ProxyFactoryBean"> <property name="proxyInterfaces"> <value>IBusinessLogic</value> </property> <property name="target"> <ref local="beanTarget"/> </property> <property name="interceptorNames"> <list> <value>theTracingBeforeAdvisor</value> <value>theTracingAfterAdvisor</value> </list> </property> </bean> <!-- Bean Classes --> <bean id="beanTarget" class="BusinessLogic"/> <!-- Advisor pointcut definition for before advice --> <bean id="theTracingBeforeAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor"> <property name="advice"> <ref local="theTracingBeforeAdvice"/> </property> <property name="pattern"> <value>.*</value> </property> </bean> <!-- Advisor pointcut definition for after advice --> <bean id="theTracingAfterAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor"> <property name="advice"> <ref local="theTracingAfterAdvice"/> </property> <property name="pattern"> <value>.*</value> </property> </bean< <!-- Advice classes --> <bean id="theTracingBeforeAdvice" class="TracingBeforeAdvice"/> <bean id="theTracingAfterAdvice" class="TracingAfterAdvice"/> </beans>
- <value>.*</value>:该表达式选择advisor所关联到的一个或多个bean上的所有联结点。
- <value>./IBusinessLogic/.foo</value>:该表达式只选择IbusinessLogic接口上的foo()方法的联结点。如果是advisor所关联到的bean,则该表达式只选择IBusinessLogic接口上的联结点。
可以对方法跟踪方面进行扩展,提供一个稍微复杂的记录(Logging)方面。记录方面提供了一个很不错的重用例子,因为记录方面所需的许多特性都已经包含在方法跟踪方面中了。
public class BusinessLogicException extends Exception { } public interface IBusinessLogic { public void foo(); public void bar() throws BusinessLogicException; } public class BusinessLogic implements IBusinessLogic { public void foo() { System.out.println( "Inside BusinessLogic.foo()"); } public void bar() throws BusinessLogicException { System.out.println( "Inside BusinessLogic.bar()"); throw new BusinessLogicException(); } }
import org.springframeworkcontext.ApplicationContext; import org.springframework.context.support.FileSystemXmlApplicationContext; public class MainApplication { public static void main(String [] args) { // Read the configuration file ApplicationContext ctx = new FileSystemXmlApplicationContext( "springconfig.xml"); //Instantiate an object IBusinessLogic testObject = (IBusinessLogic) ctx.getBean( "businesslogicbean"); //Execute the public methods of the bean testObject.foo(); try { testObject.bar(); } catch(BusinessLogicException ble) { System.out.println( "Caught BusinessLogicException"); } } }
import org.springframework.aop.ThrowsAdvice; import java.lang.reflect.Method; public class LoggingThrowsAdvice implements ThrowsAdvice { public void afterThrowing(Method method, Object[] args, Object target, Throwable subclass) { System.out.println( "Logging that a " + subclass + "Exception was thrown."); } }
本文展示了使用Spring框架中的基本AOP结构所应用的一些简单方面。在本系列的下一篇文章中,我们将介绍一些更实用的方面,探讨方面的生命周期,使用Spring框架的around通知,并使用Spring来应用AOP模式。
- 本文的源代码
- Spring Java/J2EE Framework
- Spring AOP Framework
- "Introduction to Aspect-Oriented Programming"