标签:
最简单的是静态代理方法,即代理模式,这里就不多啰嗦了。。
重点说一下JDK的动态代理和Cglib的动态代理吧
先说JDK的,需要被代理的类需要有接口,否则无法实现
package proxy.dynamic; public interface IBook { void add(); }
实现接口的类如下
package proxy.dynamic; public class Book implements IBook { @Override public void add() { System.out.println("Add Method!"); } }
创建一个代理类,需要实现一个接口InvocationHandler接口,里面有一个invoke方法需要实现
同时创建一个生成实例的方法
package proxy.dynamic; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; public class BookProxy implements InvocationHandler{ private Object target; public Object bind(Object target) { this.target = target; return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);//这里需要接口 } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object result=null; System.out.println("Before"); result=method.invoke(target, args);//执行方法 System.out.println("After"); return result; } }
接下来创建测试类
package proxy.dynamic; public class Test { /** * @param args */ public static void main(String[] args) { BookProxy bp = new BookProxy(); IBook book = (IBook) bp.bind(new Book()); book.add(); } }
可以看到依次输出了Before,方法,After
下面说一下Cglib的代理,Cglib代理不需要原类实现接口,依赖Cglib和asm两个Jar包
需要代理的类如下
package cglib.proxy; public class Book { public void add() { System.out.println("Add Method!"); } }
创建一个代理类,实现MethodInterceptor接口,同时写一个生成实例的getInstance方法
package cglib.proxy; import java.lang.reflect.Method; import net.sf.cglib.proxy.Enhancer; import net.sf.cglib.proxy.MethodInterceptor; import net.sf.cglib.proxy.MethodProxy; public class CglibProxy 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(); } @Override public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable { System.out.println("Before"); proxy.invokeSuper(obj, args); System.out.println("After"); return null; } }
接下来就是简单测试一下
package cglib.proxy; public class Test { /** * @param args */ public static void main(String[] args) { CglibProxy proxy = new CglibProxy(); Book book=(Book) proxy.getInstance(new Book()); book.add(); } }
运行效果一样的
简单总结一下,JDK动态代理,需要实现一个接口InvocationHandler,要求被代理的对象必须有一个接口
Cglib代理需要实现MethodInterceptor接口,不需要被代理的类必须有接口
性能方法,参考其他文章,说JDK代理适合多例模式,而单例模式Cglib更好一些,因为Cglib是用底层的字节码技术生成实例,耗费时间较长,性能不如JDK动态代理。(有待验证。。)
标签:
原文地址:http://my.oschina.net/eviltuzki/blog/523352