zoukankan      html  css  js  c++  java
  • java动态代理

    java动态代理有2种实现,JdkDynamicAopProxy和Cglib2AopProxy。

    spring的AOP是都用到了这2中实现,jdk动态代理是由java内部的反射机制来实现的,用ProxyGenerator.generateProxyClass(...,...)来生成字节码,cglib动态代理则是生成一个代理类的子类(所以final类是不可以动态代理的),底层则是借助asm来实现的。总的来说,反射机制在生成类的过程中比较高效,而asm在生成类之后的相关执行过程中比较高效(可以通过将asm生成的类进行缓存,这样解决asm生成类过程低效问题)。还有一点必须注意:jdk动态代理的应用前提,必须是目标类基于统一的接口。如果没有上述前提,jdk动态代理不能应用。由此可以看出,jdk动态代理有一定的局限性,cglib这种第三方类库实现的动态代理应用更加广泛,且在效率上更有优势。

    Jdk动态代理 

    原理剖析见: 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());
        }
    }

     Cglib动态代理

    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(); } }
  • 相关阅读:
    框架基础
    Servlet
    JSP数据交互二
    动态网页开发基础
    数据交互
    期末Java Web大作业----简易的学生管理系统
    南阳71----独木舟上的旅行
    南阳1092----数字分隔(二)
    顺序表、链表、栈和队列
    各类排序模版(计数排序、基数排序、桶排序、冒泡排序、选择排序、插入排序、希尔排序、归并排序、原地归并排序、快速排序、堆排序)
  • 原文地址:https://www.cnblogs.com/parkin/p/7617623.html
Copyright © 2011-2022 走看看