面向切面编程( Aspect - Oriented Programming, AOP)是对面向对象开发的一种补充,它允许开发人员在不改变原来模型的基础上动态地修改模型以满足新的需求,例如,开发人员可以在不改变原来业务逻辑模型的基础上可以动态地增加日志、安全或异常处理的功能。
下面介绍一一个在Spring中使用AOP编程的简单例子。
1)创建一个接口以及实现这个接口的类。TestAOPIn. java文件的内容如下所示。
public interface TestAOPIn {
public void doSomething( );
}
TestAOPImpl. java文件的内容如下所示。
public class TestAOPlmpl implements TestAOPIn {
public void doSomething( ) {
System. out printin( "TestAOPImpl :doSomething" );
}
}
2)配置SpringConfig. xml,使得这个类的实例化对象可以被注入到使用这个对象的Test类中。
< ?xml version="1. 0" encoding= "UTF - 8"?. >
< !DOCTYPE beans PUBLIC" -//SPRING//DTD BEAN//EN"”htp:// www. springframework. ory/drd/spring - beans. dtd" >
< beans >
< bean id = " testAOPBean" class = " org. springframework. aop. framework. ProxyFactoryBean" >
< property name =”target" >
< bean class =”testAOPIn" singleton= ”false" / >
</ property >
< /bean >
</beans>
3)在完成配置文件后, 编写如下测试代码
import org. springframework. context. ApplicationContext;
import org springfamework. context. support. FileSystemXmApplcationConext;
public class Test {
public static void main( String[] args){
ApplicationContext ctx = new FileSystemXmlApplicationContext(”SpringConfig xml ");
TesAOPln l=(TesAOPmn)cx. getBen("testAOPBean);
t.doSomething( ) ;
}
}
程序运行结果为:
TestAOPlmpl :doSomething
编写完这个模块后,开发人员需要增加对doSomething( )方法调用的跟踪,也就是说,要跟踪该方法何时被调用以及调用何时结束等内容。当然,使用传统的方法也可以实现该功能,但却会产生额外的开销,即需要修改已存在的模块。此时可以采用AOP的方式来实现这个功能。它在不修改原有模块的前提下可以完成相同的功能。
publie void daSomething( ){
System.out.println("beginCall doSomething");
System. out. println( " TestAOPlmpl:doSomething");
System. out. println(" endCall doSomething");
}
其实现原理如图所示:
为此需要提供用来跟踪函数调用的类。traceBeforeCall.java文件的内容如下所示:
public class traceBeforeCall implements MethodBeforeAdvice{
public void beforeCall ( Method arg0 , Object[ ] argl , Object arg2) throws Throwable {
System. out. printn(”beginCall doSomething ");
}
}
traceEndCall. java文件的内容如下所示:
import java. lang, eleet. Method;
import org. springframework. aop. AfterRetumingAdvice;
public class traceEndCall implements AfterReturmingAdvice{
public void afterCall( Object arg0, Method arg1 , Object[ ] arg2 , Object arg3 ) throws Throwable{
System. out. printn(”endCall doSomething) ;
}
}
只需在配置文件中配置在调用doSomething( )方法之前需要调用traceBeforeCall 类的beforeCall( )方法以及在调用doSomething( )方法之后需要调用traceEndCall类的afterCall( )方法,Spring容器就会根据配置文件在调用doSomething()方法前后自动调用相应的方法,通过在beforeCall()方法和afterCall()方法中添加跟踪的代码就可以满足对doSomething()方法调用的跟踪要求,同时还不需要更改原来已实现的代码模块。