数据源的编写(开发中不写)、使用动态代理覆写Connection的close方法
2014-03-13 23:39
369 查看
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.SQLException; import java.util.LinkedList; import javax.sql.DataSource; import com.itheima.util.JdbcUtil; //标准的数据库连接池。按照字面意思,一般叫做数据源(都是带池的,为了提高效率) public class MyDataSource implements DataSource { private static LinkedList<Connection> pool = new LinkedList<Connection>(); static{ try { //池进行初始化:10个连接 for(int i=0;i<10;i++){ pool.add(JdbcUtil.getConnection()); } } catch (Exception e) { throw new ExceptionInInitializerError("数据库连接池初始化失败"); } } //返回它的包装类,会拦截connection中的所有方法 @Override public synchronized Connection getConnection() throws SQLException { if(pool.size()>0){ final Connection conn = pool.removeFirst();//原来的数据的connection实现。被包装类 Connection proxyconn = (Connection)Proxy.newProxyInstance(conn.getClass().getClassLoader(), conn.getClass().getInterfaces(), new InvocationHandler() { public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println(method.getName()); if("close".equals(method.getName())){ return pool.add(conn); }else{ return method.invoke(conn, args); } } }); return proxyconn; }else throw new RuntimeException("服务器忙"); } @Override public PrintWriter getLogWriter() throws SQLException { return null; } @Override public void setLogWriter(PrintWriter out) throws SQLException { } @Override public void setLoginTimeout(int seconds) throws SQLException { } @Override public int getLoginTimeout() throws SQLException { return 0; } @Override public <T> T unwrap(Class<T> iface) throws SQLException { return null; } @Override public boolean isWrapperFor(Class<?> iface) throws SQLException { return false; } @Override public Connection getConnection(String username, String password) throws SQLException { return null; } }
package com.jxnu.util; import java.io.InputStream; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.Properties; //通用的工具类:与具体数据库没有关系 public class JdbcUtil { private static String driverClass; private static String url; private static String username; private static String password; static{ try { //加载配置文件 InputStream in = JdbcUtil.class.getClassLoader().getResourceAsStream("dbcfg.properties"); Properties props = new Properties(); props.load(in); driverClass = props.getProperty("driverClass"); url = props.getProperty("url"); username = props.getProperty("username"); password = props.getProperty("password"); Class.forName(driverClass); } catch (Exception e) { throw new ExceptionInInitializerError(e); } } //获取数据库的连接 public static Connection getConnection() throws Exception{ Connection conn = DriverManager.getConnection(url, username, password); return conn; } //释放占用的资源 public static void release(ResultSet rs,Statement stmt,Connection conn){ if(rs!=null){ try { rs.close(); } catch (SQLException e) { e.printStackTrace(); } } if(stmt!=null){ try { stmt.close(); } catch (SQLException e) { e.printStackTrace(); } } if(conn!=null){ try { conn.close(); } catch (SQLException e) { e.printStackTrace(); } } } }
测试:
package com.jxnu.pool04; import java.sql.Connection; import java.sql.SQLException; import java.sql.Statement; import org.junit.Test; public class Dao1Impl { MyDataSource ds = new MyDataSource(); @Test public void add(){ Connection conn = null; Statement stmt = null; try{ conn = ds.getConnection(); stmt = conn.createStatement(); //com.mysql.jdbc.Connection :MySQL //com.oracle.jdbc.Connection :Oracle //... System.out.println(conn.getClass().getName()); }catch(Exception e){ e.printStackTrace(); }finally{ if(conn!=null){ try { conn.close();//把连接给关了。不应该关,放回池中,怎么放回池中呢?连接池重点所在 } catch (SQLException e) { e.printStackTrace(); } } } } }
相关文章推荐
- JAVAWEB开发之Servlet3.0新特性的使用以及注解的详细使用和自定义注解的方法、动态代理的使用、利用动态代理实现细粒度的权限控制以及类加载和泛型反射
- 动态代理实现数据库连接池功能(代理Connection的close方法)
- 系统性能监控系列1:使用JAVA动态代理实现非侵入式的性能测量方法
- PL/SQL开发中动态SQL的使用方法
- PL/SQL开发中动态SQL的使用方法
- 使用动态代理完成字符集编码过滤器的编写
- PL/SQL开发中动态SQL的使用方法(原文http://dev.yesky.com/187/2029687.shtml)
- 【Java EE 学习 24 下】【注解在数据库开发中的使用】【反射+注解+动态代理在事务中的应用service层】
- JAVA动态代理和方法拦截(使用CGLib实现AOP、方法拦截、委托)
- PL/SQL开发中动态SQL的使用方法[转]
- JavaWeb学习笔记——开发动态WEB资源(四)打印当前使用的是get方法
- PL/SQL开发中动态SQL的使用方法
- PL/SQL开发中动态SQL的使用方法
- 动态代理的实现2-编写可生成代理和插入通告的通用方法
- Java使用注解和动态代理实现方法调用时的日志记录示例
- PL/SQL开发中动态SQL的使用方法
- 在使用 Spring Boot 和 MyBatis 动态切换数据源时遇到的问题以及解决方法
- Java程序开发中代理技术的使用方法
- 02.MyBatis在DAO层开发使用的Mapper动态代理方式
- OJ常用动态数据输入方法 C++简单的栈编写及使用