設計模式【二】代理模式

1. 靜態代理

/**
 * @authod: pp_lan on 2020/3/20.
 */
public class StaticProxy {
    interface Car {
        void drive();
    }

    static class Benz implements Car {
        @Override
        public void drive() {
            System.out.println("benz driving");
        }
    }

    static class ProxyManager implements Car {

        private Car car;

        public ProxyManager(Car car) {
            this.car = car;
        }

        @Override
        public void drive() {
            System.out.println("【代理】準備工作");
            car.drive();
            System.out.println("【代理】結束工作");
        }
    }

    public static void main(String[] args) {
        ProxyManager proxy = new ProxyManager(new Benz());
        proxy.drive();
    }
}

2. JDK動態代理

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

/**
 * @authod: pp_lan on 2020/3/20.
 * jdk動態代理
 */
public class JdkProxy implements InvocationHandler {
    private Object target;

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

    public Object getProxy() {
        Object proxy = Proxy.newProxyInstance(this.target.getClass().getClassLoader(), this.target.getClass().getInterfaces(), this);
        return proxy;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("【JDK代理】準備開始");
        Object invoke = method.invoke(target, args);
        System.out.println("【JDK代理】執行結束");
        return invoke;
    }

    public static void main(String[] args) {
        Car proxy = (Car)new JdkProxy(new Benz()).getProxy();
        proxy.drive();
    }

    interface Car {
        void drive();
    }

    static class Benz implements Car {
        @Override
        public void drive() {
            System.out.println("Benz driving");
        }
    }
}

3. Cglib動態代理

       <!-- cglib -->
       <dependency>
            <groupId>cglib</groupId>
            <artifactId>cglib</artifactId>
            <version>3.2.4</version>
        </dependency>
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;

/**
 * @authod: pp_lan on 2020/3/20.
 */
public class CglibProxy<T> {

    private Enhancer enhancer;

    public CglibProxy(Class<T> clazz) {
        this.enhancer = new Enhancer();
        this.enhancer.setSuperclass(clazz);
        this.enhancer.setCallback(new MethodInterceptor() {
            @Override
            public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
                System.out.println("【cglib代理】開始");
                Object t = methodProxy.invokeSuper(o, objects);
                System.out.println("【cglib代理】結束");
                return t;
            }
        });
    }

    public T getProxy () {
        return (T)this.enhancer.create();
    }

    public static void main(String[] args) {
        CglibProxy<Benz> cglib = new CglibProxy<>(Benz.class);
        Benz proxy = cglib.getProxy();
        proxy.drive();
    }


    static class Benz{
        public void drive() {
            System.out.println("Benz driving");
        }
    }
}

4. 優缺點

1. 靜態代理:維護麻煩,每個代理都需要單獨設置;

2. JDK代理:代理方法需要有接口,並且由於使用反射,效率相對較低

3. CGLIB代理:使用asm生成對象,被代理對象需要有可訪問的無參構造方法,效率相對較高。相關報錯:https://blog.csdn.net/pp_lan/article/details/84991460

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章