JDK和CGLib两种方式实现动态代理模式
2014-11-11 20:44
791 查看
这篇文章主要介绍利用JDK和cgLib两种方式实现动态代理模式的实例。
其运行结果如下:
这样,通过动态代理,就成功的在sayHello()和print()两个方法前后加了Log日志。
全文完。转载请注明出处。
1. 利用JDK中的类
在JDK中的动态代理用到了两个类:Proxy和InvocationHandler,如下:1.1 抽象主题
抽象主题的Java代码如下:public interface Hello { void sayHello(String to); void print(String p); }
1.2 实际主题
实际主题的Java代码如下:public class HelloImpl implements Hello { @Override public void sayHello(String to) { System.out.println("Say Hello to " + to); } @Override public void print(String p) { System.out.println("print : " + p); } }
1.3 代理
代理要实现的功能为:在sayHello()和print()两个方法前后加了Log日志。代理类的代码如下:import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; public class LogHandler implements InvocationHandler { private Object dele; //被代理对象传进来了 public LogHandler(Object obj) { this.dele = obj; } public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { doBefore(); // 在这里完全可以把下面这句注释掉,而做一些其它的事情 Object result = method.invoke(dele, args); doAfter(); return result; } private void doBefore() { System.out.println("before...."); } private void doAfter() { System.out.println("after...."); } }
1.4测试运行
import java.lang.reflect.Proxy; public class ProxyTest { public static void main(String[] args) { Hello impl = new HelloImpl(); LogHandler handler = new LogHandler(impl); // 这里把handler与impl新生成的代理类相关联 Hello hello = (Hello) Proxy.newProxyInstance( impl.getClass().getClassLoader(), impl.getClass().getInterfaces(), handler); // 这里无论访问哪个方法,都是会把请求转发到handler.invoke hello.print("All the test"); hello.sayHello("Denny"); } }
其运行结果如下:
这样,通过动态代理,就成功的在sayHello()和print()两个方法前后加了Log日志。
2. 利用cgLib中的类
下面这个例子展现了利用cgLib实现对ArrayList进行拦截,在在add或addAll元素的之前,会实行拦截操作,执行相关操作后再添加到ArrayList中去。2.1 代理(拦截器)
import java.lang.reflect.Method; import java.util.List; import net.sf.cglib.proxy.MethodInterceptor; import net.sf.cglib.proxy.MethodProxy; /** * 利用cglib的动态代理方法。java.util.List的拦截器,在add或addAll元素的之前, * 会实行拦截操作, 执行相关操作后再添加到ArrayList中去。<br> */ public class ListAddMethodInterceptor implements MethodInterceptor { @Override @SuppressWarnings("unchecked") public Object intercept(Object object, Method method, Object[] args, MethodProxy methodProxy) throws Throwable { //函数体的执行 if(args != null && args.length >= 1) { if(method.getName().equals("add")) { //add方法 addedThing = (T) args[0]; //被添加的对象 //进行过滤操作,在线化简时,这里就是执行局部搜索策略 doSomething(); } else if(method.getName().equals("addAll")) { List<IChromosome> list = (List<IChromosome>) args[0]; for(int i=0; i<list.size(); i++) { addedThing = (T)list.get(i); //被添加的对象 //进行过滤操作,在线化简时,这里就是执行局部搜索策略 doSomething (); } } } //拦截完毕,放行 Object result = methodProxy.invokeSuper(object, args); return result; } }
2.2 主要的调用方法
针对上述代理,其调用方式如下:import net.sf.cglib.proxy.Enhancer; // 设置java.util.List的动态代理 Enhancer en = new Enhancer(); // 进行代理 en.setSuperclass(java.util.ArrayList.class); en.setCallback(new ListAddMethodInterceptor(pts, distanceTolerance)); // en.setCallbackFilter(new ListCallbackFilter()); @SuppressWarnings("unchecked") List<IChromosome> popu = (List<IChromosome>) en.create(); // 动态代理设置结束
3 cgLib与JDK相比的优势
cgLib与JDK相比最大的好处就是不再需要主题有抽象接口。例如HelloImpl类,如果它没有Hello接口则无法使用动态代理,而利用cgLib则没有这方面的限制。全文完。转载请注明出处。
相关文章推荐
- Spring AOP 代理实现的两种方式: JDK动态代理 和 Cglib框架动态代理
- Spring中AOP实现的两种方式之JDK和cglib的动态代理
- 实现动态代理的两种方式介绍+例子demo(JDK、CGlib)
- Spring中AOP实现的两种方式之JDK和cglib的动态代理
- 深入理解java动态代理的两种实现方式(JDK/Cglib)
- 动态代理的两种实现方式(JDK/Cglib)
- spring02 注解方式实现MVC、spring的继承、代理模式(静/动) :jdk动态代理,cglib动态代理
- 动态代理及其两种实现方式(JDK、CGLIB)
- JDK动态代理(Proxy)的两种实现方式
- java动态代理的两种方式---jdk和cglib
- 三种实现动态代理方式(jdk、cglib、javaassist)
- 动态代理的两种方式jdk和cglib
- Spring的两种代理方式:JDK动态代理和CGLIB动态代理
- Spring系列之 (十一):AOP实现方式:动态代理的两个方式(JDK和Cglib)
- 动态代理的两种实现:JDK动态代理、CGLib动态代理
- 使用JDK和Cglib两种方式动态代理
- 详解Spring的两种代理方式:JDK动态代理和CGLIB动态代理
- spring AOP 两种底层实现( JDK动态代理 和 CGLIB代理)
- Java动态代理模式jdk和cglib的2种实现以及二者的区别(AOP面向切面的前奏)
- Java动态代理模式jdk和cglib的2种实现以及二者的区别(AOP面向切面的前奏)