JDK动态代理中包含一个类和一个接口:
InvocationHandler接口: public interface InvocationHandler { public Object invoke(Object proxy,Method method,Object[] args) throws Throwable; }
参数说明:
Object proxy:指被代理的对象。
Method method:要调用的方法
Object[] args:方法调用时所需要的参数
可以将InvocationHandler接口的子类想象成一个代理的最终操作类,替换掉ProxySubject。
Proxy类:
Proxy类是专门完成代理的操作类,可以通过此类为一个或多个接口动态地生成实现类,此类提供了如下的操作方法:
public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) throws IllegalArgumentException
参数说明:
ClassLoader loader:类加载器
Class<?>[] interfaces:得到全部的接口
InvocationHandler h:得到InvocationHandler接口的子类实例
类加载器
在Proxy类中的newProxyInstance()方法中需要一个ClassLoader类的实例,ClassLoader实际上对应的是类加载器,在Java中主要有一下三种类加载器;
Booststrap ClassLoader:此加载器采用C++编写,一般开发中是看不到的;
Extendsion ClassLoader:用来进行扩展类的加载,一般对应的是jre\lib\ext目录中的类;
AppClassLoader:(默认)加载classpath指定的类,是最常使用的是一种加载器。
动态代理
与静态代理类对照的是动态代理类,动态代理类的字节码在程序运行时由Java反射机制动态生成,无需程序员手工编写它的源代码。 动态代理类不仅简化了编程工作,而且提高了软件系统的可扩展性,因为Java 反射机制可以生成任意类型的动态代理类。java.lang.reflect 包中的Proxy类和InvocationHandler 接口提供了生成动态代理类的能力。
package jdbc.datasourcepool.utils; import java.io.InputStream; import java.io.PrintWriter; 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.SQLException; import java.sql.SQLFeatureNotSupportedException; import java.util.LinkedList; import java.util.Properties; import java.util.logging.Logger; import javax.sql.DataSource; public class DataSourcePoolProxy implements DataSource { // 给出一个容器 private static LinkedList<Connection> list = new LinkedList<Connection>(); static { InputStream in = DataSourcePoolProxy.class.getClassLoader().getResourceAsStream("db.properties"); Properties prop = new Properties(); try { prop.load(in); String driver = prop.getProperty("driver"); String url = prop.getProperty("url"); String user = prop.getProperty("user"); String password = prop.getProperty("password"); Class.forName(driver); // 初始化10个Connection for (int i = 0; i < 10; i++) { Connection conn = DriverManager.getConnection(url, user, password); list.add(conn); // 将conn对象添加容器中 } } catch (Exception e) { e.printStackTrace(); throw new ExceptionInInitializerError(e); } } public Connection getConnection() throws SQLException { if (list.size() > 0) { final Connection conn = list.removeFirst(); /* * newProxyInstance(ClassLoader loader, Class<?>[] interfaces, * InvocationHandler h) * 返回一个指定接口的代理类实例,该接口可以将方法调用指派到指定的调用处理程序。(这是静态方法) * 第一个参数:定义代理类的类加载器 * 第二个参数:代理类要实现的接口列表 * 第三个参数: 指派方法调用的调用处理程序 */ // 构造一个代理对象 Object obj = Proxy.newProxyInstance(DataSourcePoolProxy.class .getClassLoader(), conn.getClass().getInterfaces(),// 通过Connection的字节码来获得该类声明的所有方法 new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { if ("close".equals(method.getName())) { // 调用的是close方法将连接返还给连接池 System.out.println("使用动态代理" + conn); list.add(conn); return null; } else { // 对于不感兴趣的方法,直接调用真实对象完成 return method.invoke(conn, args); } } }); return (Connection) obj; } else { throw new RuntimeException("系统繁忙,请稍后再进行连接...."); } } public Connection getConnection(String username, String password) throws SQLException { return null; } public PrintWriter getLogWriter() throws SQLException { return null; } public void setLogWriter(PrintWriter out) throws SQLException { } public void setLoginTimeout(int seconds) throws SQLException { } public int getLoginTimeout() throws SQLException { return 0; } public Logger getParentLogger() throws SQLFeatureNotSupportedException { return null; } public <T> T unwrap(Class<T> iface) throws SQLException { return null; } public boolean isWrapperFor(Class<?> iface) throws SQLException { return false; } }
相关推荐
5. **使用代理**:如果需要通过代理服务器进行请求,可以使用`ProxyManager`替代`HTTPAdapter`,它会为每个代理创建单独的连接池。 6. **关闭无用连接**:虽然`requests`会自动管理连接,但在某些情况下,如服务器...
数据库连接池的基本原理是预先在内存中创建一定数量的数据库连接,应用程序在需要时可以从池中获取连接,使用完毕后再归还,而不是每次操作都创建新的连接。这大大减少了创建和销毁连接的开销,提高了系统运行效率。...
在本文中,我们将深入探讨如何通过代理模式来实现JDBC的数据库连接池,以及这一技术的重要性和实际应用。 首先,让我们理解代理模式的基本概念。代理模式是一种设计模式,它提供了一个代理对象来控制对原始对象的...
1. 引入依赖:在 Maven 或者 Gradle 的构建文件中添加对应连接池的依赖库。 2. 配置数据源:在配置文件(如 XML 或 YAML)中设置连接池的基本属性,如数据库URL、用户名、密码、最大/最小连接数等。 3. 集成到应用:...
这样,当一个数据库连接被关闭时,实际上并不会真正断开,而是返回到连接池中等待下一次使用,减少了频繁创建和销毁连接的开销。 2. **SingletonDB**: 这是一个单例模式的数据库连接类,确保在同一个进程中只有一个...
本文将详细介绍"proxool+mysql+tomcat连接池所需jar包"的相关知识,以及如何在实际项目中配置和使用。 首先,我们要理解连接池的基本概念。数据库连接池是在应用服务器启动时预创建一定数量的数据库连接,然后在...
Proxool是一个基于池化的JDBC代理,它维护着一个数据库连接池,当应用需要访问数据库时,可以从池中获取连接,用完后再归还,而不是每次请求都创建新的连接,从而提高系统性能,减少数据库的压力。 **配置步骤** 1...
在实现方面,动态连接组件封装了***中的Connection和Command对象,提供了统一的接口供信息系统使用。组件可以根据配置信息,动态生成连接字符串,创建和管理数据库连接。同时,通过异常处理机制,组件能够有效地处理...
在Java编程环境中,多项目多工程的代理设置是一项常见的需求,尤其在进行网络请求时,如使用HttpUrlConnection。这个场景通常涉及到多个独立的开发项目或模块,它们可能需要通过同一代理服务器访问互联网资源,或者...
3. 获取和使用连接:在需要发送或接收消息的地方,从连接池中获取连接,使用完毕后归还。这样可以避免频繁创建和关闭连接。 ```java Connection connection = connectionFactory.getConnection(); Channel channel =...
通过分析这个类的源代码,开发者可以学习如何在实际项目中构建和使用Moquitto连接池,提高系统的并发性能和资源利用率。 总之,Moquitto连接池是优化MQTT通信效率的重要手段,通过有效的连接管理和复用,可以降低...
Druid是一个由阿里巴巴开源的高性能、可扩展的Java数据库连接池(JDBC Connection Pool)组件。在Java开发中,数据库连接池是不可或缺的部分,它负责管理数据库连接,提高数据库访问效率,减少系统资源消耗。Druid因...
最后,在应用程序中使用Proxool就像使用普通的数据库连接一样,但实际上是通过代理连接来操作数据库: ```java Connection conn = sqlMap.getConnection(); Statement stmt = conn.createStatement(); ResultSet rs...
例如,使用`DriverManager.getConnection()`方法时,会自动利用Proxool的连接池机制。 总结来说,"proxool相关jar包.rar"提供的是一组用于管理数据库连接的Java类库,包括Proxool的两个不同版本和其依赖的CGLIB库。...
标题 "proxool必备的3个jar包" 指向的是在Java开发环境中使用Proxool连接池时所需的关键库文件。Proxool是一个开源的数据库连接池解决方案,它允许开发者管理和优化数据库连接,提高应用性能,降低资源消耗。在这个...
桥连(Tunneling or Bridge Connection)则是一种通过中间代理服务来建立数据库连接的方法,例如使用SSH隧道或者数据库连接池。桥连可以提供额外的安全性,因为所有到数据库的通信都经过加密的隧道。此外,它还可以...
- **数据库连接池**:如C3P0、DBCP、HikariCP等,使用反射初始化和管理数据库连接。 - **ORM框架**:Hibernate、MyBatis等,它们利用反射实现了对象与数据库之间的映射,简化数据库操作。 - **AOP(面向切面编程...
在实际应用中,例如,你可以使用如下代码创建一个基于 PooledDB 的连接池: ```python from DBUtils.PooledDB import PooledDB import psycopg2 class MyDatabase: def __init__(self): self.pool = PooledDB( ...
总之,Python爬虫中使用代理IP是一种常见的反反爬策略,通过合理使用代理IP,我们可以更好地执行网络抓取任务,提高爬虫的稳定性和效率。在实践中,结合其他技术如用户代理轮换、验证码识别等,可以进一步提升爬虫的...