IDB

package com.bjpowernode.proxy;

/**
* 代理类和目标类都必须使用同一个接口。
*/
public interface IDB { int insert();
int delete();
int update();
}

OracleDB

package com.bjpowernode.proxy;

/**
* 这是一个Oracle数据库相关的操作类
*
* 目标类(委托类)。
*/
public class OracleDB implements IDB{
public int insert(){ //以下是一个插入操作
System.out.println("Oracle insert data....");
try {
Thread.sleep(526);
} catch (InterruptedException e) {
e.printStackTrace();
}
return 0;
} public int delete(){ //以下是一个删除操作
System.out.println("Oracle delete data....");
try {
Thread.sleep(569);
} catch (InterruptedException e) {
e.printStackTrace();
} return 0;
} public int update(){ //以下是一个更新操作
System.out.println("Oracle update data....");
try {
Thread.sleep(456);
} catch (InterruptedException e) {
e.printStackTrace();
} return 0;
} }

TimeInvocationHandler

package com.bjpowernode.proxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method; /**
* 注册在这个接口中的代码,在代理对象调用代理方法的时候,自动执行。
* 我们的扩展代码就注册在这个类中。
*/
public class TimeInvocationHandler implements InvocationHandler { //这个程序运行期,obj引用中保存了内存地址指向的对象是一个目标对象。
private Object obj; public TimeInvocationHandler(Object obj){
this.obj = obj;
} /**
* proxy 是代理对象的引用。
* method 是目标类中的目标方法
* args 是目标类中的目标方法的实参
*/
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable { long begin = System.currentTimeMillis(); //通过反射机制去调用目标类中的目标方法
Object retValue = method.invoke(obj, args); long end = System.currentTimeMillis();
System.out.println("方法执行所耗费" + (end-begin) + "毫秒"); return retValue;
} }

Test

package com.bjpowernode.proxy;

import java.lang.reflect.Proxy;

public class Test {

    public static void main(String[] args) {

        //创建目标类对象
IDB db = new OracleDB(); //创建代理对象
//DBProxy dbProxy = new DBProxy(); //这是静态代理模式中创建对象,因为DBProxy是我们程序员手动编写的。 //创建代理对象(这次创建代理对象是交给JVM完成,包括在这个过程中,JVM也会自动生成“代理类的字节码”)
//这个代理类是动态生成的字节码不会以.class文件的形式保存在硬盘上,所以我们称作动态代理。 //第一个参数是类装载器:JVM会在内存中自动生成一个字节码,但是这个字节码要想运行,必须经过类装载器的装载
//然后进一步解析,所以必须传递一个类装载器,这个类装载器就是用来装载这个临时的“字节码”。
//代理类和目标类必须使用同一个类装载器。 //第二个参数:是JVM在生成代理类的时候需要实现接口,但是这个接口又不能随便写,因为代理类和目标类要求实现相同的接口。
//所以我们将目标类实现的接口获取到之后传递过来就行了。
//JDK中提供的代理模式只能代理接口。如果目标类它的父类型不是一个接口而是一个抽象类,那么JDK中提供的动态代理就不能用了,需要使用
//第三方组件,例如:cglib。 //第三个参数:是InvocationHandler,这是一个接口,这个接口中的方法会在代理类调用代理方法的时候自动执行。
IDB dbProxy = (IDB)Proxy.newProxyInstance(db.getClass().getClassLoader(), db.getClass().getInterfaces(), new TimeInvocationHandler(db)); //通过代理对象中的方法去执行目标对象中的方法。
dbProxy.insert(); //dbProxy是一个动态生成的代理对象,由于这个代理对象实现了和OracleDB一样的接口,所以可以用IDB接口指向JVM中的代理对象。
dbProxy.delete(); // 这里调用的delete方法是是代理类中的代理方法,不是目标类中的目标方法。但是一定会通过代理方法去调用目标方法。
dbProxy.update(); } }

  

代理模式-jdk动态代理的更多相关文章

  1. 动态代理模式——JDK动态代理

    今天,我就来讲一下动态代理的设计模式. 动态代理的意义在于生成一个代理对象,来代理真实对象,从而控制真实对象的访问.操作动态代理需要两个步骤:一.代理对象和真实对象建立代理关系.二.实现代理对象的代理 ...

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

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

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

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

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

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

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

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

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

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

  7. (转)轻松学,Java 中的代理模式及动态代理

    背景:讲到反射机制,肯定会想到动态代理. 轻松学,Java 中的代理模式及动态代理 代理模式可以在不修改被代理对象的基础上,通过扩展代理类,进行一些功能的附加与增强.值得注意的是,代理类和被代理类应该 ...

  8. Java代理(静态代理、JDK动态代理、CGLIB动态代理)

    Java中代理有静态代理和动态代理.静态代理的代理关系在编译时就确定了,而动态代理的代理关系是在运行期确定的.静态代理实现简单,适合于代理类较少且确定的情况,而动态代理则给我们提供了更大的灵活性. J ...

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

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

随机推荐

  1. 【WPF on .NET Core 3.0】 Stylet演示项目 - 简易图书管理系统(4) - 图书列表界面

    在前三章中我们完成了登录窗口, 并掌握了使用Conductor来切换窗口, 但这些其实都是在为我们的系统打基础. 而本章中我们就要开始开发系统的核心功能, 即图书管理功能了. 通过本章, 我们会接触到 ...

  2. 西柚考勤系统——alpha2

    这个作业属于哪个课程 http://edu.cnblogs.com/campus/xnsy/GeographicInformationScience 这个作业的要求在哪里 https://www.cn ...

  3. Python3之MySQL操作

    1.安装pymysql PyMySQL 是在 Python3.x 版本中用于连接 MySQL 服务器的一个库,在使用之前需要进行安装,可以使用以下命令安装最新版的 PyMySQL: 1).在cmd命令 ...

  4. Commvault逻辑架构及组件说明

    在学习和使用Commvault软件的过程中,经常会碰到一些术语和缩写,初学者可能并不是很清楚这些术语和缩写的具体含义,接下来我们梳理一下Commvault软件中这些属于和缩写的含义,有可能一次不能梳理 ...

  5. 云原生 - Istio可观察性之分布式跟踪(三)

    作者:justmine 头条号:大数据与云原生 微信公众号:大数据与云原生 创作不易,在满足创作共用版权协议的基础上可以转载,但请以超链接形式注明出处. 为了方便阅读,微信公众号已按分类排版,后续的文 ...

  6. JDK源码之StringBuffer与StringBuilder类分析

    一 概述 StringBuffer类被 final 所修饰,不能被继承,StringBuffer继承了AbstractStringBuilder类, 是一个可变的字符序列,并且类中方法都有synchr ...

  7. Oracle:imp导入dmp文件

    oracle命令行登录 sqlplus / as sysdba 创建用户 create user 用户 identified by 密码 ; 创建表空间 create tablespace 表空间名 ...

  8. 【译】SQ3R学习法则

    SQ3R 观察-提问-阅读-复述-回顾 背景 SQ3R是一种理解策略,可帮助学生在阅读时思考他们正在阅读的文章. SQ3R通常被归类为学习策略,通过教导学生在初次阅读一篇文章时如何阅读和像高效读者一样 ...

  9. C++使用类调用CUDA核函数

    正如CUDA C所称,CUDA对C语言进行了很好的扩展,直接使用C语言可以非常简单方便的调用CUDA核函数.但是当想使用C++的类成员函数直接调用核函数是不可行的,第一,核函数不能作为类的成员函数,第 ...

  10. HTTPS详解二:SSL / TLS 工作原理和详细握手过程

    HTTPS 详解一:附带最精美详尽的 HTTPS 原理图 HTTPS详解二:SSL / TLS 工作原理和详细握手过程 在上篇文章HTTPS详解一中,我已经为大家介绍了 HTTPS 的详细原理和通信流 ...