一、动态代理的作用

  使用动态代理可以拦截一个对象某个方法的执行,并执行自定义的方法,其本质是反射

  优点:灵活

  缺点:由于其本质是反射,所以执行速度相对要慢一些

二、数据库连接池设计思想

  1.为什么要使用数据库连接池:创建Connection对象的过程是非常耗时的,为了保证Connection可以重用,应该对Connection进行管理。

  2.设计要求:

    (1)连接池能够实现维护多个连接,必须要保证每一个线程获取到的是不同的Connection对象。

    (2)提供一个方法能够回收连接。

  3.最基本的实现

package day15_2;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.ArrayList; /**
* 使用最基本的方式创建数据库连接池
* @author kdyzm
*
*/
public class JDBCPool1 {
private static ArrayList<Connection>pool=new ArrayList<Connection>();
static
{
try {
Class.forName("com.mysql.jdbc.Driver");
String url="jdbc:mysq://localhost:3306?useUnicode=true&characterEncoding=utf-8";
for(int i=0;i<5;i++)
{
Connection conn=DriverManager.getConnection(url, "root", "5a6f38");
pool.add(conn);
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
} public Connection getConn()
{
synchronized (pool) {
Connection conn=pool.remove(0);
System.out.println("还有 "+pool.size()+"个连接");
return conn;
}
} public static void back(Connection conn)
{
System.out.println("还连接:"+conn);
pool.add(conn);
}
}

  4.程序员写代码总是习惯性的调用close方法,如果实际调用了close方法,则该连接将会被释放,再也回收不回来了,所以应当使用一种方法拦截close方法的执行,并且替换成自定义的动作。使用代理可以完成这个任务。

  代码示例:

import java.io.File;
import java.io.FileInputStream;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.net.URL;
import java.net.URLDecoder;
import java.sql.Connection;
import java.sql.DriverManager;
import java.util.LinkedList;
import java.util.Properties;
public class ConnUtils {
private static LinkedList<Connection> pool = new LinkedList<Connection>();
static{
try {
//声明资源器类 - 
Properties prop = new Properties();
//获取这个文件的路径
URL url = ConnUtils.class.getClassLoader().getResource("jdbc.properties");
String path = url.getPath();
//为了防止有中文或是空格
path = URLDecoder.decode(path,"UTf-8");
File file = new File(path);
//加载jdbc.properties这个文件
prop.load(new FileInputStream(file));
//获取信息
String driver = prop.getProperty("driver");
Class.forName(driver);
String jdbcurl = prop.getProperty("url");
String nm = prop.getProperty("name");
String pwd = prop.getProperty("pwd");
//创建三个原生的连接,都将它们代理
String poolSize = prop.getProperty("poolSize");
int size = Integer.parseInt(poolSize);
for(int i=0;i<size;i++){
final Connection con = DriverManager.getConnection(jdbcurl,nm,pwd);
//对con进行动态代理
Object proxyedObj =
Proxy.newProxyInstance(ConnUtils.class.getClassLoader(),
new Class[]{Connection.class},
new InvocationHandler() {
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
//是否是close方法
if(method.getName().equals("close")){
synchronized (pool) {
pool.addLast((Connection) proxy);
pool.notify();
}
return null;//如果调用的是close则不会调用被代理类的方法。
}
return method.invoke(con, args);
}
});
//将代理对象放到pool中
pool.add((Connection) proxyedObj);
}
} catch (Exception e) {
e.printStackTrace();
}
} public static Connection getConn(){
synchronized (pool) {
if(pool.size()==0){  //如果连接池中没有连接则进入等待池中等待
try {
pool.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
return getConn();
}else{          //如果连接池中有连接则将连接分配出去。
Connection con = pool.removeFirst();
System.err.println("还有几个:"+pool.size());
return con;
}
}
}
}

  5.动态代理的核心类。

  (1)Proxy类:提供用于创建动态代理类和实例的动态方法,它还是由这些方法创建的所有动态代理类的超类。

  (2)InvocationHandler接口:是代理实例的调用处理程序实现的接口。

  6.代理的任务

  (1)在内存中创建某个接口的子类。

  (2)拦截所有在代理上执行的方法。

三、联系人管理小练习。

  源代码:https://github.com/kdyzm/day15

  

【Java EE 学习 15】【自定义数据库连接池之动态代理的使用】的更多相关文章

  1. [javaEE] 数据库连接池和动态代理

    实现javax.sql.DataSource接口 实现Connection getConnection()方法 定义一个静态的成员属性LinkedList类型作为连接池,在静态代码块中初始化5条数据库 ...

  2. Java EE开发平台随手记5——Mybatis动态代理接口方式的原生用法

    为了说明后续的Mybatis扩展,插播一篇广告,先来简要说明一下Mybatis的一种原生用法,不过先声明:下面说的只是Mybatis的其中一种用法,如需要更深入了解Mybatis,请参考官方文档,或者 ...

  3. 【Java EE 学习 16 上】【dbcp数据库连接池】【c3p0数据库连接池】

    一.回顾之前使用的动态代理的方式实现的数据库连接池: 代码: package day16.utils; import java.io.IOException; import java.lang.ref ...

  4. Java Web(九) JDBC及数据库连接池及DBCP,c3p0,dbutils的使用

    DBCP.C3P0.DBUtils的jar包和配置文件(百度云盘):点我下载 JDBC JDBC(Java 数据库连接,Java Database Connectify)是标准的Java访问数据库的A ...

  5. 【Java EE 学习 16 下】【dbutils的使用方法】

    一.为什么要使用dbutils 使用dbutils可以极大程度的简化代码书写,使得开发进度更快,效率更高 二.dbutils下载地址 http://commons.apache.org/proper/ ...

  6. 【Java EE 学习 19】【使用过滤器实现全站压缩】【使用ThreadLocal模式解决跨DAO事务回滚问题】

    一.使用过滤器实现全站压缩 1.目标:对网站的所有JSP页面进行页面压缩,减少用户流量的使用.但是对图片和视频不进行压缩,因为图片和视频的压缩率很小,而且处理所需要的服务器资源很大. 2.实现原理: ...

  7. Java EE学习——Quartz的Cron表达式

    经历过低谷后,还是要好好学习,越失落会越来越落后. 今天写一下Cron表达式的用法,虽然是之前自己写的,也过了挺长一段时间,这次就拿出来作为回顾吧. Cron表达式是Quartz的精髓(个人觉得),比 ...

  8. 【转】JDBC学习笔记(8)——数据库连接池(dbcp&C3P0)

    转自:http://www.cnblogs.com/ysw-go/ JDBC数据库连接池的必要性 一.在使用开发基于数据库的web程序时,传统的模式基本是按一下步骤: 1)在主程序(如servlet/ ...

  9. 第77节:Java中的事务和数据库连接池和DBUtiles

    第77节:Java中的事务和数据库连接池和DBUtiles 前言 看哭你,字数:8803,承蒙关照,谢谢朋友点赞! 事务 Transaction事务,什么是事务,事务是包含一组操作,这组操作里面包含许 ...

随机推荐

  1. PRINCE2

    首先要说的是,我这篇体会是针对一定的背景的,不能算是一种通用的管理方式,只能是我自己的经验总结,能给大家平常的管理提供一点思路,我就很满足了.先说说背景,我所在公司做的是大型桌面应用软件,简单点说就是 ...

  2. 网页游戏外挂辅助AMF模拟通讯必备

    class AMF_Post_Data { public List<byte> message; /// <summary> /// 初始化Message /// </s ...

  3. Codeforces Round #342 (Div. 2) D. Finals in arithmetic(想法题/构造题)

    传送门 Description Vitya is studying in the third grade. During the last math lesson all the pupils wro ...

  4. (转)Javascript本地存储小结

    转自:https://i.cnblogs.com/EditPosts.aspx?opt=1 以下是原文: 1. 各种存储方案的简单对比 Cookies:浏览器均支持,容量为4KB UserData:仅 ...

  5. 制作wordpress留言板

    总结步骤如下: 1.找到模板目录中的single.php文件,复制single.php并重命名为guestbook.php 2.在guestbook最顶部添加如下代码(用于模板调用) <?php ...

  6. Bootstrap学习笔记

    Bootstrap提供了一套响应式.移动设备优先的流式栅格系统. Bootstrap把一个容器或整个网页平均分成了12列. 栅格系统必须放在.container或container-fluid中 样式 ...

  7. FireFox每次访问页面时检查最新版本

    FireFox每次访问页面时检查最新版本 浏览器都有自己的缓存机制,作为开发人员,每次js的修改都要清空缓存,显然很不方便.而firefox并没有提供ie那样的设置. 下面的方法就可以非常方便的设置f ...

  8. MySql 里的IFNULL、NULLIF和ISNULL用法区别

    mysql中isnull,ifnull,nullif的用法如下: isnull(expr) 的用法:如expr 为null,那么isnull() 的返回值为 1,否则返回值为 0. mysql> ...

  9. php代码规范—2

    如何写出好的 PHP 代码? 在本文中,我们将探讨一些良好的编程习惯,这将帮助你避免代码中的缺陷. 1- 编写模块化代码 良好的PHP代码应该是模块化代码.PHP的面向对象的编程功能是一些特别强大的工 ...

  10. godaddy域名使用DNSPod做DNS解析图文教程

    考虑到很多朋友看到英文就很头痛,在godaddy解析域名也不怎么方便,我们需要把在godaddy注册的域名,使用国内的DNS服务器,全部都是免费的哦. 首先打开www.dnspod.cn  用自己的常 ...