怎么使用动态代理实现AOP功能

分类: J2EE   出处:iocblog整理  更新时间:2009-06-24   添加到收藏  

    一、使用的背景(也不能算是使用的背景,最多只能算是一个在什么条件下面我想到了使用动态代理实现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;

    public invokejniinfo(object proxy,
               method method,
               object[] args,
               object result,
               throwable exception){
        this.proxy = proxy;
        this.method = method;
        this.args = args;
        this.result = result;
        this.exception = exception;
    }
    …………………………………………………………
    …………………………………………………………
    所有成员的get/set方法
    …………………………………………………………
    …………………………………………………………
}

    从该类的成员变量可以知道,这个类使用来将调用函数的基本信息如代理的对象,调用的方法,调用方法的参数等信息传递给interceptor,使得在interceptor 之中可以通过使用该对象作出相应的拦截。

    3.实现一个抽象的拦截器abstractinterceptor
   
    该拦截器实现了interceptor接口,它里面的方法全都是空的,其目的是当某些拦截器只是需要实现三个方法中的一个方法或者两个方法的时候,就可以继承该抽象类,覆盖需要的实现的方法就可以了。

    4.实现日志记录拦截器loginterceptor[iocblog.net 来源]

    该拦截器主要是实现在调用之前记录日志,调用之后记录日志和出现异常的时候记录日志。其代码如下:

public class loginterceptor implements interceptor {
 private log log = logfactory.getlog(“初始化log” );
 public void before(invokejniinfo invinfo) {
  //调用invokejniinfo对象的method的getname方法获取方法名
  log.debug("enter the" + invinfo.getmethod().getname());
 }
 public void after(invokejniinfo invinfo) {
    //调用invokejniinfo对象的method的getname方法获取方法名
  log.debug("exit the" + invinfo.getmethod().getname());
 }
 public void exceptionthrow(invokejniinfo invinfo) {
   //调用invokejniinfo对象的method的getname方法获取方法名
  log.error("call the" + invinfo.getmethod().getname() + " has error!");
    //调用invokejniinfo对象的exception的getstacktrace方法获取具体异常并记录
  log.error(invinfo.getexception().getstacktrace());
 }
}
    5.实现初始化javabean拦截器initparamsinterceptor
     
    该类继承abstractinterceptor,只需覆盖before方法即可。其代码如下:
     
public class initparamsinterceptor extends abstractinterceptor {

 public void before(invokejniinfo invinfo) {
  if(invinfo.getargs().length>0){
   //初始化第一个参数
   initcontainsobjectnullutil.initcontainsoutparameter(invinfo.getargs()[0]);
  }
 }

}

[1] [2] 下一页


Tag: AOP ,动态代理



文章整理:iocblog
版权申明:本站文章均来自网络,如有侵权,请联系我们,我们收到后立即删除,谢谢!
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有。