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

Posted xueguanfeng

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了03动态代理--JDK动态代理和CGLib动态代理的组合实例相关的知识,希望对你有一定的参考价值。

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动态代理的组合实例的主要内容,如果未能解决你的问题,请参考以下文章

Spring 静态代理+JDK动态代理和CGLIB动态代理

JDK的动态代理与cglib动态代理

动态代理:JDK动态代理和CGLIB代理的区别

动态代理:JDK动态代理和CGLIB代理的区别

jdk动态代理和cglib动态代理的区别

final类又没实现接口应该用哪一种代理, jdk动态代理还是cglib代理