一、使用的背景(也不能算是使用的背景,最多只能算是一个在什么条件下面我想到了使用动态代理实现AOP的拦截功能):
因为在项目中程序的结构是使用SOAP调用JNI,因此在SOAP服务端里面没有任何实现代码,仅仅是new一个JNI的对象,然后调用JNI对应的方法。但是在调用JNI方法之前需要对传进JNI的JavaBean进行初始化,而且还需要记录日志。而SOAP服务端的代码是通过ant自动生成的,需要对他进行手工的修改,在修改过程中发现每一个方法里面都是相同的:记录进入方法的日志、初始化JavaBean和记录退出方法的日志,这写东西都是通过拷贝粘贴来完成的,想到假如以后再加一个什么功能的时候又得每一个方法进行拷贝粘贴,而且方法的数量还不少,所以觉得这样来实现是不科学的。示例代码如下:
public class SOAP{
private JniInterface jni = null;
private Log log = 。。。;
public SOAP(){
jni=new JniClass();
}
/**方法A**/
public JavaBeanA aMethod(JavaBeanA javaBeanA){
log.debug("进入A方法");
//初始化JavaBean
Init(javaBeanA);
//调用JNI对应的方法
JavaBeanA result = jni.aMethod(javaBeanA);
log.debug("退出A方法");
return result;
}
……………………………………
……………………………………
等等,很多这样的方法
……………………………………
……………………………………
}
从示例代码里面可以看出,除了调用JNI对应的方法不同之外,其他的都是相同的代码,把所有的东西进行拷贝复制是不合理的。每当对SOAP进行修改,就必须将所有的方法重新拷贝粘贴。为了省去拷贝粘贴这一工序,所以使用动态代理实现AOP拦截共能。
二、实现AOP拦截
1. 定义Interceptor接口
public interface Interceptor {
//在调用之前调用该方法
public void before(InvokeJniInfo invInfo);
//在调用之后调用该方法
public void after(InvokeJniInfo invInfo);
//出现异常之后调用该方法
public void exceptionThrow(InvokeJniInfo invInfo);
}
2. 定义 InvokeJniInfo 类
在Interceptor接口中的InvokeJniInfo类,该类的定义如下:
public class InvokeJniInfo {
//被代理的对象
Object proxy;
//被调用的方法
Method method;
//被调用方法的参数列表
Object[] args;
//调用之后的结果
Object result;
//抛出的异常
Throwable exception;