分享
 
 
 

关于InvocationHandler的学习心得

王朝java/jsp·作者佚名  2006-01-09
窄屏简体版  字體: |||超大  

InvocationHandler is the interface implemented by the invocation handler of a proxy instance.

Each proxy instance has an associated invocation handler. When a method is invoked on a proxy instance, the method invocation is encoded and dispatched to the invoke method of its invocation handler.

实现了InvocationHandler接口的

Object invoke(Object proxy, Method method, Object[] args)

Proxy 代理类

Method 调用的方法

Args 调用方法的参数

的方法的类可以作为InvocationHandler类的参数来构建Proxy类的实例

static Object newProxyInstance(ClassLoader loader, Class[] interfaces, InvocationHandler h)

loader - the class loader to define the proxy class in

interfaces - the list of interfaces for the proxy class to implement

h - the invocation handler to dispatch method invocations to

Example:

ConnectionWrapper(Connection con) {

Class[] interfaces = {

java.sql.Connection.class};

this.connection = (Connection) Proxy.newProxyInstance(

con.getClass().getClassLoader(),

interfaces, this);

m_originConnection = con;

}

作用说明:

当调用被代理的类(Connection)的实例的方法时系统将转到包含代理类(Proxy)的InvocationHandler的invoke方法中去执行相应代码。

这样就可以在不修改代码的前提下为已经存在的类来添加新的功能。

如:(全部代码参看DBConnectionPool.java

public Object invoke(Object proxy, Method m, Object[] args) throws Throwable {

Object obj = null;

if (CLOSE_METHOD_NAME.equals(m.getName())) {

DBConnectionPool.pushConnectionBackToPool(this);

}

else {

obj = m.invoke(m_originConnection, args);

}

if (DEBUG) {

System.out.println(m.getName()+"is invoke!");

}

lastAccessTime = System.currentTimeMillis();

return obj;

}

DBConnectionPool.java

import java.sql.*;

import java.lang.reflect.*;

import java.util.*;

import java.io.*;

public class DBConnectionPool {

private static LinkedList m_notUsedConnection = new LinkedList();

private static HashSet m_usedUsedConnection = new HashSet();

private static String m_url = "";

private static String m_user = "";

private static String m_password = "";

static final boolean DEBUG = true;

static private long m_lastClearClosedConnection = System.currentTimeMillis();

public static long CHECK_CLOSED_CONNECTION_TIME = 4 * 60 * 60 * 1000; //4 hours

static {

initDriver();

}

private DBConnectionPool() {

}

private static void initDriver() {

Driver driver = null;

//load mysql driver

try {

driver = (Driver) Class.forName(

"com.microsoft.jdbc.sqlserver.SQLServerDriver").newInstance();

installDriver(driver);

}

catch (Exception e) {

}

//load postgresql driver

try {

driver = (Driver) Class.forName("org.postgresql.Driver").newInstance();

installDriver(driver);

}

catch (Exception e) {

}

}

public static void installDriver(Driver driver) {

try {

DriverManager.registerDriver(driver);

}

catch (Exception e) {

e.printStackTrace();

}

}

public static synchronized Connection getConnection() {

clearClosedConnection();

while (m_notUsedConnection.size() > 0) {

try {

ConnectionWrapper wrapper = (ConnectionWrapper) m_notUsedConnection.

removeFirst();

if (wrapper.connection.isClosed()) {

continue;

}

m_usedUsedConnection.add(wrapper);

if (DEBUG) {

wrapper.debugInfo = new Throwable("Connection initial statement");

}

return wrapper.connection;

}

catch (Exception e) {

}

}

int newCount = getIncreasingConnectionCount();

LinkedList list = new LinkedList();

ConnectionWrapper wrapper = null;

for (int i = 0; i < newCount; i++) {

wrapper = getNewConnection();

if (wrapper != null) {

list.add(wrapper);

}

}

if (list.size() == 0) {

return null;

}

wrapper = (ConnectionWrapper) list.removeFirst();

m_usedUsedConnection.add(wrapper);

m_notUsedConnection.addAll(list);

list.clear();

return wrapper.connection;

}

private static ConnectionWrapper getNewConnection() {

try {

Connection con = DriverManager.getConnection(m_url, m_user, m_password);

ConnectionWrapper wrapper = new ConnectionWrapper(con);

return wrapper;

}

catch (Exception e) {

e.printStackTrace();

}

return null;

}

static synchronized void pushConnectionBackToPool(ConnectionWrapper con) {

boolean exist = m_usedUsedConnection.remove(con);

if (exist) {

m_notUsedConnection.addLast(con);

}

}

public static int close() {

int count = 0;

if(DEBUG){

System.out.println("it is DBConnection's close()");

}

Iterator iterator = m_notUsedConnection.iterator();

while (iterator.hasNext()) {

try {

( (ConnectionWrapper) iterator.next()).close();

count++;

}

catch (Exception e) {

}

}

m_notUsedConnection.clear();

iterator = m_usedUsedConnection.iterator();

while (iterator.hasNext()) {

try {

ConnectionWrapper wrapper = (ConnectionWrapper) iterator.next();

wrapper.close();

if (DEBUG) {

wrapper.debugInfo.printStackTrace();

}

count++;

}

catch (Exception e) {

}

}

m_usedUsedConnection.clear();

return count;

}

private static void clearClosedConnection() {

long time = System.currentTimeMillis();

//sometimes user change system time,just return

if (time < m_lastClearClosedConnection) {

time = m_lastClearClosedConnection;

return;

}

//no need check very often

if (time - m_lastClearClosedConnection < CHECK_CLOSED_CONNECTION_TIME) {

return;

}

m_lastClearClosedConnection = time;

//begin check

Iterator iterator = m_notUsedConnection.iterator();

while (iterator.hasNext()) {

ConnectionWrapper wrapper = (ConnectionWrapper) iterator.next();

try {

if (wrapper.connection.isClosed()) {

iterator.remove();

}

}

catch (Exception e) {

iterator.remove();

if (DEBUG) {

System.out.println(

"connection is closed, this connection initial StackTrace");

wrapper.debugInfo.printStackTrace();

}

}

}

//make connection pool size smaller if too big

int decrease = getDecreasingConnectionCount();

if (m_notUsedConnection.size() < decrease) {

return;

}

while (decrease-- > 0) {

ConnectionWrapper wrapper = (ConnectionWrapper) m_notUsedConnection.

removeFirst();

try {

wrapper.connection.close();

}

catch (Exception e) {

}

}

}

/**

* get increasing connection count, not just add 1 connection

* @return count

*/

public static int getIncreasingConnectionCount() {

int count = 1;

int current = getConnectionCount();

count = current / 4;

if (count < 1) {

count = 1;

}

return count;

}

/**

* get decreasing connection count, not just remove 1 connection

* @return count

*/

public static int getDecreasingConnectionCount() {

int count = 0;

int current = getConnectionCount();

if (current < 10) {

return 0;

}

return current / 3;

}

public synchronized static void printDebugMsg() {

printDebugMsg(System.out);

}

public synchronized static void printDebugMsg(PrintStream out) {

if (DEBUG == false) {

return;

}

StringBuffer msg = new StringBuffer();

msg.append("debug message in " + DBConnectionPool.class.getName());

msg.append("\r\n");

msg.append("total count is connection pool: " + getConnectionCount());

msg.append("\r\n");

msg.append("not used connection count: " + getNotUsedConnectionCount());

msg.append("\r\n");

msg.append("used connection, count: " + getUsedConnectionCount());

out.println(msg);

Iterator iterator = m_usedUsedConnection.iterator();

while (iterator.hasNext()) {

ConnectionWrapper wrapper = (ConnectionWrapper) iterator.next();

wrapper.debugInfo.printStackTrace(out);

}

out.println();

}

public static synchronized int getNotUsedConnectionCount() {

return m_notUsedConnection.size();

}

public static synchronized int getUsedConnectionCount() {

return m_usedUsedConnection.size();

}

public static synchronized int getConnectionCount() {

return m_notUsedConnection.size() + m_usedUsedConnection.size();

}

public static String getUrl() {

return m_url;

}

public static void setUrl(String url) {

if (url == null) {

return;

}

m_url = url.trim();

}

public static String getUser() {

return m_user;

}

public static void setUser(String user) {

if (user == null) {

return;

}

m_user = user.trim();

}

public static String getPassword() {

return m_password;

}

public static void setPassword(String password) {

if (password == null) {

return;

}

m_password = password.trim();

}

}

class ConnectionWrapper

implements InvocationHandler {

private final static String CLOSE_METHOD_NAME = "close";

public Connection connection = null;

private Connection m_originConnection = null;

static final boolean DEBUG = true;

public long lastAccessTime = System.currentTimeMillis();

Throwable debugInfo = new Throwable("Connection initial statement");

ConnectionWrapper(Connection con) {

Class[] interfaces = {

java.sql.Connection.class};

this.connection = (Connection) Proxy.newProxyInstance(

con.getClass().getClassLoader(),

interfaces, this);

m_originConnection = con;

}

void close() throws SQLException {

if(DEBUG){

System.out.println("it is close method");

}

m_originConnection.close();

}

public Object invoke(Object proxy, Method m, Object[] args) throws Throwable {

Object obj = null;

if (CLOSE_METHOD_NAME.equals(m.getName())) {

DBConnectionPool.pushConnectionBackToPool(this);

}

else {

obj = m.invoke(m_originConnection, args);

}

if (DEBUG) {

System.out.println(m.getName()+"is invoke!");

}

lastAccessTime = System.currentTimeMillis();

return obj;

}

public static void main(String[] args) {

DBConnectionPool.setUrl(

"jdbc:microsoft:sqlserver://192.168.0.76:1433;DatabaseName=sms_misc");

DBConnectionPool.setUser("lhf");

DBConnectionPool.setPassword("lhf");

Connection con = DBConnectionPool.getConnection();

Connection con1 = DBConnectionPool.getConnection();

Connection con2 = DBConnectionPool.getConnection();

//do something with con ...

try {

Statement stmt1 = con.createStatement();

Statement stmt2 = con1.createStatement();

Statement stmt3 = con2.createStatement();

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

// stmt1.executeUpdate("exec testyh");

// stmt2.executeUpdate("update yhgatemt_v3 set yh_status='wait'");

// stmt3.executeUpdate("update yhgatemt_v3 set yh_status='past'");

}

}

catch (Exception e) {

System.out.println("error");

}

try {

System.out.println("Closing con");

con.close();

}

catch (Exception e) {}

try {

System.out.println("Closing con1");

con1.close();

}

catch (Exception e) {}

try {

System.out.println("Closing con2");

con2.close();

}

catch (Exception e) {}

con = DBConnectionPool.getConnection();

con1 = DBConnectionPool.getConnection();

try {

con1.close();

}

catch (Exception e) {}

con2 = DBConnectionPool.getConnection();

DBConnectionPool.printDebugMsg();

}

}

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有