1. 动态代理


  • 动态代理就是通过代理类是代理类与相关接口不直接发生联系,而在运行期(Runtime)实现动态关联。
  • 动态代理主要用到java.lang.reflect包中的两个类,InvocationHandler接口和Proxy类。
  • 动态代理相较于静态代理最大的不同就是:动态代理的代理类不需要手动生成,该代理类是在运行期间动态生成的,这个动态生成的代理类已经实现代理对象的相关接口(Interface)。在生成代理类的同时,必须提供一个handler,这个handler有InvocationHandler提供,同时用来接管实际的工作。

2. InvocationHandler接口


(1)接口声明:
public interface InvocationHandler
  • 每一个动态代理类都必须实现InvocationHandler接口,InvocationHandler是代理实例(代理的真实对象),的调用处理程序实现的接口,当通过代理实例调用一个方法的时候,该方法的调用就会指派到它调用处理程序(InvocationHandler接口)的 invoke 方法。
(2)invoke方法声明:
Object invoke(Object proxy, Method method, Object[] args) throws Throwable
参数意义:Object proxy: 指代所代理的真实对象,也就是真实对象的代理
Method method: 指代所调用的真实对象的某个方法的Method对象
Object[] args: 指代所代理的真实对象某个方法的参数

3. Proxy类


(1)类声明:
public class Proxy extends Object implements Serializable
  • Proxy 提供用于创建动态代理类和实例的静态方法,它还是由这些方法创建的所有动态代理类的超类(JDK).
  • Proxy类根据已经提供的相关接口和被代理的类就可以利用反射机制得到实现的方法,根据Proxy类的newProxyInstance(...)方法生成代理类。
(2)newProxyInstance方法声明:
public static Object newProxyInstance(ClassLoader loader,
Class<?>[] interfaces,
InvocationHandler h)
throws IllegalArgumentException
参数意义:
ClassLoader loader: 类加载器,就是把动态生成的代理类的字节码文件加载到JVM虚拟机中,一般使用被代理类的类加载器
Class<?>[] interfaces:为代理对象提供的接口,就是被代理类实现的接口
InvocationHandler h: 当代理对象调用方法的时候关联到InvocationHandler对象上,也就是前面说的*调用处理程序*(有待更深理解)

4.动态代理模式实现


package com.manu;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class TestTrendsProxy {
public static void main(String[] args) {
Subject man = new Man();
Proxy p = new Proxy(man);
//通过java.lang.reflect.newProxyInstance(...)方法获得真实对象的代理对象
Subject subject = (Subject)java.lang.reflect.Proxy.newProxyInstance(man.getClass().getClassLoader(), man.getClass().getInterfaces(), p);
//通过代理对象调用真实对象相关接口中实现的方法,这个时候就会跳转到这个代理对象所关联的handler的invoke()方法去执行
subject.shopping();
//获得真实对象的代理对象所对应的Class对象的名称,用字符串表示
System.out.println(subject.getClass().getName());
//调用处理程序的表示
InvocationHandler handler = java.lang.reflect.Proxy.getInvocationHandler(subject);
System.out.println(handler);
}
}
//被代理人和代理人要执行的动作
interface Subject{
void shopping();
}
//被代理类
class Man implements Subject{
private String name="Tom";
public void shopping() {
System.out.println(name+"要去买东西...");
}
}
//代理类
class Proxy implements InvocationHandler{
private Object target;//要代理的真实对象
public Proxy(Subject target){
this.target = target;
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("proxy:"+proxy.getClass().getName());
System.out.println("购买之前的评估工作...");
method.invoke(target, args);
System.out.println("购买之后的满意度调查...");
return null;
}
}

下面是运行结果:

运行结果:
proxy:com.manu.$Proxy0
购买之前的评估工作...
Tom要去买东西...
购买之后的满意度调查...
com.manu.$Proxy0
com.manu.Proxy@6bc7c054

运行结果中出现的$Proxy0是subject.getClass().getName())得到的,返回的是类的名称,这是在运行时动态创建的,命名方式貌似是$Proxy+编号构成。整个代理过程主要体现在一个handler上。

如果选择关注微信公众号:jzman-blog,一起交流学习!


关于java动态代理模式的更多相关文章

  1. JAVA动态代理模式(从现实生活角度理解代码原理)

    所谓动态代理,即通过代理类:Proxy的代理,接口和实现类之间可以不直接发生联系,而可以在运行期(Runtime)实现动态关联. java动态代理主要是使用java.lang.reflect包中的两个 ...

  2. java动态代理模式

    java动态代理机制详解 Spring的核心AOP的原理就是java的动态代理机制. 在java的动态代理机制中,有两个重要的类或接口: 1.InvocationHandler(Interface): ...

  3. Java动态代理模式浅析

    Java代理设计模式 - 静态代理 Java中的动态代理 - 调用处理器 代理设计模式的UML图: 我将首先介绍Java中的各种代理实现方法 Java代理设计模式 - 静态代理 这个例子非常简单,只有 ...

  4. java 动态代理模式(jdk和cglib)

    package proxy.dynamicproxy; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Met ...

  5. Java 动态代理模式浅析

    目录 Java代理设计模式 - 静态代理 静态代理的优点 静态代理的缺点 Java中的动态代理 - 调用处理器 主要笔记: 动态代理类的限制 代理设计模式的UML图: 我将首先介绍Java中的各种代理 ...

  6. JAVA代理模式与动态代理模式

    1.代理模式 所谓代理,就是一个人或者一个机构代表另一个人或者另一个机构采取行动.在一些情况下,一个客户不想或者不能够直接引用一个对象,而代理对象可以在客户端和目标对象之前起到中介的作用.代理模式给某 ...

  7. Java设计模式系列之动态代理模式(转载)

    代理设计模式 定义:为其他对象提供一种代理以控制对这个对象的访问. 动态代理使用 java动态代理机制以巧妙的方式实现了代理模式的设计理念. 代理模式示例代码 public interface Sub ...

  8. Java静态代理与动态代理模式的实现

    前言:    在现实生活中,考虑以下的场景:小王打算要去租房,他相中了一个房子,准备去找房东洽谈相关事宜.但是房东他很忙,平时上班没时间,总找不到时间去找他,他也没办法.后来,房东想了一个办法,他找到 ...

  9. java jdk动态代理模式举例浅析

    代理模式概述 代理模式是为了提供额外或不同的操作,而插入的用来替代”实际”对象的对象,这些操作涉及到与”实际”对象的通信,因此代理通常充当中间人角色. java中常用的动态代理模式为jdk动态代理和c ...

随机推荐

  1. VueX状态管理器 的应用

    VueX状态管理器 cnpm i vuex axios -S 1 创建Vuex 仓库 import Vue from 'vue' import Vuex from 'vuex' vue.use(Vue ...

  2. Python-Pyquery库的安装和调用

    解析库pyquery:# pip安装pyquery库pip3 install pyquery from pyquery import PyQuery as pq # 定义doc,输入html源代码 d ...

  3. 处理公共CDN突然失效的情况

    公共CDN的使用 刚开始开发我的博客时,使用的bootcdn,发现他们被黑过,虽然想骂那些“黑客”,但是我们也没办法去防范,只能从自己的网站上入手解决. 那时我还没技术解决这个问题,网上搜过,大都只提 ...

  4. vs远程调试iis

    1.在开发电脑上 找到 D:\Software\VS2010\Common7\IDE\Remote Debugger 下面msvsmon.exe所在的两个文件夹x86和x64,使用x86或者x64是根 ...

  5. Community Cloud零基础学习(四)Builder创建自定义的布局

    前几篇讲了Community Cloud权限配置等信息,但是没有太讲过 Community如何进行配置layout,本篇主要描述使用Builder去进行符合需求的Community Layout的构建 ...

  6. VOIP RTP RTSP 实现 Baresip 源码分析

    RTP 使用 udp 进行数据传输,udp 是不能保证,数据包一定可以到达的,也不提供时序.同时还有 MTU 限制. RTCP 用来配合 RTP 提供,传输报告,会话建立和退出. 一大批参考规范 * ...

  7. 【小程序】---- input获得焦点时placeholder重影BUG

    问题小程序的input组件有个自身的bug,即当输入框获取焦点时placeholder内容会出现重影现象. 解决思路原理:将placeholder内容单独写在另外的标签里,控制其显示隐藏.操作:将代表 ...

  8. C++ 删除字符串中的数字并重新按顺序排列

    #include <stdio.h> #include <string.h> char* Find_str(char* p) { ; i < strlen(p); i++ ...

  9. 事务的隔离级别,mysql中开启事务、django中开启事务

    目录 一.事务的特性 二.数据库中开启事务 三.Django中开启事务的两种方式 第一种 第二种 四.事务的隔离级别 隔离级别 如何查看mysql隔离级别? 修改事务的隔离级别 隔离级别解释 read ...

  10. java 知识点总结(转)

    转载自 https://www.cnblogs.com/wl310538259/p/5218251.html (一)Java 1.接口和抽象类的区别 ①抽象类里可以有构造方法,而接口内不能有构造方法. ...