Proxy是一种结构设计模型,主要解决对象直接访问带来的问题,代理又分为静态代理和动态代理(JDK代理、CGLIB代理。

静态代理:又程序创建的代理类,或者特定的工具类,在平时开发中经常用到这种代理模式,这种一般在程序运行前就已经生成对应的class文件;

动态代理:在程序运行时通过反射机制动态创建。

下面通过一个场景实现以下三种代理方式

  • 步骤一:定义商店接口(Subject)
  • 步骤二:个人店家运营(RealSubject)
  • 步骤三:平台运营(proxy)
  • 步骤四:个体消费(client)

几种代理方式都会用到Subject、RealSubject,现在这里定义

Store.java(Subject):定义两个接口operate(运营),business(交易)。

public interface Store {
/**
* 店铺运营
*/
public void operate(); /**
* 店铺交易
*/
public void business();
}

PersonStore.java(RealSubject) 单个用户运营

public class PersonStore implements Store {
@Override
public void operate() {
System.out.println("个人商店运营");
} @Override
public void business() {
System.out.println("个人商店交易");
}
}

静态代理

静态代理的实现比较简单,代理类通过实现与目标对象相同的接口,并在类中维护一个代理对象,这种场景用于个体商家比较少的情况,如果多的话代理类十分繁多、不易维护

创建静态代理类

ProxyStroe.java(proxy):在代理平台运营是收取管理费用100,这个代理类需要实现Store接口,并制定目标类target(PersonStore)。

public class ProxyStroe implements Store{

    private Store personStore = new PersonStore();

    @Override
public void operate() {
System.out.println("收取管理费用100元");
personStore.operate();
} @Override
public void business() {
personStore.business();
}
}

静态代理调用

StaticConsumer.java(client):通过创建ProxyStroe去代理PersonStore,并进行操作。

public class StaticConsumer {

    public static void main(String[] args) {
ProxyStroe store = new ProxyStroe();
store.operate();
store.business();
}
}

动态代理

JDK代理

动态代理类是通过接口实现的,利用拦截器(拦截器必须实现InvocationHanlder)加上反射机制生成一个实现代理接口的匿名类,

在调用具体方法前调用InvokeHandler来处理。

创建jdk代理类

JDKStoreHandler.java(proxy):通过实现InvocationHandler接口的invoke方法,在里面进行反射调用,newProxyInstanse通过目标对象创建真是对象。

public class JDKStoreHandler implements InvocationHandler {

    /**
* 目标对象
*/
private Object targetObject; @Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if("operate".equals(method.getName())){
System.out.println("收取管理费用100元");
}
return method.invoke(targetObject, args);
} /**
*
* @param targetObject
* @return
*/
public Object newProxyInstanse(Object targetObject){
this.targetObject = targetObject;
return Proxy.newProxyInstance(targetObject.getClass().getClassLoader(),targetObject.getClass().getInterfaces(),this);
}
}

JDK代理对象调用

JDKDynamicConsumer.java(proxy):通过JDKStoreHandler的newProxyInstanse创建真实目标对象,并调用接口的方法

public class JDKDynamicConsumer {

    public static void main(String[] args) {
Store store = (Store)new JDKStoreHandler().newProxyInstanse(new PersonStore());
store.operate();
store.business();
}
}

CGLIB代理

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

创建cglib代理对象

CglibProxy.java(proxy):需要实现MethodInterceptor的intercept方法,并进行反射调用。通过createProxyObject创建真实对象,这里是根据目标对象直接生成对象。

public class CglibProxy implements MethodInterceptor{

    /**
* CGlib需要代理的目标对象
*/
private Object targetObject; public Object createProxyObject(Object targetObject){
this.targetObject = targetObject;
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(targetObject.getClass());
enhancer.setCallback(this);
Object proxyObj = enhancer.create();
return proxyObj;
} @Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
if("operate".equals(method.getName())){
System.out.println("收取管理费用100元");
}
return method.invoke(targetObject, objects);
}
}

CGLib代理对象调用

CglibDynamicConsumer.java(client):通过CglibProxy的createProxyObject创建真实目标对象,对进行方法调用

public class CglibDynamicConsumer {

    public static void main(String[] args) {
Store store = (Store)new CglibProxy().createProxyObject(new PersonStore());
store.operate();
store.business();
}
}

源码已上传:https://github.com/itrickzhang/proxy-demo

Java代理设计模式(Proxy)的几种具体实现的更多相关文章

  1. Java代理设计模式(Proxy)的四种具体实现:静态代理和动态代理

    面试问题:Java里的代理设计模式(Proxy Design Pattern)一共有几种实现方式?这个题目很像孔乙己问"茴香豆的茴字有哪几种写法?" 所谓代理模式,是指客户端(Cl ...

  2. 巧用代理设计模式(Proxy Design Pattern)改善前端图片加载体验

    这篇文章介绍一种使用代理设计模式(Proxy Design Pattern)的方法来改善您的前端应用里图片加载的体验. 假设我们的应用里需要显示一张尺寸很大的图片,位于远端服务器.我们用一些前端框架的 ...

  3. java 代理设计模式

    首先代理(deleration)是什么,在日常生活中我们有很多这种的例子,比如你上个QQ,各种空间被什么代理刷屏,对的,代理不是生产产品的商家,也不是进购产品的卖家,他们只是帮别人卖东西,这就相当于一 ...

  4. Java代理类Proxy的用法

    代理(proxy) 利用代理可以在运行时创建一个实现了一组给定接口的新类.这种功能只有在编译时无法确定需要实现哪个接口时才有必要使用. 何时使用代理 假设有一个表示接口的Class对象(有可能只包含一 ...

  5. java 代理的三种实现方式

    Java 代理模式有如下几种实现方式: 1.静态代理. 2.JDK动态代理. 3.CGLIB动态代理. 示例,有一个打招呼的接口.分别有两个实现,说hello,和握手.代码如下. 接口: public ...

  6. Java基础-设计模式之-代理模式Proxy

    代理模式是对象的结构模式.代理模式给某一个对象提供一个代理对象,并由代理对象控制对原对象的引用. 代理模式是常用的Java 设计模式,它的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理 ...

  7. Java设计模式—Proxy动态代理模式

    代理:设计模式 代理是一种常用的设计模式,其目的就是为其他对象提供一个代理以控制对某个对象的访问.代理类负责为委托类预处理消息,过滤消息并转发消息,以及进行消息被委托类执行后的后续处理. 图 1. 代 ...

  8. Java的三种代理模式(Proxy,CGLib)

    1.静态代理,这种不用说最不靠谱.每个类一个代理,代码量很大. 2.JDK代理.使用java.lang.reflect.Proxy进行代理,但是被代理的类必须要实现接口. 3.Cglib代理.不用实现 ...

  9. 《JAVA设计模式》之代理模式(Proxy)

    在阎宏博士的<JAVA与模式>一书中开头是这样描述代理(Proxy)模式的: 代理模式是对象的结构模式.代理模式给某一个对象提供一个代理对象,并由代理对象控制对原对象的引用. 代理模式的结 ...

随机推荐

  1. (通俗易懂小白入门)网络流最大流——EK算法

    网络流 网络流是模仿水流解决生活中类似问题的一种方法策略,来看这么一个问题,有一个自来水厂S,它要向目标T提供水量,从S出发有不确定数量和方向的水管,它可能直接到达T或者经过更多的节点的中转,目前确定 ...

  2. 关于asp.net调用gemalto超级狗api的具体实现

    鉴于网上关于超级狗的具体操作并不详细,我把我所知道的写下来,希望能给有需求的网友做个参考.软件外壳保护我就不说了,没有什么难度,供应商也会提供文档,一步一步操作即可.我要说的是用于保护发给客户的程序, ...

  3. Java泛型使用的简单介绍

    目录 一. 泛型是什么 二. 使用泛型有什么好处 三. 泛型类 四. 泛型接口 五. 泛型方法 六. 限定类型变量 七. 泛型通配符 7.1 上界通配符 7.2 下界通配符 7.3 无限定通配符 八. ...

  4. aes秘钥限制问题解决办法

    在oarcle jdk1.8上执行256位的aes秘钥加密报错如下: java.lang.RuntimeException: java.security.InvalidKeyException: Il ...

  5. Spring1

    一.Spring是什么?有什么用? Spring的适用环境是这样的,假设现在有一个类port,它将提供一个返回消息的功能,代码如下: public class port { private weibo ...

  6. 从零开始实现ASP.NET Core MVC的插件式开发(四) - 插件安装

    标题:从零开始实现ASP.NET Core MVC的插件式开发(四) - 插件安装 作者:Lamond Lu 地址:https://www.cnblogs.com/lwqlun/p/11260750. ...

  7. 《机器学习技法》---AdaBoost算法

    1 AdaBoost的推导 首先,直接给出AdaBoost算法的核心思想是:在原数据集上经过取样,来生成不同的弱分类器,最终再把这些弱分类器聚合起来. 关键问题有如下几个: (1)取样怎样用数学方式表 ...

  8. 100天搞定机器学习|day37 无公式理解反向传播算法之精髓

     100天搞定机器学习(Day1-34) 100天搞定机器学习|Day35 深度学习之神经网络的结构 100天搞定机器学习|Day36 深度学习之梯度下降算法 本篇为100天搞定机器学习之第37天,亦 ...

  9. 消息中间件——RabbitMQ(三)理解RabbitMQ核心概念和AMQP协议!

    前言 本章学习,我们可以了解到以下知识点: 互联网大厂为什么选择RabbitMQ? RabbiMQ的高性能之道是如何做到的? 什么是AMQP高级协议? AMQP核心概念是什么? RabbitMQ整体架 ...

  10. 使用 Docker 部署 Spring Boot

    Docker 技术发展为微服务落地提供了更加便利的环境,使用 Docker 部署 Spring Boot 其实非常简单,这篇文章我们就来简单学习下. 首先构建一个简单的 Spring Boot 项目, ...