标签:
不论进行什么程序或者框架的源码分析,总是要建立在使用它的基础之上的,当我们使用了它,然后才会有好奇心和动力去分析它是怎么样实现的。
其实有很少的编程人员会直接使用commons-pool,但是常常在我们的项目中需要使用到它。我是如何开始接触commons-pool的呢?这是在我学习javaEE开发的时候接触的,当时候的时候需要使用dbcp作为数据库连接池,然而dbcp依赖于commons-pool来缓存连接,本人又是一个喜欢研究的人,而且喜欢对一个东西有很深的了解之后,然后将它的作用发挥到最大。
在前面开始提到了commons-dbcp使用到了commons-pool,那么commons-dbcp为什么要使用它呢?
commons-dbcp提供给开发者一个可用的数据库连接池,顾名思义commons-dbcp缓存了很多数据库的连接。难么这个缓存的功能是在dbcp中实现的吗?不是的,其实dbcp中的数据库的缓存的功能是有commons-pool来提供的,这也就说明了commons-pool具有缓存对象的功能。
为什么需要缓存对象?这是因为对象的创建和释放都是一个很耗费时间和空间的过程,所有如果只是在需要的对象的创建对象,那么使用该对象的程序或者用户就会等待较长的时间。特别是对于需要频繁创建和销毁某类对象、或者需要频繁访问修改的应用程序来说尤为重要(当然这整个过程都是建立在可复用的对象的基础上)。
既然提到了commons-pool提供了对象缓存的功能,那么什么是对象缓存呢,以及什么是缓存呢?我们知道对象的创建的流程是:分配内存空间、对象初始化、对象注册到对象数上、返回对象的引用等过程。如果没有进行对象的缓存,那么每次需要一个对象的时候就需要经历上面的步骤,如果此类操作比较频繁,那么就会大大的降低程序的性能。
public class HashMap<K,V> extends AbstractMap<K,V>
implements Map<K,V>, Cloneable, Serializable {
private static final long serialVersionUID = 362498820763181265L;
/*
* Implementation notes.
*
/
......
上面的HashMap中的K和V,没有明确的指定K和V的类型,这样就可以使得HashMap能使用多种基础的数据类型或者是自定义的类作为其的K或者V。这样就给了HashMap更灵活的使用。
而在commons-pool中则是
// 对象工厂类(T为对象的类型)
public interface PooledObjectFactory<T> {
// 创建一个对象(T为对象的类型)
PooledObject<T> makeObject() throws Exception;
// 销毁一个对象(T为对象的类型)
void destroyObject(PooledObject<T> p) throws Exception;
......
下面是一个小例子
UserInfo.java 这是我们需要缓存的对象的类型
package mh.test;
public class UserInfo {
private String name;
private int age;
public UserInfo() {
// TODO Auto-generated constructor stub
}
public UserInfo(String name, int age) {
// TODO Auto-generated constructor stub
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
// TODO Auto-generated method stub
return "用户名:"+this.name+",年龄:"+this.age;
}
}
UserFactory.java 缓存对象的生产工厂,必须继承commons-pool的工厂类
package mh.test;
import org.apache.commons.pool2.PooledObject;
import org.apache.commons.pool2.PooledObjectFactory;
import org.apache.commons.pool2.impl.DefaultPooledObject;
public class UserFactory implements PooledObjectFactory<UserInfo>{
@Override
public PooledObject<UserInfo> makeObject() throws Exception {
// TODO Auto-generated method stub
System.out.println("创建一个新的对象");
return new DefaultPooledObject<UserInfo>(new UserInfo());
}
@Override
public void destroyObject(PooledObject<UserInfo> p) throws Exception {
// TODO Auto-generated method stub
UserInfo user = p.getObject();
System.out.println("销毁对象"+user.toString());
user = null;
}
@Override
public boolean validateObject(PooledObject<UserInfo> p) {
// TODO Auto-generated method stub
if(p.getObject() instanceof UserInfo){
System.out.println("是一个合法的对象");
return true;
}
System.out.println("是一个非法的对象");
return false;
}
@Override
public void activateObject(PooledObject<UserInfo> p) throws Exception {
// TODO Auto-generated method stub
System.out.println("重新初始化对象");
}
@Override
public void passivateObject(PooledObject<UserInfo> p) throws Exception {
// TODO Auto-generated method stub
UserInfo user = p.getObject();
System.out.println("对象已经被归还:"+user.toString());
}
}
TestPool .java 如何使用commons-pool
package mh.test;
import org.apache.commons.pool2.impl.GenericObjectPool;
public class TestPool {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
GenericObjectPool<UserInfo> pool = new GenericObjectPool<UserInfo>(new UserFactory());
try {
UserInfo user = pool.borrowObject();
user.setAge(10);
user.setName("mh");
System.out.println(user.toString());
pool.returnObject(user);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
其实commons-pool的工作原理很简单,泛型+工厂模式+缓存链表。泛型,可以使得框架可以缓存多种对象类型;工厂模式,用户通过继承工厂接口,并向缓冲池注册自定义的工厂类,使得框架的可扩展性更强; 缓存链表,通过链表的方式缓存已经生成好的对象。
标签:
原文地址:http://blog.csdn.net/m47838704/article/details/51354807