码迷,mamicode.com
首页 > 编程语言 > 详细

java-动态代理

时间:2017-10-01 23:51:26      阅读:387      评论:0      收藏:0      [点我收藏+]

标签: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这种第三方类库实现的动态代理应用更加广泛,且在效率上更有优势。

 

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(); } }

 

java-动态代理

标签:static   callback   override   back   logs   子类   oid   ring   created   

原文地址:http://www.cnblogs.com/parkin/p/7617623.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!