commons-pool源码分析总结

来源:互联网 发布:武汉大学网络管理中心 编辑:程序博客网 时间:2024/05/16 06:44

不论进行什么程序或者框架的源码分析,总是要建立在使用它的基础之上的,当我们使用了它,然后才会有好奇心和动力去分析它是怎么样实现的。

其实有很少的编程人员会直接使用commons-pool,但是常常在我们的项目中需要使用到它。我是如何开始接触commons-pool的呢?这是在我学习javaEE开发的时候接触的,当时候的时候需要使用dbcp作为数据库连接池,然而dbcp依赖于commons-pool来缓存连接,本人又是一个喜欢研究的人,而且喜欢对一个东西有很深的了解之后,然后将它的作用发挥到最大。

1.commons-pool提供了什么样的功能

在前面开始提到了commons-dbcp使用到了commons-pool,那么commons-dbcp为什么要使用它呢?

commons-dbcp提供给开发者一个可用的数据库连接池,顾名思义commons-dbcp缓存了很多数据库的连接。难么这个缓存的功能是在dbcp中实现的吗?不是的,其实dbcp中的数据库的缓存的功能是有commons-pool来提供的,这也就说明了commons-pool具有缓存对象的功能。

为什么需要缓存对象?这是因为对象的创建和释放都是一个很耗费时间和空间的过程,所有如果只是在需要的对象的创建对象,那么使用该对象的程序或者用户就会等待较长的时间。特别是对于需要频繁创建和销毁某类对象、或者需要频繁访问修改的应用程序来说尤为重要(当然这整个过程都是建立在可复用的对象的基础上)。

2. 缓存的基本原理

既然提到了commons-pool提供了对象缓存的功能,那么什么是对象缓存呢,以及什么是缓存呢?我们知道对象的创建的流程是:分配内存空间、对象初始化、对象注册到对象数上、返回对象的引用等过程。如果没有进行对象的缓存,那么每次需要一个对象的时候就需要经历上面的步骤,如果此类操作比较频繁,那么就会大大的降低程序的性能。

3. commons-pool缓存的实现

  • commons-pool中的泛型编程
    在java中如果要使得一段程序或者一个框架是可复用的,那么泛型编程就必不可少。泛型编程所谓的意思就是该段程序或者是框架所针对的对象的类型没有明确的限制,比如说大家常常使用的HashMap
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工作原理解析
    这里写图片描述

其实commons-pool的工作原理很简单,泛型+工厂模式+缓存链表。泛型,可以使得框架可以缓存多种对象类型;工厂模式,用户通过继承工厂接口,并向缓冲池注册自定义的工厂类,使得框架的可扩展性更强; 缓存链表,通过链表的方式缓存已经生成好的对象。

4. 总结

  • 其实缓存的原理都是一样的,只是各自的实现的方式大同小异,只要我们了解了其中的原理之后,就能更好的去阅读源代码。
  • commons-pool提供了两种缓存服务GenericKeyedObjectPool(K,V带键值对的) 、GenericObjectPool(T,只有值的),虽然功能上有些差别,但是实现原理都是一样的。
0 0
原创粉丝点击