a、先定义一个接口,这个接口中的方法是“目标方法”java
package com.brickworkers; public interface Sky { public void rain(); }
b、接着写一个这个接口的具体实现:spring
package com.brickworkers; public class SkyImpl implements Sky{ @Override public void rain() { System.out.println("it`s raining"); } }
c、若是要完成动态代理,首先须要定义一个InvocationHandler接口的子类:ide
package com.brickworkers; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; public class MyInvocationHandler implements InvocationHandler { //目标对象 private Object obj = null; //获取目标对象的代理对象 public Object getProxy(Object obj){ this.obj = obj; return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), this); } //控制执行目标对象的方法 @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("目标对象方法执行以前"); Object result = method.invoke(obj, args); System.out.println("目标对象方法执行以后"); return result; } }
d:JDK动态代理测试类:测试
package com.brickworkers; public class ProxyTest { public static void main(String[] args) { //实例化InvocationHandler MyInvocationHandler myInvocationHandler = new MyInvocationHandler(); //生产代理对象 Sky sky = (Sky) myInvocationHandler.getProxy(new SkyImpl()); sky.rain(); } } //执行结果: 目标对象方法执行以前 // it`s raining // 目标对象方法执行以后
为何JDK动态代理只能局限于接口呢?查阅了一些技术文档和JDK动态代理的源码,发如今反编译产生的proxyTest.class中,类的定义以下:this
import dynamic.proxy.UserService; import java.lang.reflect.*; public final class $ProxyTest extends Proxy implements Sky { ...... }
从反编译的源码能够看出,proxyTest继承了Proxy,然而在Java中只支持单继承,可是能够实现多个接口,因此JDK动态代理只能局限于接口。spa
那么JDK实现动态代理须要实现类经过接口定义业务方法,对于没有接口的类,要实现动态代理要怎么办呢?这个时候就须要CGLib动态代理了。.net
CGLib采用了很是底层的字节码技术,其原理是经过字节码技术为一个类建立子类,并在子类中采用方法拦截的技术拦截全部分类方法的调用,顺势织入和横切逻辑。-http://blog.csdn.net/yakoo5/article/details/9099133/代理
a、定义一个目标对象:对象
package com.brickworkers; public class Color { public void showColor(){ System.out.println("red"); } }
b、若是要完成动态代理,首先须要定义一个MethodInterceptor接口的子类:
package com.brickworkers; 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 MyCglib implements MethodInterceptor { //目标对象 private Object obj = null; public Object getProxy(Object obj){ this.obj = obj; Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(obj.getClass()); // 回调方法 enhancer.setCallback(this); // 建立代理对象 return enhancer.create(); } @Override public Object intercept(Object object, Method method, Object[] args, MethodProxy methodProxy) throws Throwable { System.out.println("目标对象方法执行以前"); Object result = methodProxy.invoke(obj, args); System.out.println("目标方法执行以后"); return result; } }
c、CGLib动态代理测试类:
package com.brickworkers; public class CGLibTest { public static void main(String[] args) { MyCglib myCglib = new MyCglib(); Color color = (Color) myCglib.getProxy(new Color()); color.showColor(); } } //执行结果:目标对象方法执行以前 // red // 目标方法执行以后
由于CGLib动态代理是建立一个子类来实现的,那么对于继承的定义,final类是没法进行代理的。