在做爬虫管理时,为了避免重复的打开/关闭 webclinet ,使得一次创建的webclient能被重复利用。接触到了这一工具
jar包下载地址:
http://commons.apache.org/proper/commons-pool/download_pool.cgi
简要介绍:
该项目提供了对象池解决方案,也就是一种对象一次创建多次使用。例如提高像 数据库连接,socket通信等大对象的调用效率。
三大核心接口:
ObjectPool : 定义了对象池的功能(如:存取,过期等)
PooledObjectFactory : 定义了被池化的对象的创建,初始化,激活,钝化及销毁等功能
PooledObject : 定义了池化的对象的一些附加信息(创建时间,池中状态等)
大致工作流程:由PooledObjectFactory创建对象,经过PooledObject包装,最后放入ObjectPool中以供使用。
测试小demo:
大致项目结构
package emp.entity;
public class Employee {
private String name;
private String password;
public Employee() {
super();
}
public Employee(String name, String password) {
super();
this.name = name;
this.password = password;
}
public void dosmt(String str){
System.out.println(this.name+str);
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
package emp.entity;
import org.apache.tomcat.dbcp.pool2.BasePooledObjectFactory;
import org.apache.tomcat.dbcp.pool2.PooledObject;
import org.apache.tomcat.dbcp.pool2.impl.DefaultPooledObject;
public class EmpFactory extends BasePooledObjectFactory<Employee> {
@Override
public Employee create() throws Exception {
return new Employee("CL", "123");
}
@Override
public PooledObject<Employee> wrap(Employee emp) {
return new DefaultPooledObject<Employee>(emp);
}
}
package emp.util;
import java.util.NoSuchElementException;
import org.apache.tomcat.dbcp.pool2.ObjectPool;
import org.apache.tomcat.dbcp.pool2.impl.GenericObjectPool;
import emp.entity.EmpFactory;
import emp.entity.Employee;
public class EmpUtil {
private ObjectPool<Employee> poll = new GenericObjectPool<Employee>(new EmpFactory());
private EmpUtil(){}
private static EmpUtil instance = new EmpUtil();
public static EmpUtil getInstance(){
return instance;
}
public void dowork(){
Employee emp1 = new Employee("CL","123");
System.out.println("未使用EmpFactory生成的对象地址:"+emp1);
emp1.dosmt("在码代码中,勿扰!");
Employee emp2 = null;
try {
emp2 = poll.borrowObject();
System.out.println("使用EmpFactory生成的对象地址:"+emp2);
emp2.dosmt("在码代码中,勿扰!");
} catch (NoSuchElementException e) {
e.printStackTrace();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (Exception e) {
throw new RuntimeException("Unable to borrow buffer from pool" + e.toString());
}finally{
try {
if(emp2 != null){
poll.returnObject(emp2);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
package emp.action;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import emp.entity.Employee;
import emp.util.EmpUtil;
public class Empaction extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
EmpUtil.getInstance().dowork();
Employee emp = new Employee("CL","123");
System.out.println("emp的地址"+emp);
emp.dosmt("在休息中!勿扰");
System.out.println("===================我是分割线===================");
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
当外面的请求过来后,Empaction会分别在控制台打印EmpUtil内的对象地址以及new出来的对象地址:
其中EmpUtil有两个对象,一个是调用EmpFactory中生成在对象池中的对象,另一个是new出来的。
这样来验证Apache commons-pool是否能复用对象
控制台输出结果如下:
结果一目了然,在池中的对象能够被我循环的调用。