首页 > 其他 > 详细

03、动态代理--JDK动态代理和CGLib动态代理的组合实例

时间:2018-05-15 19:09:55      阅读:191      评论:0      收藏:0      [点我收藏+]
package com.offer.note.Java基础.动态代理.CGLib引入增强;

public interface Browser {
    void visitInternet();
}

 

package com.offer.note.Java基础.动态代理.CGLib引入增强;

/**
 * 目标类:被代理类
 *
 * @author: xueguanfeng
 * @date: 2018-05-15 09:57
 */
public class ChromeBrowser implements Browser {
    @Override
    public void visitInternet() {
        System.out.println("visit YouTube");
    }

    //非接口方法
    public void listenToMusic() {
        System.out.println("listen to Cranberries");
    }
}

 

package com.offer.note.Java基础.动态代理.CGLib引入增强;

import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;

/**
 * CGLib引入增强
 *
 * @author: xueguanfeng
 * @date: 2018-05-15 13:08
 */
public class CglibIntroductionBrowserProxy implements MethodInterceptor, Game {

    private static CglibIntroductionBrowserProxy proxy = new CglibIntroductionBrowserProxy();

    private CglibIntroductionBrowserProxy() {

    }

    public static CglibIntroductionBrowserProxy getInstance() {
        return proxy;
    }

    public <T> T getProxy(Class<T> clazz) {
        //第二个入参:指定产生的代理类实现的接口,指定的接口中的方法,需要通过反射来调用,不能通过CGLib来触发调用
        return (T) Enhancer.create(clazz, new Class[]{Game.class}, this);
    }

    @Override
    public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
        Object retVal;
        //判断执行方法是否为指定代理类实现的接口中的方法,如果是,则通过“反射”调用接口的实现类。
        if (method.getDeclaringClass().isInterface()) {
            method.setAccessible(true);
            System.out.println("=================通过反射调用目标方法===================");
            encrypt();
            retVal = method.invoke(this, args);
            decrypt();

            //如果不是,则通过CGLib来触发。
        } else {
            System.out.println("=================CGLib触发目标方法调用===================");
            encrypt();
            retVal = proxy.invokeSuper(obj, args);
            decrypt();
        }
        return retVal;
    }

    @Override
    public void start() {
        System.out.println("start a game");
    }

    ////////////////////////////////增强///////////////////////////////////////

    /**
     * 加密
     */
    private void encrypt() {
        System.out.println("encrypt ...");
    }

    /**
     * 解密
     */
    private void decrypt() {
        System.out.println("decrypt ...");
    }

}

 

package com.offer.note.Java基础.动态代理.CGLib引入增强;

/**
 * 测试类
 *
 * @author: xueguanfeng
 * @date: 2018-05-15 13:10
 */
public class CglibIntroductionDynamicProxyTest {

    public static void main(String[] args) {
        //动态生成的代理类的实例
        ChromeBrowser browser = CglibIntroductionBrowserProxy.getInstance().getProxy(ChromeBrowser.class);
        browser.visitInternet();
        browser.listenToMusic();

        //动态生成的代理类实现了Game接口(return (T) Enhancer.create(clazz, new Class[]{Game.class}, this);)
        Game game = (Game) browser;
        game.start();
    }
}

 

03、动态代理--JDK动态代理和CGLib动态代理的组合实例

原文:https://www.cnblogs.com/xueguanfeng/p/9042377.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!