`
gupeng_ie
  • 浏览: 26184 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

动态代理(附原理图)

阅读更多

代理:

代理主要体现在(代理类)和(委托类)之间的协调工作,

1.代理类 --proxy

承接着(委托类--目标类)的相关服务的(扩展处理--方法功能增强)的责任

分为 静态代理类 和 动态代理类。

 

*动态代理类:

利用java反射机制--Proxy类 和 InvocationHandler接口。 

 

首先创造一个 (接口实现) 和一个 (InvocationHandler)实例,

{以类装载器、接口数组(Class对象),InvocationHandler来生成}--> (代理类)。 

 

通过 代理类--Proxy 的代理,

(接口) 和 (实现类) 之间可以不直接发生联系,而可以在运行期(Runtime)实现动态关联。  

 

java.lang.reflect.Proxy只能代理(接口),不能代理类。

JDK提供的动态代理只适用于实现接口的类,

CGlib实现动态代理,它提供动态代理的对象可以不实现接口。

 

Java Proxy功能主要通过

java.lang.reflect.Proxy类 与

java.lang.reflect.InvocationHandler接口

实现。

 

*静态代理类:

在程序运行前,代理类的.class文件就已经存在。

 

2.委托类 --目标类

是接口的真正的实现者。 

------------------------------------------------------------------------------------------------

 

动态代理 代码详解:

* 使用程序自动的去完成方法的增强,使用程序去生成代理类

* 获得代理类,Proxy.newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) 

* 实现

Proxy.newProxyInstance(

ClassLoader,//确定代理类被加载到内存的类加载器,一般使用当前类的类加载器

Class[],    //确定代理类需要实现的接口的字节码

InvocationHandler //接口,具体的处理类,在此我们使用到匿名内部类

 //invoke(Object proxy,Method method,Object[] args) -->需要重写的方法

 //* proxy,代理对象本身--代理

 //* method,代理对象执行的方法 在内存的描述,即为一个反射对象

 //* args,当前方法执行的具体、实际参数

 

 //* invoke,委托类的每一个方法在执行时,将被invoke()拦截,即都会调用invoke()

)

 

**获得接口的两种方法:

  final Subject realSubject = new RealSubject();

realSubject.getClass().getInterfaces();

new Class[]{Subject.class};

------------------------------------------------------------------------------------------------

代理作用:

对 (目标对象)--委托类 访问时,对其方法进行拦截,我们可以在此,对我们需要的方法进行功能增强。

即 拦截、增强

 

-------------------------------------------------------------------------------------------------

实例--用 代理 完成连接池

* 思路:

* 1.通过DriverManager获得链接(mysql)

* 2.使用自定义代理类获得链接

* 通过程序编写实现类(动态代理)

* 代理对象的每一个方法都会执行InvocationHandler的invoke方法

* 对具体的方法做出处理,通过方法的名称进行判断。method.getName()

* 注意:需要进行返回return --> 跳出方法

* 对被代理对象--委托类(具体Connection的实现类),进行其他方法的执行。

* 反射:method.invoke(被代理对象--委托类,实际参数)

* 3.目的,对需要增强的方法进行增强

* 将close方法原有的内容替换成,"将当前链接归还给连接池"。

 

*连接池 工具类 代码:

package cn.gp.pool.utils;

 

import java.io.InputStream;

import java.lang.reflect.InvocationHandler;

import java.lang.reflect.Method;

import java.lang.reflect.Proxy;

import java.sql.Connection;

import java.sql.DriverManager;

import java.sql.ResultSet;

import java.sql.SQLException;

import java.sql.Statement;

import java.util.LinkedList;

import java.util.Properties;

 

public class PoolProxyUtils {

 

//创建 连接池--集合,用来盛放 连接--Connection

private static LinkedList<Connection> pool = new LinkedList<Connection>();

//初始化 连接,将 连接 放入 连接池,并使用 动态代理

static {

try {

//获得 建立连接 的参数

InputStream is = PoolProxyUtils.class.getClassLoader()

.getResourceAsStream("jdbc.properties");

 

Properties prop = new Properties();

prop.load(is);

 

String driver = prop.getProperty("driver");

String url = prop.getProperty("url");

String user = prop.getProperty("user");

String password = prop.getProperty("password");

 

//加载驱动

Class.forName(driver);

 

//建立连接池 **核心代码**

for (int x = 0; x < 10; x++) {

// 获得 连接对象--委托类

final Connection conn = DriverManager.getConnection(url, user,

password);

 

//创建 代理对象

Connection connctionProxy = (Connection) Proxy.newProxyInstance(

PoolProxyUtils.class.getClassLoader(), // 提供 类加载器

new Class[] { Connection.class }, // 提供 委托类接口

new InvocationHandler() { // 具体 处理类

 

@Override

public Object invoke(Object proxy,

Method method, Object[] args)

throws Throwable {

// 查看正在使用 委托类的哪个方法

String name = method.getName();

 

// 增强close方法

if ("close".equals(name)) {

// 将 连接 归还 连接池

pool.add((Connection) proxy);

// 跳出invoke()

return null;

}

 

// 其他方法 调用 原类 的方法

return method.invoke(conn, args);

}

});

// 将 代理类对象 添加到 连接池 中

pool.add(connctionProxy);

}

} catch (Exception e) {

throw new RuntimeException(e.getMessage(), e);

}

 

}

//获得连接

public static Connection getConnection() {

//如果 连接池 中有 连接,就获取

if (pool.size() > 0) {

return pool.get(0);

}

//连接池中没有 连接,稍等,递归,调用自身

try {

Thread.sleep(500);

} catch (Exception e) {

throw new RuntimeException(e.getMessage(), e);

}

return getConnection();

}

//释放资源

public static void closeResource(Connection conn, Statement st, ResultSet rs) {

try {

if (rs != null) {

rs.close();

}

} catch (SQLException e) {

e.printStackTrace();

} finally {

try {

if (st != null) {

st.close();

}

} catch (SQLException e) {

e.printStackTrace();

} finally {

try {

if (conn != null) {

conn.close();

}

} catch (SQLException e) {

e.printStackTrace();

}}}}}

-----------------------------------------------------------------------------------------------------------------------------


--------------------------------------------------------------------------------------------

**调用原理:

 

  • 大小: 49.1 KB
  • 大小: 53.2 KB
分享到:
评论

相关推荐

    VB代理服务器附检测代理程序.7z

    标题中的“VB代理服务器附检测代理程序.7z”是一个基于Visual Basic(VB)开发的代理服务器软件,其中包含了代理服务器管理和检测的功能。这个程序设计用于帮助用户管理和测试多个代理服务器的IP地址,确保网络连接...

    基于气味代理优化算法求解单目标优化问题附matlab代码(SAO,Smell Agent Optimization)标准.zip

    5. **绘图函数**:`func_plot.m`用于可视化目标函数的表面和代理在搜索过程中的动态行为,有助于理解算法的搜索路径和性能。 6. **主程序**:`main.m`是主程序,它调用上述所有函数,设置参数(如代理数量、迭代...

    爬虫的HTTP原理(附三大爬虫案例)

    这时,我们需要通过设置代理IP、动态改变User-Agent、解析验证码等方式来应对。此外,使用Cookie管理会话,保持登录状态,也是爬虫中常见的需求。 总结,掌握HTTP原理对爬虫开发者来说非常重要,它能帮助我们理解...

    H5指定盒子截图,H5页面生成卡片完整代码附效果图,H5指定盒子生成图片

    这个库的工作原理是将DOM树转换成Canvas上的绘图命令,从而实现网页内容的截图。但是,由于CSS3的一些特性无法直接在Canvas上绘制,html2canvas可能无法完美地复制所有CSS样式。例如,透明度、渐变和阴影等效果可能...

    《Head_First_设计模式》附书源码

    这本书的附书源码包含了许多书中提到的经典设计模式的实际代码实现,为读者提供了动手实践的机会,帮助深化理解和应用。 设计模式是软件开发中经过验证的、在特定情境下解决常见问题的模板,它提供了一种通用的解决...

    牛客校招面试题测试(附答案与解析)java篇.rar

    7. **反射与动态代理**:了解Class类,反射API的使用,以及动态代理(Proxy)在AOP(面向切面编程)中的应用。 8. **JVM**:垃圾回收机制(GC),内存区域划分(堆、栈、方法区等),类加载机制(双亲委派模型),...

    【电子版】校招面试题库(附答案与解析)java篇.zip

    1. 数据结构与算法:数组、链表、树、图,排序算法,查找算法等。 2. 网络协议:TCP/IP、HTTP,以及网络编程基础知识。 3. 架构设计:微服务、分布式、高并发等系统架构设计原则。 这份资料全面而深入,不仅包含了...

    牛客2019【电子版】校招面试题库(附答案与解析)java篇

    8. **反射机制**:类的加载、类的实例化、访问私有成员、动态代理等。 9. **设计模式**:常见的设计模式,如单例模式、工厂模式、建造者模式、装饰器模式、代理模式等。 10. **JVM**:内存模型,垃圾回收机制,类...

    校招面试题库java(附答案与解析)

    7. **设计模式**:熟悉常见的设计模式,如单例模式、工厂模式、观察者模式、装饰器模式、代理模式等,能够展现出良好的编程思维和代码组织能力。 8. **数据结构与算法**:虽然Java面试主要测试编程能力,但数据结构...

    java笔试题大集合及答案(另附各大公司笔试题)

    7. **反射**:如何在运行时动态获取类的信息,创建对象,调用方法,以及其在插件化、动态代理等场景中的应用。 8. **设计模式**:工厂模式、单例模式、装饰器模式、观察者模式、适配器模式等常见设计模式的原理和...

    全网最齐全的Java面试题库-附答案-持续更新.zip

    这个名为“全网最齐全的Java面试题库-附答案-持续更新.zip”的压缩包文件,显然旨在为Java开发者提供一个全面的面试准备资源,包括问题和对应的答案。这份资料可能是由专家或经验丰富的开发者编纂,涵盖了Java的基础...

    java面试笔试试题大集合及答案(另附各大公司笔试题)

    设计模式是软件工程的精髓,常见的设计模式有工厂模式、单例模式、建造者模式、观察者模式、适配器模式、装饰器模式、桥接模式、代理模式、策略模式、模板方法模式、访问者模式等。理解并能灵活运用这些模式可以提高...

    【定位】基于非测距的定位算法Dv-Hop算法实现节点定位附Matlab代码.zip

    该算法的核心思想是利用-hop计数作为距离的代理。在一个WSN中,已知位置的节点被称为锚节点,未知位置的节点是待定位节点。Dv-Hop算法假设从一个锚节点到另一个锚节点的平均hop数与它们之间的实际距离成正比。通过多...

    java笔试题大集合及答案(另附各大公司笔试题)

    15. **算法与数据结构**:基础算法如排序(冒泡、选择、插入、快速、归并等)、查找(二分查找、哈希查找等),以及链表、树、图等数据结构的理解和应用。 通过上述知识点的学习和实践,求职者不仅可以为笔试做好...

    CE认证需要的基本资料

    4. **电器原理图**(仅适用于电气产品):展示产品的电气工作原理,帮助审核人员理解产品的安全电路设计。 5. **机械装配图和关键零部件图纸**:对于机械产品,提供装配图和关键部件的详细图纸,以验证其机械安全性...

    网站整站下载器--中国网协专版(附有效注册码)

    9. **辅助工具**:为了提高下载效率,用户还可以配合使用代理服务器、CDN加速等服务,尤其是对于大型网站的下载。 10. **学习与应用**:对于开发者而言,了解这类工具的工作机制有助于提升网页抓取和数据挖掘的能力...

    Java笔试题大集合及答案(另附各大公司笔试题)

    3. **数据结构与算法**:数组、链表、栈、队列、堆、树、图等数据结构的特性及其操作,以及排序算法(冒泡、选择、插入、快速、归并等)、查找算法(顺序、二分、哈希等)是常见的笔试题型。求职者应能熟练掌握这些...

    计算机网络模拟试题(三)附参考答案.doc

    【计算机网络模拟试题(三)附参考答案】 一、填空题 1、分组交换网的组网方式一般有**虚拟电路(VC)**和**数据报(Datagram)**两种。虚拟电路方式在网络中预先建立一条路径,数据报方式则每个数据包独立选择...

    OA办公系统——(SSM)附代码和数据库

    这些表之间的关系需要通过ER图(实体关系图)来清晰地表示,确保数据的一致性和完整性。 5. **工作流程**:OA系统的重点在于实现自动化的工作流程,如请假审批、报销申请等。这部分通常会涉及到工作流引擎,例如...

Global site tag (gtag.js) - Google Analytics