标签:static callback override back logs 子类 oid ring created
java动态代理有2种实现,JdkDynamicAopProxy和Cglib2AopProxy。
spring的AOP是都用到了这2中实现,jdk动态代理是由java内部的反射机制来实现的,用ProxyGenerator.generateProxyClass(...,...)来生成字节码,cglib动态代理则是生成一个代理类的子类(所以final类是不可以动态代理的),底层则是借助asm来实现的。总的来说,反射机制在生成类的过程中比较高效,而asm在生成类之后的相关执行过程中比较高效(可以通过将asm生成的类进行缓存,这样解决asm生成类过程低效问题)。还有一点必须注意:jdk动态代理的应用前提,必须是目标类基于统一的接口。如果没有上述前提,jdk动态代理不能应用。由此可以看出,jdk动态代理有一定的局限性,cglib这种第三方类库实现的动态代理应用更加广泛,且在效率上更有优势。
原理剖析见: http://www.cnblogs.com/MOBIN/p/5597215.html
package com.amigo.study.DynamicProxyDemo; /** * Created by moi on 2017/10/1. */ public interface IDbService { public String getDBName(); }
package com.amigo.study.DynamicProxyDemo; /** * Created by moi on 2017/10/1. */ public class DBServiceImpl implements IDbService { @Override public String getDBName() { System.out.println("db name is amigo."); return "amigo"; } }
package com.amigo.study.DynamicProxyDemo; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; /** * Created by moi on 2017/10/1. */ public class DBServiceInvokeHandler implements InvocationHandler { private Object target; DBServiceInvokeHandler() { super(); } DBServiceInvokeHandler(Object target) { super(); this.target = target; }
/**
* 动态代理的目的往往是要增强被代理类,这里就是增强逻辑的放置位置。
* @param proxy
* @param method
* @param args
* @return
* @throws Throwable
*/
@Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { if ("getDBName".equals(method.getName())) { System.out.println("++++++before " + method.getName() + "++++++"); Object result = method.invoke(target, args); System.out.println("++++++after " + method.getName() + "++++++"); return result; } else { Object result = method.invoke(target, args); return result; } } }
package com.amigo.study.DynamicProxyDemo; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Proxy; /** * Created by moi on 2017/10/1. */ public class DynamicProxyTest { public static void main(String[] args) { // 这里是保存下来生成的.class文件。 注意:要在工程根目录新建/com/sun/proxy的目录,要不会报错。 System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles", "true"); JDKDynamicProxyTest(); } public static void JDKDynamicProxyTest() { IDbService iDbService = new DBServiceImpl(); InvocationHandler invocationHandler = new DBServiceInvokeHandler(iDbService); IDbService userServiceProxy = (IDbService) Proxy.newProxyInstance(iDbService.getClass().getClassLoader(), iDbService.getClass().getInterfaces(), invocationHandler); System.out.println(userServiceProxy.getDBName()); } }
package com.amigo.study.DynamicProxyDemo; import net.sf.cglib.proxy.MethodInterceptor; import net.sf.cglib.proxy.MethodProxy; import java.lang.reflect.Method; /** * Created by moi on 2017/10/1. */ public class DBServiceMethodInterceptor implements MethodInterceptor { @Override public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable { System.out.println("Before:" + method); Object object = methodProxy.invokeSuper(o, objects); System.out.println("After:" + method); return object; } }
package com.amigo.study.DynamicProxyDemo; import net.sf.cglib.proxy.Enhancer; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Proxy; /** * Created by moi on 2017/10/1. */ public class DynamicProxyTest { public static void main(String[] args) { // JDKDynamicProxyTest(); CglibDynamicProxyTest(); } public static void JDKDynamicProxyTest() { IDbService iDbService = new DBServiceImpl(); InvocationHandler invocationHandler = new DBServiceInvokeHandler(iDbService); IDbService userServiceProxy = (IDbService) Proxy.newProxyInstance(iDbService.getClass().getClassLoader(), iDbService.getClass().getInterfaces(), invocationHandler); System.out.println(userServiceProxy.getDBName()); } public static void CglibDynamicProxyTest(){ Enhancer enhancer = new Enhancer();
// 设置被代理类 enhancer.setSuperclass(DBServiceImpl.class);
// 回调函数用于增强被代理类 enhancer.setCallback(new DBServiceMethodInterceptor()); DBServiceImpl dbService = (DBServiceImpl)enhancer.create(); dbService.getDBName(); } }
标签:static callback override back logs 子类 oid ring created
原文地址:http://www.cnblogs.com/parkin/p/7617623.html