03、动态代理--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();
    }
}

 

posted @ 2018-05-15 18:18  windjammer  阅读(364)  评论(0编辑  收藏  举报