首先我们来谈谈jdk的动态代理,它允许开发者在运行期创建接口的代理实例,那么当我们在运行过程中调用某个实例的某个方法时,可以使用代理对象去具体实现它,从而达到aop的效果。
(1)jdk的动态代理主要涉及两个类:proxy和invocacationHandler,invocationHandler里面包含了横切逻辑,并且可以使用反射调用目标类的方法(就是切点),proxy类主要是使用它的一个newinstance方法去创建一个代理实例。
下面我们来看代码:
package com.yue.test; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; public class testHandler implements InvocationHandler{ private Object target; public testHandler(Object o){ this.target = o; } /* * 这里的method对象是java反射机制中的方法反射类对象,通过这个方法反射对象可以调用目标对象中的方法 * 里面的target是目标类对象,利用反射在目标类对象中找到对应的方法传入参数后调用 * 也可以说是根据目标对象得到的代理对象是在目标对象的基础上插入了横切逻辑的 * @see java.lang.reflect.InvocationHandler#invoke(java.lang.Object, java.lang.reflect.Method, java.lang.Object[]) */ @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("hey"); Object obj = method.invoke(target, args); System.out.println("end!"); return obj; } }
package com.yue.test; public class PrivateCar implements Car{ public void say(){ System.out.println("spring is fun!"); } }
package com.yue.test; public interface Car { public void say(); }
package com.yue.test; import java.lang.reflect.Proxy; public class Test { public static void main(String[] args){ PrivateCar pc = new PrivateCar(); testHandler th = new testHandler(pc); //这里因为生成的代理对象实现了目标对象的所有接口,所以根据多态可以变为Car类型 Car car = (Car)Proxy.newProxyInstance(pc.getClass().getClassLoader(), pc.getClass().getInterfaces(), th); car.say(); } }
hey spring is fun! end!
(2)若要不是用于接口定义,则需要用到cglib代理(这里需要格外引入jar包)
cglib代理使用底层的字节码技术,可以为一个类创建子类,并在子类中采用方法拦截的技术拦截所有父类方法的调用,织入横切逻辑
下面我们来看看代码:
package com.yue.test; public class Test { public static void main(String[] args){ CglibProxy cp = new CglibProxy(); PrivateCar pc = (PrivateCar)cp.getProxy(PrivateCar.class); pc.say(); } }
package com.yue.test; 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 Enhancer enhancer = new Enhancer(); /* * 这里的setSuperClass表示创建的代理对象是这个类的子类 * create方法表示使用字节码的方式创建子类对象 */ public Object getProxy(Class clazz){ enhancer.setSuperclass(clazz); enhancer.setCallback(this); return enhancer.create(); } /* * 每个父类方法的调用,都会被这个intercept方法拦截住,并且织入横切逻辑 * 这里的methodProxy对象也是利用java的反射机制去执行父类中的业务方法 * @see net.sf.cglib.proxy.MethodInterceptor#intercept(java.lang.Object, java.lang.reflect.Method, java.lang.Object[], net.sf.cglib.proxy.MethodProxy) */ @Override public Object intercept(Object arg0, Method arg1, Object[] arg2, MethodProxy arg3) throws Throwable { System.out.println("heycglib"); Object obj = arg3.invokeSuper(arg0, arg2); return obj; } }
原文地址:http://blog.csdn.net/carioo/article/details/45114363