Java代理设计模式(Proxy)的几种具体实现
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)的几种具体实现的更多相关文章
- Java代理设计模式(Proxy)的四种具体实现:静态代理和动态代理
面试问题:Java里的代理设计模式(Proxy Design Pattern)一共有几种实现方式?这个题目很像孔乙己问"茴香豆的茴字有哪几种写法?" 所谓代理模式,是指客户端(Cl ...
- 巧用代理设计模式(Proxy Design Pattern)改善前端图片加载体验
这篇文章介绍一种使用代理设计模式(Proxy Design Pattern)的方法来改善您的前端应用里图片加载的体验. 假设我们的应用里需要显示一张尺寸很大的图片,位于远端服务器.我们用一些前端框架的 ...
- java 代理设计模式
首先代理(deleration)是什么,在日常生活中我们有很多这种的例子,比如你上个QQ,各种空间被什么代理刷屏,对的,代理不是生产产品的商家,也不是进购产品的卖家,他们只是帮别人卖东西,这就相当于一 ...
- Java代理类Proxy的用法
代理(proxy) 利用代理可以在运行时创建一个实现了一组给定接口的新类.这种功能只有在编译时无法确定需要实现哪个接口时才有必要使用. 何时使用代理 假设有一个表示接口的Class对象(有可能只包含一 ...
- java 代理的三种实现方式
Java 代理模式有如下几种实现方式: 1.静态代理. 2.JDK动态代理. 3.CGLIB动态代理. 示例,有一个打招呼的接口.分别有两个实现,说hello,和握手.代码如下. 接口: public ...
- Java基础-设计模式之-代理模式Proxy
代理模式是对象的结构模式.代理模式给某一个对象提供一个代理对象,并由代理对象控制对原对象的引用. 代理模式是常用的Java 设计模式,它的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理 ...
- Java设计模式—Proxy动态代理模式
代理:设计模式 代理是一种常用的设计模式,其目的就是为其他对象提供一个代理以控制对某个对象的访问.代理类负责为委托类预处理消息,过滤消息并转发消息,以及进行消息被委托类执行后的后续处理. 图 1. 代 ...
- Java的三种代理模式(Proxy,CGLib)
1.静态代理,这种不用说最不靠谱.每个类一个代理,代码量很大. 2.JDK代理.使用java.lang.reflect.Proxy进行代理,但是被代理的类必须要实现接口. 3.Cglib代理.不用实现 ...
- 《JAVA设计模式》之代理模式(Proxy)
在阎宏博士的<JAVA与模式>一书中开头是这样描述代理(Proxy)模式的: 代理模式是对象的结构模式.代理模式给某一个对象提供一个代理对象,并由代理对象控制对原对象的引用. 代理模式的结 ...
随机推荐
- spring aop 解决模糊查询参数 % - /等特殊符号问题
import com.hsq.common.utils.StringUtil;import org.aspectj.lang.ProceedingJoinPoint;import org.aspect ...
- Spring Cloud 相关资料链接
Spring Cloud中文网:https://springcloud.cc/ Spring Cloud API:https://springcloud.cc/spring-cloud-dalston ...
- Hadoop单机、伪分布式、分布式集群搭建
JDK安装 设置hostname [root@bigdata111 ~]# vi /etc/hostname 设置机器hosts [root@bigdata111 ~]# vi /etc/hosts ...
- SpringBoot:Web开发
西部开源-秦疆老师:基于SpringBoot 2.1.6 的博客教程 , 基于atguigu 1.5.x 视频优化 秦老师交流Q群号: 664386224 未授权禁止转载!编辑不易 , 转发请注明出处 ...
- 消息中间件-activemq安全机制
activemq作为消息中间件这样一个独立的个体存在,连通用户和服务器.如果没有一套完备的安全机制去设置用户权限设置消息分发机制可想后果是非常严重.ActiveMQ如果不加入安全机制的话,任何人只要知 ...
- Netty学习(九)-Netty编解码技术之Marshalling
前面我们讲过protobuf的使用,主流的编解码框架其实还有很多种: ①JBoss的Marshalling包 ②google的Protobuf ③基于Protobuf的Kyro ④Apache的Thr ...
- Ubuntu 18.04 LTS版本 GoldenDict安装与配置
为何安装? GoldenDict是一款Linux下很好用的词典软件,其具有的关于词典的裁剪功能使得用户能够方便地对各种词典进行添加或删除,其具有的屏幕取词功能能够帮助用户方便地进行翻译,其具有的网络源 ...
- html学习笔记整理
网页 1.网页的组成部分 网页是由文字,图片,视频,音频,输入框,按钮这些元素(也就是html标签)组成. 2.浏览网页常用的五大主流浏览器 谷歌,IE,火狐,欧朋,safari.浏览器的内核(渲染引 ...
- 时间格式的字符串在ios中的转换问题
在移动端使用时间选择器的时候,选择了一个时间转换为时间戳,谷歌浏览器以及安卓手机使用 new Date( 选择的时间 ).getTime() 都能够拿到时间戳, 但是在ios手机上会出现出现NAN ...
- cmd命令行带参启动程序
cmd命令行带参启动程序 有一些程序不支持被直接启动,编写代码时,我们可以通过Process类来启动某个进程(某个软件),在不用代码调从而启动某个软件时,windows系统下,通常我们会用到cmd命令 ...