动态代理模式——JDK动态代理
今天,我就来讲一下动态代理的设计模式。
动态代理的意义在于生成一个代理对象,来代理真实对象,从而控制真实对象的访问。操作动态代理需要两个步骤:一、代理对象和真实对象建立代理关系。二、实现代理对象的代理逻辑方法。
在Java中,有很多的动态代理技术。如:JDK、CGLIB、Javassist、ASM,其中最常用的动态代理技术有两种:一种是JDK动态代理,这是JDK自带的功能;另一种就是CGLIB,这是第三方提供的一种技术。
这次主要讲的是JDK动态代理和CGLIB动态代理。在JDK动态代理中,我们必须使用接口,而CGLIB就不需要。
JDK 动态代理
JDK 动态代理是 java.lang.reflect.* 包提供的方式,它必须借助一个接口才能产生代理对象,所以我们先定义一个接口。代码如下:
public interface HelloWorld {
public void sayHelloWorld();
}
然后提供实现类来实现此接口。代码如下:
public class HelloWorldImpl implements HelloWorld {
@Override
public void sayHelloWorld() {
System.out.println("Hello World! 动态代理学习篇");
}
}
这是最简单的 Java 接口与实现类的关系。这时我们开始今天学习的内容,JDK动态代理。我们先要建立代理对象和真实服务对象的关系,然后实现代理逻辑。
在 JDK 动态代理中,要实现代理逻辑类必须去实现 java.lang.reflect.InvocationHandler 接口,它里面定义了一个 invoke 方法,并且提供接口数组用于下挂代理对象。代码如下:
public class JdkProxy implements InvocationHandler {
//真实对象
private Object target = null;
/**
* 建立代理对象和真实对象的代理关系,并返回代理对象
* @param obj 真实对象
* @return 代理对象
*/
public Object bind(Object target){
this.target = target;
return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
}
/**
* 代理方法逻辑
* @param proxy 代理对象
* @param method 当前调度方法
* @param args 当前方法的参数
* @return 代理结果返回
* @throws 异常
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("进入代理逻辑方法");
System.out.println("在调度真实对象之前的服务");
//相当于调用 sayHelloWorld 的方法
Object obj = method.invoke(target, args);
System.out.println("在调度真实对象之后的服务");
return obj;
}
}
第1步,建立代理对象和真实对象的关系。这里使用 bind 方法去完成,方法里面首先用类的属性 target 保存了真实对象,然后通过如下代码建立并生成代理对象。
Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
其中 newProxyInstance 方法包含三个参数。
第一个参数为:类加载器。
第二个参数为:把生成的动态代理对象下挂在哪些接口下。
第三个参数为:定义实现方法逻辑的代理类,this 表示当前对象,它必须实现 InvocationHandler 接口方法的 invoke 方法,它就是代理逻辑方法的现实方法。
第2步,实现代理逻辑方法。 invoke 方法可以实现代理逻辑, invoke 方法的三个参数的意义如下:
proxy:代理对象,就是 bind 方法生成的对象。
method:当前调度的方法。
args: 调度方法的参数。
测试一下JDK动态代理方法。代码如下:
public class TestProxy {
public static void main(String[] args) {
JdkProxy jdkTest = new JdkProxy();
HelloWorld proxy = (HelloWorld)jdkTest.bind(new HelloWorldImpl());
proxy.sayHelloWorld();
}
}
测试结果如下:

这就是 JDK 动态代理,它是一种常用的动态代理。
动态代理模式——JDK动态代理的更多相关文章
- 代理模式-jdk动态代理
IDB package com.bjpowernode.proxy; /** * 代理类和目标类都必须使用同一个接口. */ public interface IDB { int insert(); ...
- 静态代理与JDK动态代理
demo地址: https://github.com/ZbLeaning/leaning 代理: 为其他对象提供一种代理以控制对这个对象的访问.分为静态代理和动态代理.代理模式的目的就是为真实业务对象 ...
- Java三种代理模式:静态代理、动态代理和cglib代理
一.代理模式介绍 代理模式是一种设计模式,提供了对目标对象额外的访问方式,即通过代理对象访问目标对象,这样可以在不修改原目标对象的前提下,提供额外的功能操作,扩展目标对象的功能. 简言之,代理模式就是 ...
- 代理模式(静态代理、JDK动态代理原理分析、CGLIB动态代理)
代理模式 代理模式是设计模式之一,为一个对象提供一个替身或者占位符以控制对这个对象的访问,它给目标对象提供一个代理对象,由代理对象控制对目标对象的访问. 那么为什么要使用代理模式呢? 1.隔离,客户端 ...
- 从静态代理,jdk动态代理到cglib动态代理-一文搞懂代理模式
从代理模式到动态代理 代理模式是一种理论上非常简单,但是各种地方的实现往往却非常复杂.本文将从代理模式的基本概念出发,探讨代理模式在java领域的应用与实现.读完本文你将get到以下几点: 为什么需要 ...
- 代理模式之静态代理,JDK动态代理和cglib动态代理
代理模式,顾名思义,就是通过代理去完成某些功能.比如,你需要购买火车票,不想跑那么远到火车站售票窗口买,可以去附近的火车票代售点买,或者到携程等第三方网站买.这个时候,我们就把火车站叫做目标对象或者委 ...
- 代理模式详解:静态代理、JDK动态代理与Cglib动态代理
代理模式简介分类 概念 代理,是为了在不修改目标对象的基础上,增强目标方法的业务逻辑. 客户类需要执行的是目标对象的目标方法,但是真正执行的是代理对象的代理方法,客户类对目标对象的访问是通过代 ...
- Java之代理(jdk静态代理,jdk动态代理,cglib动态代理,aop,aspectj)
一.概念 代理是什么呢?举个例子,一个公司是卖摄像头的,但公司不直接跟用户打交道,而是通过代理商跟用户打交道.如果:公司接口中有一个卖产品的方法,那么公司需要实现这个方法,而代理商也必须实现这个方法. ...
- Java设计模式-代理模式之动态代理(附源代码分析)
Java设计模式-代理模式之动态代理(附源代码分析) 动态代理概念及类图 上一篇中介绍了静态代理,动态代理跟静态代理一个最大的差别就是:动态代理是在执行时刻动态的创建出代理类及其对象. 上篇中的静态代 ...
随机推荐
- 【Luogu P3388】割点模板
Luogu P3388 在一个无向图中,如果有一个顶点集合,删除这个顶点集合以及这个集合中所有顶点相关联的边以后,图的连通分量增多,就称这个点集为割点集合. 如果某个割点集合只含有一个顶点X(也即{X ...
- 23种GoF设计模式的分类
GoF设计模式一共有23个.一般可以按目的和作用范围来进行划分,具体划分方法如下: 第一,这些模式按目的(即完成什么样任务)来划分为创建型.结构型和行为型这三种模式: 创建型:用来创建对象.单例.原型 ...
- 科学使用Log4View2
目录 目录 前言 科学使用 编辑和调试程序集 调试程序集 编辑程序集 结语 推荐文献 目录 NLog日志框架使用探究-1 NLog日志框架使用探究-2 科学使用Log4View2 前言 这个标题很低调 ...
- altium designer 20.0.8
altium designer 20.0.8 download : http://dl3.downloadly.ir/Files/Software/Altium_Designer_20.0.8_Bet ...
- C# partial 关键字分析
简单的来说 partial是局部类型的意思 就是说有这个关键字的类.结构或接口可以写成几个部分 比如 public partial class Program { static void Main(s ...
- 英语口语考试资料College life
College life Early in senior high school, we longed to be enrolled in a university. Now the dream ha ...
- plot()与dev 函数族的使用
1. plot()的类型选择 plot()函数,属于graphics包中. plot(a,b,type="value") type:以什么样的形式来画a,b之间的关系: ·&quo ...
- MQTT版本升级过程及源码解析
MQTT版本升级过程及源码解析 首先说一下为什么要写这篇文章呢,在我发现网上对MQTT的文章介绍实在太少了,可能也是使用这个的频率比较低吧!还有对问题的定位以及解决的方式和办法也太少了,所以特意写这篇 ...
- 怎么解决js中如滑动到最底端一次操作触发多次
定义一个布尔类型到标志,处理中将起设置为true ,处理完改完false,逻辑: data{ isInProcessing:false } //逻辑函数过程中: if(isInProcessing){ ...
- volatile在外设寄存器基地址定义时的作用
volatile,作用就是告诉编译器不要因优化而省略此指令,必须每次都直接读写其值,这样就能确保每次读或者写寄存器都真正执行到位.——野火