结构型模式----代理模式

  使用一个简单场景来描述代理模式:

  1. 顾客买阿迪达斯鞋,不找原厂商买,找二道贩子买,二道贩子就是一个代理

  2. 代理不会改变最终顾客到手的东西--鞋

  3. 二道贩子也不会按照鞋的拿货价卖给你,他屏蔽了鞋的原始价钱信息,按照自己定的价卖给你

 

  直接上代码,代码中实现了三种代理方式:①静态 ②jdk动态 ③cglib

  其中 cglib 的方式需要引入pom依赖如下:

<dependency>
    <groupId>cglib</groupId>
    <artifactId>cglib</artifactId>
    <version>3.3.0</version>
</dependency>

  代码如下, 都写在一个类里方便观看:

package com.haopan.proxy;

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

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

public class ProxyTest {
    public static void main(String[] args) {
        System.out.println("静态代理:");
        System.out.println("静态代理: 客户端向代理买鞋, 花费: " + AdidasFactoryProxy.getInstance().getStaticProxyCost() + "$");
        System.out.println();
        System.out.println("动态代理:");
        System.out.println("JDK动态代理: 客户端向代理买鞋, 花费: " + AdidasFactoryProxy.getInstance().getJdkProxyCost() + "$");
        System.out.println();
        System.out.println("CgLib代理:");
        System.out.println("CGLib代理: 客户端向代理买鞋, 花费: " + AdidasFactoryProxy.getInstance().getCgLibProxyCost() + "$");
    }
}

/**
 * 阿迪达斯工厂接口
 */
interface IAdidasFactory {
    /**
     * 获取一双鞋子的价钱
     */
    int cost();
}

/**
 * 阿迪达斯工厂实现
 */
class AdidasFactory implements IAdidasFactory {
    @Override
    public int cost() {
        System.out.println("我是厂商, 这双鞋子1000$.");
        return 1000;
    }
}

/**
 * 阿迪达斯工厂的代理商
 */
class AdidasFactoryProxy {

    // 本段代码使用了<饿汉式单例模式> start
    private static final AdidasFactoryProxy INSTANCE = new AdidasFactoryProxy();
    private AdidasFactoryProxy() {
    }
    public static AdidasFactoryProxy getInstance() {
        return AdidasFactoryProxy.INSTANCE;
    }
    // 本段代码使用了<饿汉式单例模式> end

    /**
     * 静态代理: 编译时代码已经生成
     * @return
     */
    public int getStaticProxyCost() {
        final IAdidasFactory target = new AdidasFactory();
        System.out.println("静态代理介入------前");
        int returnValue = target.cost();
        System.out.println("静态代理介入------后, 我要加价100$块钱卖出去.");
        return returnValue + 100;
    }

    /**
     * 动态代理: 运行时通过接口反射出类实例调用方法
     * @return
     */
    public int getJdkProxyCost() {
        final IAdidasFactory target = new AdidasFactory();
        IAdidasFactory target2 = (IAdidasFactory) Proxy.newProxyInstance(
                target.getClass().getClassLoader(),
                target.getClass().getInterfaces(),
                (proxy, method, args) -> {
                    System.out.println("动态代理介入------前");
                    Object returnValue = method.invoke(target, args);
                    System.out.println("动态代理介入------后, 我要加价100$块钱卖出去.");
                    return (int) returnValue + 100;
                });
        return target2.cost();
    }

    /**
     * CGLib代理: 运行时通过创建增强子类来调用方法
     * @return
     */
    public int getCgLibProxyCost() {
        IAdidasFactory target = new AdidasFactory();
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(target.getClass());
        enhancer.setCallback(new MethodInterceptor() {
            @Override
            public Object intercept(Object object, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
                System.out.println("CgLib代理介入------前");
                // invokeSuper: 使用回调函数中的object参数,
                // Object returnValue = methodProxy.invokeSuper(object, objects);
                // invoke: 使用加强对象本身 target
                Object returnValue = methodProxy.invoke(target, objects);
                System.out.println("CgLib代理介入------后, 我要加价100$块钱卖出去.");
                return (int) returnValue + 100;
            }
        });
        IAdidasFactory enhancerProxy = (IAdidasFactory) enhancer.create();
        return enhancerProxy.cost();
    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值