首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > 编程 >

java署理的两种实现

2012-11-05 
java代理的两种实现package daopublic interface BookFacade {public void addBook()}-----------------

java代理的两种实现

package dao;public interface BookFacade {       public void addBook();   }--------------------------------package dao.impl;import dao.BookFacade;public class BookFacadeImpl implements BookFacade {        public void addBook() {           System.out.println("add by jdk proxy");       }      }   --------------------------------package proxy;import java.lang.reflect.InvocationHandler;   import java.lang.reflect.Method;   import java.lang.reflect.Proxy;   //JDK动态代理代理类  public class BookFacadeProxy implements InvocationHandler {       private Object target;       /**       * 绑定委托对象并返回一个代理类       * @param target       * @return       */       public Object bind(Object target) {           this.target = target;           //取得代理对象           return Proxy.newProxyInstance(target.getClass().getClassLoader(),                   target.getClass().getInterfaces(), this);   //要绑定接口(这是一个缺陷,cglib弥补了这一缺陷)       }           /**       * 调用方法       */       public Object invoke(Object proxy, Method method, Object[] args)               throws Throwable {           Object result=null;           System.out.println("事物开始");           //执行方法           result=method.invoke(target, args);           System.out.println("事物结束");           return result;       }      }   --------------------------package proxy;import dao.BookFacade;import dao.impl.*;// 使用JDK的动态代理必须依靠接口实现public class TestProxy {          public static void main(String[] args) {           BookFacadeProxy proxy = new BookFacadeProxy();           BookFacade bookProxy = (BookFacade) proxy.bind(new BookFacadeImpl());           bookProxy.addBook();       }      } /*以上为java反射下的代理*/-------------------------------------------package dao.cglib;public class BookFacade  {   //未使用接口     public void addBook() {           System.out.println("add by Cglib.");       }      }   --------------------------------------------package proxy;import java.lang.reflect.Method;   import net.sf.cglib.proxy.Enhancer;   import net.sf.cglib.proxy.MethodInterceptor;   import net.sf.cglib.proxy.MethodProxy;  // 实现MethodInterceptor的intercept(拦截器)public class BookFacadeCglib implements MethodInterceptor  {       private Object target;           //创建代理对象      public Object getInstance(Object target) {           this.target = target;           Enhancer enhancer = new Enhancer();           enhancer.setSuperclass(this.target.getClass());           // 回调方法           enhancer.setCallback(this);           // 创建代理对象           return enhancer.create();       }             // 回调方法  (拦截器:默认拦截子类)--在这里可以做很多的文章哦    public Object intercept(Object obj, Method method, Object[] args,               MethodProxy proxy) throws Throwable {           System.out.println("Begin");                   proxy.invokeSuper(obj, args);   //obj调用对象,args参数列表        System.out.println("End");           return null;             }      }----------------------------------------package proxy;import dao.cglib.BookFacade;//使用cglib的代理public class TestCglib {           public static void main(String[] args) {           BookFacadeCglib cglib=new BookFacadeCglib();                   BookFacade bookCglib=(BookFacade)cglib.getInstance(new BookFacade());                bookCglib.addBook();       }   }

------------http://share.iteye.com/blog/1106718-------------
JDK的动态代理主要涉及到java.lang.reflect包中的两个类:Proxy和InvocationHandler。其中InvocationHandler是一个接口,可以通过实现该接口定义横切逻辑,在并通过反射机制调用目标类的代码,动态将横切逻辑和业务逻辑编织在一起。
而Proxy为InvocationHandler实现类动态创建一个符合某一接口的代理实例。

cglib(Code Generation Library)是一个强大的,高性能,高质量的Code生成类库。它可以在运行期扩展Java类与实现Java接口。
cglib封装了asm,可以在运行期动态生成新的class。
cglib用于AOP,jdk中的proxy必须基于接口,cglib却没有这个限制。

原理区别:

java动态代理是利用反射机制生成一个实现代理接口的匿名类,在调用具体方法前调用InvokeHandler来处理。而cglib动态代理是利用asm开源包,对代理对象类的class文件加载进来,通过修改其字节码生成子类来处理。

1、如果目标对象实现了接口,默认情况下会采用JDK的动态代理实现AOP
2、如果目标对象实现了接口,可以强制使用CGLIB实现AOP
3、如果目标对象没有实现了接口,必须采用CGLIB库,spring会自动在JDK动态代理和CGLIB之间转换

热点排行