最近用新的一套web框架做项目,有很多常用的包集成在里面。
这里总结一下:
每天总结三个
Commons-Discovery.jar:
使用Apache Commons 的 Discovery 工具包可以实现接口和实现的分离,包括JAR SPI规范的简单实现。
Discovery组件被用以查找可插拔接口的实现实例,它提供了一种通用的实例化这些实现的方式,而且可以管理单例(工厂)的生命周期。本质上来讲,就是定位那些实现了给定Java接口的类,并实例化。除此之外,Discovery还可以用以在给定的classpath中查找并加载资源文件。
Discovery组件在查找所有的实现类的时候需要预先将允许被查找的实现类配置到默认的配置文件中,默认的配置文件为:
/META-INF/services/<YOUR Interface whole name including pkg name>, Discovery将依次加载该文件中配置的允许加载的实现类。
另外接口和实现类的映射关系也可以在一个properties配置文件中定义,格式是:
XXX(接口类名)=XXXimpl(实现类名)
结合面向接口的编程方法,可以实现一个简单的面向服务的调用方式。
ClassLoaders loaders =
ClassLoaders.getAppLoaders(serviceClass, serviceClass.getClass(), false );
DiscoverClass discover = new DiscoverClass(loaders);
// 使用newInstance方式直接产生接口实现的实例
implInstance = (PublicService) discover.newInstance(serviceClass, defaultImpl);
// 也可以使用find的方式返回对应的实现类
implClass = discover.find(serviceClass, configFile, defaultImpl);
/****
完整程序中使用了cglib的 net.sf.cglib.proxy.Enhancer 对返回的实现类进行了增强,可以实现一个简单的面向方面的程序结构:
**/
public class ServiceFinder {
private static final String configFile = " services.properties " ;
private static Enhancer enhancer = new Enhancer();
private ServiceFinder() {
}
public static PublicService lookup(Class serviceClass) {
return lookup(serviceClass, null );
}
public static PublicService lookup(Class serviceClass, String defaultImpl) {
// 创建一个类装入器的实例
ClassLoaders loaders =
ClassLoaders.getAppLoaders(serviceClass, serviceClass.getClass(), false );
DiscoverClass discover = new DiscoverClass(loaders);
PublicService impl = null ;
try {
Class implClass = null ;
// 用DiscoverClass的实例来查找实现类
if (defaultImpl == null || "" .equals(defaultImpl)) {
implClass = discover.find(serviceClass, PropertiyFile.load(configFile));
} else {
implClass = discover.find(serviceClass, configFile, defaultImpl);
}
enhancer.setSuperclass(implClass);
enhancer.setCallback( new ServiceInterceptor(implClass.toString()));
impl = (PublicService) enhancer.create();
// using DiscoverClass instance lookup the impelement
// impl = (PublicService) discover.newInstance(serviceClass, defaultImpl);
} catch (Exception ex) {
ex.printStackTrace();
throw new IllegalArgumentException( " 无法获取指定的服务项 " );
}
return impl;
}
Commons-Pool.jar:(参考 )
ommons Pool组件提供了一整套用于实现对象池化的框架,以及若干种各具特色的对象池实现,可以有效地减少处理对象池化时的工作量,为其它重要的工作留下更多的精力和时间。
恰当地使用对象池化技术,可以有效地减少对象生成和初始化时的消耗,提高系统的运行效率。
PoolableObjectFactory、ObjectPool和ObjectPoolFactory
在Pool组件中,对象池化的工作被划分给了三类对象:
PoolableObjectFactory用于管理被池化的对象的产生、激活、挂起、校验和销毁;
ObjectPool用于管理要被池化的对象的借出和归还,并通知PoolableObjectFactory完成相应的工作;
ObjectPoolFactory则用于大量生成相同类型和设置的ObjectPool。
相应地,使用Pool组件的过程,也大体可以划分成“创立PoolableObjectFactory”、“使用ObjectPool”和可选的“利用ObjectPoolFactory”三种动作。
创立PoolableObjectFactory
Pool组件利用PoolableObjectFactory来照看被池化的对象。ObjectPool的实例在需要处理被池化的对象的产生、激活、挂起、校验和销毁工作时,就会调用跟它关联在一起的PoolableObjectFactory实例的相应方法来操作。
PoolableObjectFactory是在org.apache.commons.pool包中定义的一个接口。实际使用的时候需要利用这个接口的一个具体实现。Pool组件本身没有包含任何一种PoolableObjectFactory实现,需要根据情况自行创立。
创立PoolableObjectFactory的大体步骤是:
创建一个实现了PoolableObjectFactory接口的类。
import org.apache.commons.pool.PoolableObjectFactory;
public class PoolableObjectFactorySample
implements PoolableObjectFactory {
private static int counter = 0;
}
为这个类添加一个Object makeObject()方法。这个方法用于在必要时产生新的对象。
public Object makeObject() throws Exception {
Object obj = String.valueOf(counter++);
System.err.println("Making Object " + obj);
return obj;
}
为这个类添加一个void activateObject(Object obj)方法。这个方法用于将对象“激活”――设置为适合开始使用的状态。
public void activateObject(Object obj) throws Exception {
System.err.println("Activating Object " + obj);
}
为这个类添加一个void passivateObject(Object obj)方法。这个方法用于将对象“挂起”――设置为适合开始休眠的状态。
public void passivateObject(Object obj) throws Exception {
System.err.println("Passivating Object " + obj);
}
为这个类添加一个boolean validateObject(Object obj)方法。这个方法用于校验一个具体的对象是否仍然有效,已失效的对象会被自动交给destroyObject方法销毁
public boolean validateObject(Object obj) {
boolean result = (Math.random() > 0.5);
System.err.println("Validating Object "
+ obj + " : " + result);
return result;
}
为这个类添加一个void destroyObject(Object obj)方法。这个方法用于销毁被validateObject判定为已失效的对象。
public void destroyObject(Object obj) throws Exception {
System.err.println("Destroying Object " + obj);
}
使用ObjectPool
有了合适的PoolableObjectFactory之后,便可以开始请出ObjectPool来与之同台演出了。
ObjectPool是在org.apache.commons.pool包中定义的一个接口,实际使用的时候也需要利用这个接口的一个具体实现。Pool组件本身包含了若干种现成的ObjectPool实现,可以直接利用。如果都不合用,也可以根据情况自行创建。具体的创建方法,可以参看Pool组件的文档和源码。
ObjectPool的使用方法类似这样:
生成一个要用的PoolableObjectFactory类的实例。
PoolableObjectFactory factory = new PoolableObjectFactorySample();
利用这个PoolableObjectFactory实例为参数,生成一个实现了ObjectPool接口的类(例如StackObjectPool)的实例,作为对象池。
ObjectPool pool = new StackObjectPool(factory);
需要从对象池中取出对象时,调用该对象池的Object borrowObject()方法。
Object obj = null;
obj = pool.borrowObject();
需要将对象放回对象池中时,调用该对象池的void returnObject(Object obj)方法。
pool.returnObject(obj);
当不再需要使用一个对象池时,调用该对象池的void close()方法,释放它所占据的资源。
pool.close();
这些操作都可能会抛出异常,需要另外处理。
另外,ObjectPool接口还定义了几个可以由具体的实现决定要不要支持的操作,包括:
void clear()
清除所有当前在此对象池中休眠的对象。
int getNumActive()
返回已经从此对象池中借出的对象的总数。
int getNumIdle()
返回当前在此对象池中休眠的对象的数目。
void setFactory(PoolableObjectFactory factory)
将当前对象池与参数中给定的PoolableObjectFactory相关联。如果在当前状态下,无法完成这一操作,会有一个IllegalStateException异常抛出。
利用ObjectPoolFactory
有时候,要在多处生成类型和设置都相同的ObjectPool。如果在每个地方都重写一次调用相应构造方法的代码,不但比较麻烦,而且日后修改起来,也有所不便。这种时候,正是使用ObjectPoolFactory的时机。
ObjectPoolFactory是一个在org.apache.commons.pool中定义的接口,它定义了一个称为ObjectPool createPool()方法,可以用于大量生产类型和设置都相同的ObjectPool。
Pool组件中,对每一个ObjectPool实现,都有一个对应的ObjectPoolFactory实现。它们相互之间,有一一对应的参数相同的构造方法。使用的时候,只要先用想要的参数和想用的ObjectPoolFactory实例,构造出一个ObjectPoolFactory对象,然后在需要生成ObjectPool的地方,调用这个对象的createPool()方法就可以了。日后无论想要调整所用ObjectPool的参数还是类型,只需要修改这一处,就可以大功告成了。
import org.apache.commons.pool.ObjectPool;
import org.apache.commons.pool.ObjectPoolFactory;
import org.apache.commons.pool.PoolableObjectFactory;
import org.apache.commons.pool.impl.StackObjectPoolFactory;
public class ObjectPoolFactorySample {
public static void main(String[] args) {
Object obj = null;
PoolableObjectFactory factory
= new PoolableObjectFactorySample();
ObjectPoolFactory poolFactory
= new StackObjectPoolFactory(factory);
ObjectPool pool = poolFactory.createPool();
try {
for(long i = 0; i < 100 ; i++) {
System.out.println("== " + i + " ==");
obj = pool.borrowObject();
System.out.println(obj);
pool.returnObject(obj);
}
obj = null;
}
catch (Exception e) {
e.printStackTrace();
}
finally {
try{
if (obj != null) {
pool.returnObject(obj);
}
pool.close();
}
catch (Exception e){
e.printStackTrace();
}
}
}
}
Commons-FileUpload.jar:
FileUpload 使得在你可以在应用和Servlet中容易的加入强大和高性能的文件上传能力。
上传文件到指定的目录。
上传文件到指定的目录,并限定文件大小。
利用 Servlet 来实现文件上传。(参考 )
servlet
package com.zj.sample;
import java.io.File;
import java.io.IOException;
import java.util.Iterator;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
@SuppressWarnings("serial")
public class Upload extends HttpServlet {
private String uploadPath = "D:\\temp"; // 上传文件的目录
private String tempPath = "d:\\temp\\buffer\\"; // 临时文件目录
File tempPathFile;
@SuppressWarnings("unchecked")
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException {
try {
// Create a factory for disk-based file items
DiskFileItemFactory factory = new DiskFileItemFactory();
// Set factory constraints
factory.setSizeThreshold(4096); // 设置缓冲区大小,这里是4kb
factory.setRepository(tempPathFile);// 设置缓冲区目录
// Create a new file upload handler
ServletFileUpload upload = new ServletFileUpload(factory);
// Set overall request size constraint
upload.setSizeMax(4194304); // 设置最大文件尺寸,这里是4MB
List<FileItem> items = upload.parseRequest(request);// 得到所有的文件
Iterator<FileItem> i = items.iterator();
while (i.hasNext()) {
FileItem fi = (FileItem) i.next();
String fileName = fi.getName();
if (fileName != null) {
File fullFile = new File(fi.getName());
File savedFile = new File(uploadPath, fullFile.getName());
fi.write(savedFile);
}
}
System.out.print("upload succeed");
} catch (Exception e) {
// 可以跳转出错页面
e.printStackTrace();
}
}
public void init() throws ServletException {
File uploadFile = new File(uploadPath);
if (!uploadFile.exists()) {
uploadFile.mkdirs();
}
File tempPathFile = new File(tempPath);
if (!tempPathFile.exists()) {
tempPathFile.mkdirs();
}
}
}
html
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=GB18030">
<title>File upload</title>
</head>
<body>
// action="fileupload"对应web.xml中<servlet-mapping>中<url-pattern>的设置.
<form name="myform" action="fileupload" method="post"
enctype="multipart/form-data">
File:<br>
<input type="file" name="myfile"><br>
<br>
<input type="submit" name="submit" value="Commit">
</form>
</body>
</html>
web.xml
<servlet> <servlet-name>Upload</servlet-name> <servlet-class>com.zj.sample.Upload</servlet-class> </servlet> <servlet-mapping> <servlet-name>Upload</servlet-name> <url-pattern>/fileupload</url-pattern> </servlet-mapping>