今天,我就来讲一下动态代理的设计模式。

  动态代理的意义在于生成一个代理对象,来代理真实对象,从而控制真实对象的访问。操作动态代理需要两个步骤:一、代理对象和真实对象建立代理关系。二、实现代理对象的代理逻辑方法。

  在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动态代理的更多相关文章

  1. 代理模式-jdk动态代理

    IDB package com.bjpowernode.proxy; /** * 代理类和目标类都必须使用同一个接口. */ public interface IDB { int insert(); ...

  2. 静态代理与JDK动态代理

    demo地址: https://github.com/ZbLeaning/leaning 代理: 为其他对象提供一种代理以控制对这个对象的访问.分为静态代理和动态代理.代理模式的目的就是为真实业务对象 ...

  3. Java三种代理模式:静态代理、动态代理和cglib代理

    一.代理模式介绍 代理模式是一种设计模式,提供了对目标对象额外的访问方式,即通过代理对象访问目标对象,这样可以在不修改原目标对象的前提下,提供额外的功能操作,扩展目标对象的功能. 简言之,代理模式就是 ...

  4. 代理模式(静态代理、JDK动态代理原理分析、CGLIB动态代理)

    代理模式 代理模式是设计模式之一,为一个对象提供一个替身或者占位符以控制对这个对象的访问,它给目标对象提供一个代理对象,由代理对象控制对目标对象的访问. 那么为什么要使用代理模式呢? 1.隔离,客户端 ...

  5. 从静态代理,jdk动态代理到cglib动态代理-一文搞懂代理模式

    从代理模式到动态代理 代理模式是一种理论上非常简单,但是各种地方的实现往往却非常复杂.本文将从代理模式的基本概念出发,探讨代理模式在java领域的应用与实现.读完本文你将get到以下几点: 为什么需要 ...

  6. 代理模式之静态代理,JDK动态代理和cglib动态代理

    代理模式,顾名思义,就是通过代理去完成某些功能.比如,你需要购买火车票,不想跑那么远到火车站售票窗口买,可以去附近的火车票代售点买,或者到携程等第三方网站买.这个时候,我们就把火车站叫做目标对象或者委 ...

  7. 代理模式详解:静态代理、JDK动态代理与Cglib动态代理

    代理模式简介分类 概念 ​ 代理,是为了在不修改目标对象的基础上,增强目标方法的业务逻辑. ​ 客户类需要执行的是目标对象的目标方法,但是真正执行的是代理对象的代理方法,客户类对目标对象的访问是通过代 ...

  8. Java之代理(jdk静态代理,jdk动态代理,cglib动态代理,aop,aspectj)

    一.概念 代理是什么呢?举个例子,一个公司是卖摄像头的,但公司不直接跟用户打交道,而是通过代理商跟用户打交道.如果:公司接口中有一个卖产品的方法,那么公司需要实现这个方法,而代理商也必须实现这个方法. ...

  9. Java设计模式-代理模式之动态代理(附源代码分析)

    Java设计模式-代理模式之动态代理(附源代码分析) 动态代理概念及类图 上一篇中介绍了静态代理,动态代理跟静态代理一个最大的差别就是:动态代理是在执行时刻动态的创建出代理类及其对象. 上篇中的静态代 ...

随机推荐

  1. Dart Learn Notes 02

    Functions Dart是一门面向对象的语言,所以即便是方法也是一个对象,它的类型是Function. 这就意味着方法可以指向变量,也可以作为方法中的参数供其他方法使用.甚至可以让 一个类作为一个 ...

  2. cenos7搭建gitlab

    git.github和gitlab的区别 git:是一种版本控制系统,是一个命令,是一种工具 gitlib:是基于实现功能的开发库 github:是一个基于git实现的在线代码仓库软件 gitlib可 ...

  3. 【搞定面试官】谈谈你对JDK中Executor的理解?

    ## 前言 随着当今处理器计算能力愈发强大,可用的核心数量越来越多,各个应用对其实现更高吞吐量的需求的不断增长,多线程 API 变得非常流行.在此背景下,Java自JDK1.5 提供了自己的多线程框架 ...

  4. 从零开始手写 spring ioc 框架,深入学习 spring 源码

    IoC Ioc 是一款 spring ioc 核心功能简化实现版本,便于学习和理解原理. 创作目的 使用 spring 很长时间,对于 spring 使用非常频繁,实际上对于源码一直没有静下心来学习过 ...

  5. JS中的同步异步编程

    首先我们先看看同步与异步的定义,及浏览器的执行机制,方便我们更好地理解同步异步编程. 浏览器是多线程的,JS是单线程的(浏览器只分配一个线程来执行JS)   进程大线程小:一个进程中包含多个线程,例如 ...

  6. MySQL数据库day20190922

    1.dos命令 set names gbk; 2.MySQL练习#创建school数据库: create database school;#切换school数据库: use school; # pri ...

  7. vsftpd cmds_allowed 权限控制

    vsftpd cmds_allowed cmds_allowed=ABOR,CWD,LIST,MDTM,MKD,NLST, PASS,PASV,PORT,PWD,QUIT,RETR,RMD,RNFR, ...

  8. MySQL多索引查询选择

    MySQL多索引查询选择 MySQL选择索引-引入 我们知道我们一个表里面可以有多个索引的,那么我们查询数据的时候不指定索引,MySQL就会帮我们自动选择.既然是MySQL程序帮我们自动选择的那么会不 ...

  9. VLAN实验1(VLAN基础配置及Access接口)

    本实验基于<HCNA网 络技术实验指南> 本实验使用eNSP软件 原理概述: 早期的局域网技术是基于总线型结构的.总线型拓扑结构是由一根单电缆连接着所 有主机,这种局域网技术存在着冲突域问 ...

  10. 移动端开发语言的未来的猜想#华为云&#183;寻找黑马程序员#【华为云技术分享】

    版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/devcloud/article/detai ...