代理模式

静态代理

  • 实现 代理类与目标类实现相同的接口
    • 代理类
package com.tmq.designmodeldemo.proxy.staticproxy;

import com.tmq.designmodeldemo.proxy.dynamic.IGamePlayer;

/**
 * 静态代理
 * 和代理对象实现相同的接口
 * @Author tangmqb DCITS
 * @DATE 2020/7/31 16:19
 * @Version 1.0.0
 */
public class GameplayerProxy implements IGamePlayer {

    private IGamePlayer gamePlayer;

    public GameplayerProxy(IGamePlayer gamePlayer) {
        this.gamePlayer = gamePlayer;
    }

    @Override
    public void login(String userName) {
        System.out.println("游戏代理登录了,静态代理开始");
        gamePlayer.login(userName);
    }

    @Override
    public void killBoss() {
        gamePlayer.killBoss();

    }

    @Override
    public void updateGrade() {
        System.out.println("打怪结束,游戏代练完了,收费:$150");
        gamePlayer.updateGrade();
    }
}

静态代理比较简单,不做过多描述

动态代理

  • JDK代理 java动态代理是利用反射机制生成一个实现代理接口的匿名类,在调用具体方法前调用InvokeHandler来处理。

  • Cglib代理 利用asm开源包,对代理对象类的class文件加载进来,通过修改其字节码生成子类来处理

  • jdk代理

package com.tmq.designmodeldemo.proxy.dynamic;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

/**
 * @Author tangmqb DCITS
 * @DATE 2020/7/31 15:52
 * @Version 1.0.0
 */
public class MyInvoketionHandle implements InvocationHandler {

    private Object target ;

    public MyInvoketionHandle(Object target) {
        this.target = target;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("游戏代练...");
        Object invoke = method.invoke(this.target , args);
        return invoke;
    }
}
测试
package com.tmq.designmodeldemo.proxy.dynamic;

import java.lang.reflect.Proxy;

/**
 * @Author tangmqb DCITS
 * @DATE 2020/7/31 15:55
 * @Version 1.0.0
 */
public class ProxyClient1 {

    public static void main(String[] args) {
        GamePlayer gamePlayer = new GamePlayer();
        MyInvoketionHandle handle = new MyInvoketionHandle(gamePlayer);
        //这里只能强转接口类
        IGamePlayer proxy =(IGamePlayer) Proxy.newProxyInstance(gamePlayer.getClass().getClassLoader(), gamePlayer.getClass().getInterfaces(), handle);
        proxy.login("不差钱");
        proxy.killBoss();
        proxy.updateGrade();
    }
}
  • Cglib代理
package com.tmq.designmodeldemo.proxy.dynamic;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

/**
 * @Author tangmqb DCITS
 * @DATE 2020/7/31 15:52
 * @Version 1.0.0
 */
public class MyInvoketionHandle implements InvocationHandler {

    private Object target ;

    public MyInvoketionHandle(Object target) {
        this.target = target;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("游戏代练...");
        Object invoke = method.invoke(this.target , args);
        return invoke;
    }
}
测试
package com.tmq.designmodeldemo.proxy.dynamic;

import java.lang.reflect.Proxy;

/**
 * @Author tangmqb DCITS
 * @DATE 2020/7/31 15:55
 * @Version 1.0.0
 */
public class ProxyClient1 {

    public static void main(String[] args) {
        GamePlayer gamePlayer = new GamePlayer();
        MyInvoketionHandle handle = new MyInvoketionHandle(gamePlayer);
        //这里只能强转接口类
        IGamePlayer proxy =(IGamePlayer) Proxy.newProxyInstance(gamePlayer.getClass().getClassLoader(), gamePlayer.getClass().getInterfaces(), handle);
        proxy.login("不差钱");
        proxy.killBoss();
        proxy.updateGrade();
    }
}

总结

如果目标对象实现了接口,默认情况下会采用JDK的动态代理实现AOP 
如果目标对象实现了接口,可以强制使用CGLIB实现AOP 
如果目标对象没有实现了接口,必须采用CGLIB库,spring会自动在JDK动态代理和CGLIB之间转换
end