FTPClient与commons-pool2

设计模式

FTPClient与commons-pool2整合过程中涉及到的设计模式有:工厂方法模式、单例模式。

工厂方法模式

工厂方法模式定义了一个创建对象的接口,但由子类决定要实例化的类是哪一个,工厂方法让实例化推迟到子类。当需要增加一个新的产品时,只需要增加一个具体的产品类和与之对应的具体工厂即可,无须修改原有系统。但是由于每新增一个新产品时就需要增加两个类,这样会导致系统的复杂度增加。

FTPClient与commons-pool2_第1张图片

单例模式

单例模式确保一个类只有一个实例,并提供一个全局访问点。

单例模式有五种实现方法:双重校验锁、枚举、静态内部类、恶汉、懒汉。

在这里选择静态内部类。

代码

主要有FTPClientFactory和FTPClientUtil两个类

使用commons-pool2
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.pool2.BasePooledObjectFactory;
import org.apache.commons.pool2.PooledObject;
import org.apache.commons.pool2.impl.DefaultPooledObject;

import java.util.Properties;

/**
 * Created by udbwcso on 2016/3/14.
 */
public class FTPClientFactory extends BasePooledObjectFactory<FTPClient> {

    private final String host;
    private final int port;
    private final String username;
    private final String password;

    public FTPClientFactory(final String host, final int port, final String username, final String password){
        this.host = host;
        this.port = port;
        this.username = username;
        this.password = password;
    }

    public FTPClientFactory(Properties properties){
        this.host = properties.getProperty("host");
        this.port = Integer.parseInt(properties.getProperty("port"));
        this.username = properties.getProperty("username");
        this.password = properties.getProperty("password");
    }

    /**
     * Creates an object instance, to be wrapped in a {@link PooledObject}.
     * <p>This method <strong>must</strong> support concurrent, multi-threaded
     * activation.</p>
     *
     * @return an instance to be served by the pool
     * @throws Exception if there is a problem creating a new instance,
     *                   this will be propagated to the code requesting an object.
     */
    public FTPClient create() throws Exception {
        FTPClient client = new FTPClient();
        client.connect(host, port);
        client.login(username, password);
        return client;
    }

    /**
     * Wrap the provided instance with an implementation of
     * {@link PooledObject}.
     *
     * @param obj the instance to wrap
     * @return The provided instance, wrapped by a {@link PooledObject}
     */
    public PooledObject<FTPClient> wrap(FTPClient obj) {
        return new DefaultPooledObject<FTPClient>(obj);
    }

    /**
     * destroy object
     */
    @Override
    public void destroyObject(PooledObject<FTPClient> p) throws Exception {
        FTPClient ftpClient = p.getObject();
        ftpClient.logout();
        ftpClient.disconnect();
    }
}

工具类
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.pool2.ObjectPool;
import org.apache.commons.pool2.impl.GenericObjectPool;

import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

/**
 * Created by udbwcso on 2016/3/15.
 */
public class FTPClientUtil {

    private static final String FTP_PROPERTIES = "/ftp.properties";

    private FTPClientUtil(){
    }

    public static FTPClientUtil getInstance(){
        return SingletonHolder.instance;
    }

    /**
     * Returns the pathname of the current working directory.
     * @return
     */
    public String getWorkingDirectory() throws Exception {
        FTPClient client = getClientPool().borrowObject();
        String workingDir = client.printWorkingDirectory();
        getClientPool().returnObject(client);
        return workingDir;
    }

    private ObjectPool<FTPClient> getClientPool(){
        return SingletonHolder.POOL;
    }

    private static class SingletonHolder {

        private static final ObjectPool<FTPClient> POOL;

        static {
            InputStream resourceAsStream = FTPClientUtil.class.getResourceAsStream(FTP_PROPERTIES);
            Properties p = null;
            if (resourceAsStream != null) {
                p = new Properties();
                try {
                    p.load(resourceAsStream);
                } catch (IOException e) {
                } finally {
                    try {
                        resourceAsStream.close();
                    } catch (IOException e) {
                        // Ignored
                    }
                }
            }
            POOL = new GenericObjectPool<FTPClient>(new FTPClientFactory(p));
        }

        private static FTPClientUtil instance = new FTPClientUtil();

    }

}

目前只有获取工作目录的方法,有待后续开发。

https://github.com/udbwcso/uftp

你可能感兴趣的:(FTPClient与commons-pool2)