JDK动态代理连接池
JDK动态代理
1 什么是JDK动态代理
刚刚写ItcastConnection时爽么?因为Connection中的方法太多了,每个都要写,所以很累吧。累点到是没什么,可以完成功能就是好的。但是不是什么时候可以用代理的,有时你可能会遇到要代理的东西,只有在运行时才能知道,所以你不可能先把代理写出来!这时就需要使用动态代理。
JDK动态代理是JavaSE中一个高级特性,不是那么好理解的,但是它可是框架们的"秘密武器"。你要是可以理解它,那么将来在学习框架时,你就会知道框架是怎么完成一些"神奇功能"的。
动态代理的作用:在运行时生成一个实现了指定接口的对象。
例如在运行时生成一个对象,这个对象实现了Connection接口。
2 JDK动态代理之Hello World
我们要写一个程序,这个程序会在运行时动态的生成一个对象,这个对象会实现Connection接口。
Connectoin c = (Connection)Proxy.newInstance(Connetion.class);
上面代码只是示意代码,不能编译通过的。
上面代码有个问题:生成一个实现了指定接口的对象,但是我们知道实现接口,需要为接口中每个方法添加实现内容,那么这个动态代理对象它是怎么实现Connection接口中的方法的呢?也就是说,我现在如果调用了代理对象的close()方法,它会执行什么呢?这就是问题!
想生成代理对象,还需要提供实现内容!
别的先别去管,先来看一个接口:InvocationHandler。
|
class HelloWorldHandler implements InvocationHandler { public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("Hello 动态代理!"); return } } |
InvoactionHandler接口只有一个方法,invoke()!方法的参数你不要去管是什么意思,只需要知道它只有一个方法,名字叫invoke(),一会儿再去讨论它参数的含义。
Connectoin c = (Connection)Proxy.newInstance(Connetion.class, new HelloWorldHandler());
上面代码还是示意代码,不能编译通过。
我们这回在创建代理对象时,多给出了一个参数,是一个接口的实现类。实现类中有一条输出语句"Hello 动态代理!",现在生成的代理对象是Connection接口的实现类对象,你调用代理对象的任何方法都会调用HelloWorldHandler的invoke()方法,即输出"Hello 动态代理!"。
Connectoin c = (Connection)Proxy.newInstance(Connetion.class, new HelloWorldHandler());
c.close();
c.toString();
c.createStatement();
还是示意代码!
上面示意代码中调用了三个方法,无论哪个方法都会输出"Hello 动态代理!"。现在你知道InvocationHandler接口的作用了吧。
|
public ClassLoader loader = Thread.currentThread().getContextClassLoader(); Class[] interfaces = {Connection.class}; InvocationHandler h = new HelloWorldHandler(); Connection con = (Connection)Proxy.newProxyInstance(loader, interfaces, h); con.close(); con.toString(); con.createStatement(); } |
3 真正的代理
虽然我们学会了动态代理,但还没有真正的代理。真正的代理是需要一个真正的连接对象,然后我们的代理对象使用它来完成任务。为了说明这个真正的代理,需要写几个类:
|
public public } |
|
public public System.out.println("服务..."); } } |
上面代码中写了一个Waiter接口,和一个WaiterImpl,它是Waiter接口的实现类。现在我们要写一个WaiterImpl的代理类。
|
public private Waiter waiter; public WaiterProxy(Waiter waiter) { this.waiter = waiter; } public waiter.serve(); } } |
上面代理中,WaiterProxy就是一个代理类,当然,这个代理类没有实际的意义,因为它没有做任何的改变,所以没有意思!通常代理类是这样的,它会去实现一个接口,但它还需要一个该接口的实现类对象,然后所有实现都使用这个对象来完成。象是上面的代理中,WaiterProxy是一个代理类,它实现了Waiter接口,而且它还需要一个Waiter类型的对象,然后所有的实现都是代理这个对象功能。但是通常代理类会对被代理的对象的一些行为做一些改动,我们的例子中没有做。
上面的WaiterProxy虽然是一个代理类,但它不是动态代理。下面是通过JDK动态代理来生成一个代理对象。
|
public private Waiter waiter; public WaiterHandler(Waiter waiter) { this.waiter = waiter; } public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { return method.invoke(waiter, args); } } |
|
ClassLoader loader = Thread.currentThread().getContextClassLoader(); Class[] interfaces = {Waiter.class}; Waiter watier = new WaiterImpl(); InvocationHandler h = new WaiterHandler(watier); Waiter proxy = (Waiter)Proxy.newProxyInstance(loader, interfaces, h); proxy.serve(); |
4 使用动态代理完成连接池
|
public private String username; private String password; private String url; private String driverClassName;
private List<Connection> list = new ArrayList<Connection>(); private
private flag = false; try { Class.forName(driverClassName); } catch(ClassNotFoundException e) { throw } for(int i = 0; i < 5; i++) { final Connection con = DriverManager.getConnection(url, username, password); ClassLoader l = Thread.currentThread().getContextClassLoader(); Class[] ins = {Connection.class}; InvocationHandler h = new InvocationHandler() { public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { if(method.getName().equals("close")) { list.add((Connection)proxy); return } else { return method.invoke(con, args); } } }; Connection proxy = (Connection)Proxy.newProxyInstance(l, ins, h); list.add(proxy); } }
public Connection getConnection() throws SQLException { if(flag) { init(); } if(list.size() > 0) { return } throw } ...... } |
JDK动态代理连接池的更多相关文章
- Spring AOP详解 、 JDK动态代理、CGLib动态代理
AOP是Aspect Oriented Programing的简称,面向切面编程.AOP适合于那些具有横切逻辑的应用:如性能监测,访问控制,事务管理以及日志记录.AOP将这些分散在各个业务逻辑中的代码 ...
- 【转载】Spring AOP详解 、 JDK动态代理、CGLib动态代理
Spring AOP详解 . JDK动态代理.CGLib动态代理 原文地址:https://www.cnblogs.com/kukudelaomao/p/5897893.html AOP是Aspec ...
- 【原创】分布式之缓存击穿 【原创】自己动手实现静态资源服务器 【原创】自己动手实现JDK动态代理
[原创]分布式之缓存击穿 什么是缓存击穿 在谈论缓存击穿之前,我们先来回忆下从缓存中加载数据的逻辑,如下图所示 因此,如果黑客每次故意查询一个在缓存内必然不存在的数据,导致每次请求都要去存储层去查 ...
- Spring AOP JDK动态代理与CGLib动态代理区别
静态代理与动态代理 静态代理 代理模式 (1)代理模式是常用设计模式的一种,我们在软件设计时常用的代理一般是指静态代理,也就是在代码中显式指定的代理. (2)静态代理由 业务实现类.业务代理类 两部分 ...
- JDK动态代理与CGLib动态代理
1.JDK动态代理 JDK1.3以后java提供了动态代理技术,允许开发者在运行期创建接口的代理实例,动态代理是实现AOP的绝好底层技术. JDK的动态代理主要涉及到java.lang.reflect ...
- JDK动态代理[4]----ProxyGenerator生成代理类的字节码文件解析
通过前面几篇的分析,我们知道代理类是通过Proxy类的ProxyClassFactory工厂生成的,这个工厂类会去调用ProxyGenerator类的generateProxyClass()方法来生成 ...
- 017 Java中的静态代理、JDK动态代理、cglib动态代理
一.静态代理 代理模式是常用设计模式的一种,我们在软件设计时常用的代理一般是指静态代理,也就是在代码中显式指定的代理. 静态代理由业务实现类.业务代理类两部分组成.业务实现类负责实现主要的业务方法,业 ...
- JDK动态代理深入理解分析并手写简易JDK动态代理(下)
原文同步发表至个人博客[夜月归途] 原文链接:http://www.guitu18.com/se/java/2019-01-05/27.html 作者:夜月归途 出处:http://www.guitu ...
- JDK动态代理深入理解分析并手写简易JDK动态代理(上)
原文同步发表至个人博客[夜月归途] 原文链接:http://www.guitu18.com/se/java/2019-01-03/27.html 作者:夜月归途 出处:http://www.guitu ...
随机推荐
- 求出数组中所有数字的和&&弹出层效果
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- Java虚拟机对锁优化所做的努力(读书笔记)
锁偏向 是一种加锁操作的优化手段,他的核心思想是:如果一个线程获得了锁,那么就进入偏向模式,当这个线程再次请求锁时,无须在做任何同步操作,因此在几乎没有锁竞争的场合,偏向锁是比较好的优化效果 ...
- Python 实现指定目录下 删除指定大小的文件
import os, sys from stat import * BIG_FILE_THRESHOLD = 6000L #1000000L dict1 = {} # dict2 = {} # def ...
- Oracle PLSQL通过SMTP发送E-MAIL邮件代码
登录到SMTPserver发送邮件,支持HTML CREATE OR REPLACE PROCEDURE send_mail( p_recipient VARCHAR2, -- 邮件接收 ...
- Python3链接MySQL数据库
Python 2.x 上连接MySQL的库倒是不少的,其中比较著名就是MySQLdb(Django项目都使用它:我也在开发测试系统时也使用过),见:http://sourceforge.net/pro ...
- TCP/IP详解 卷一(第十四章 DNS:域名系统)
域名系统(DNS Domain Name System)是一种用于TCP/IP应用程序的分布式数据库,它提供主机名字和IP地址之间的转换及有关电子邮件的选路信息. 从应用角度上看,对DNS的访问时通过 ...
- MySql 删除相同前缀的表名
SELECT CONCAT('drop table ', table_name, ';') FROM information_schema.tables WHERE table_name LIKE ' ...
- PHP和Java的主要区别有哪些?哪个最适合Web开发语言?
一.前言 PHP和Java都是现在比较流行的二种编程语言. 对于许多新手来说,都会思考如果学的时候,该学哪种语言呢?下面这篇文章给大家整理两者的区别以及一些选择建议,一起来看看吧. 二.简介 PHP与 ...
- Springboot Maven 多模块项目中 @Service跨模块引用失败的问题
子模块中引用另一个子模块中的Service, @Autowired失败. 添加了模块之间的依赖没解决. 组以后在启动类上加上 @SpringBootApplication(scanBasePackag ...
- 《TomCat与Java Web开发技术详解》(第二版) 第六章节对应CD附带的helloapp无法启动的问题解决
首先记录一下如何解决此章节CD中附带的helloapp无法启动的问题 我用的tomcat版本是:7.0.47:为了便于控制,针对此章节的helloapp,我在tomcat/conf/Catalina/ ...