欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java?GenericObjectPool?對象池化技術之SpringBoot?sftp?連接池工具類詳解

 更新時間:2023年04月07日 11:05:32   作者:VipSoft  
這篇文章主要介紹了Java?GenericObjectPool?對象池化技術之SpringBoot?sftp?連接池工具類詳解,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下

Java BasePooledObjectFactory 對象池化技術

通常一個對象創(chuàng)建、銷毀非常耗時的時候,我們不會頻繁的創(chuàng)建和銷毀它,而是考慮復用。復用對象的一種做法就是對象池,將創(chuàng)建好的對象放入池中維護起來,下次再用的時候直接拿池中已經創(chuàng)建好的對象繼續(xù)用,這就是池化的思想。

Apache Commons Pool是一個對象池的框架,他提供了一整套用于實現(xiàn)對象池化的API。它提供了三種對象池:GenericKeyedObjectPool,SoftReferenceObjectPool和GenericObjectPool,其中GenericObjectPool是我們最常用的對象池,內部實現(xiàn)也最復雜。

GenericObjectPool

GenericObjectPool 是一個通用對象池框架,我們可以借助它實現(xiàn)一個健壯的對象池,UML圖如下所示:

GenericObjectPool 實現(xiàn)了ObjectPool接口,而ObjectPool就是對象池的核心接口,它定義了一個對象池應該實現(xiàn)的行為。

public interface ObjectPool<T> extends Closeable {
    /**
     * 從池中借走到一個對象
     */
    T borrowObject() throws Exception, NoSuchElementException, IllegalStateException;
    /**
     * 把對象歸還給對象池
     */
    void returnObject(T var1) throws Exception;
    /**
     * 驗證對象的有效性
     */
    void invalidateObject(T var1) throws Exception;

    /**
     * 往池中添加一個對象
     */
    void addObject() throws Exception, IllegalStateException, UnsupportedOperationException;
    /**
     * 返回對象池中有多少對象是空閑的,也就是能夠被借走的對象的數(shù)量。
     */
    int getNumIdle();
    /**
     * 返回對象池中有對象對象是活躍的,也就是已經被借走的,在使用中的對象的數(shù)量。
     */
    int getNumActive();
    /**
     * 清理對象池。注意是清理不是清空,該方法要求的是,清理所有空閑對象,釋放相關資源。
     */
    void clear() throws Exception, UnsupportedOperationException;
    /**
     * 關閉對象池。這個方法可以達到清空的效果,清理所有對象以及相關資源。
     */
    void close();
}

BasePooledObjectFactory

Java BasePooledObjectFactory 對象池化技術

使用GenericObjectPool只需要創(chuàng)建一個對象工廠類,繼承BasePooledObjectFactory并重寫它的create()destroyObject()
如下文中的:SftpPool.java

public interface PooledObjectFactory<T> {
    /**
     * 創(chuàng)建一個可由池提供服務的實例,并將其封裝在由池管理的PooledObject中。
     */
    PooledObject<T> makeObject() throws Exception;

    /**
     *  銷毀池不再需要的實例
     */
    void destroyObject(PooledObject<T> var1) throws Exception;

    /**
     * 確保實例可以安全地由池返回
     */
    boolean validateObject(PooledObject<T> var1);

    /**
     * 重新初始化池返回的實例
     */
    void activateObject(PooledObject<T> var1) throws Exception;

    /**
     * 取消初始化要返回到空閑對象池的實例
     */
    void passivateObject(PooledObject<T> var1) throws Exception;
}

配置類GenericObjectPoolConfig

GenericObjectPoolConfig是封裝GenericObject池配置的簡單“結構”,此類不是線程安全的;它僅用于提供創(chuàng)建池時使用的屬性。大多數(shù)情況,可以使用GenericObjectPoolConfig提供的默認參數(shù)就可以滿足日常的需求。

工作原理流程

  • 構造方法
    當我們執(zhí)行構造方法時,主要工作就是創(chuàng)建了一個存儲對象的LinkedList類型容器,也就是概念意義上的“池”
  • 從對象池中獲取對象
    獲取池中的對象是通過borrowObject()命令,源碼比較復雜,簡單而言就是去LinkedList中獲取一個對象,如果不存在的話,要調用構造方法中第一個參數(shù)Factory工廠類的makeObject()方法去創(chuàng)建一個對象再獲取,獲取到對象后要調用validateObject方法判斷該對象是否是可用的,如果是可用的才拿去使用。LinkedList容器減一
  • 歸還對象到線程池
    簡單而言就是先調用validateObject方法判斷該對象是否是可用的,如果可用則歸還到池中,LinkedList容器加一,如果是不可以的則調用destroyObject方法進行銷毀

上面三步就是最簡單的流程,由于取和還的流程步驟都在borrowObject和returnObject方法中固定的,所以我們只要重寫Factory工廠類的makeObject()和validateObject以及destroyObject方法即可實現(xiàn)最簡單的池的管理控制,通過構造方法傳入該Factory工廠類對象則可以創(chuàng)建最簡單的對象池管理類。這算是比較好的解耦設計模式,借和還的流程如下圖所示:

使用Demo

<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-pool2</artifactId>
    <version>2.7.0</version>
</dependency>

<!-- https://mvnrepository.com/artifact/com.jcraft/jsch -->
<dependency>
    <groupId>com.jcraft</groupId>
    <artifactId>jsch</artifactId>
    <version>0.1.55</version>
</dependency>
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>vipsoft-parent</artifactId>
        <groupId>com.vipsoft.boot</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>vipsoft-sftp</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencies>

        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-pool2</artifactId>
            <version>2.7.0</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/com.jcraft/jsch -->
        <dependency>
            <groupId>com.jcraft</groupId>
            <artifactId>jsch</artifactId>
            <version>0.1.55</version>
        </dependency>

        <dependency>
            <groupId>org.eclipse.paho</groupId>
            <artifactId>org.eclipse.paho.client.mqttv3</artifactId>
            <version>1.2.5</version>
        </dependency>


        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.3.6</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

application.yaml

server:
  port: 8088
  application:
    name: sftp Demo


sftp:
  host: 172.16.3.88 # 服務器ip
  port: 22 # ssh端口
  username: root # 用戶名
  password: root # 密碼
  # 連接池參數(shù)
  pool:
    max-total: 10
    max-idle: 10
    min-idle: 5

SftpPoolException.java

package com.vipsoft.sftp.exception;


/**
 * sftp連接池異常
 */
public class SftpPoolException extends RuntimeException {

    private static final long serialVersionUID = 1L;

    /**
     * Constructs a new runtime exception with {@code null} as its
     * detail message.  The cause is not initialized, and may subsequently be
     * initialized by a call to {@link #initCause}.
     */
    public SftpPoolException() {
    }

    /**
     * Constructs a new runtime exception with the specified detail message.
     * The cause is not initialized, and may subsequently be initialized by a
     * call to {@link #initCause}.
     *
     * @param message the detail message. The detail message is saved for
     *                later retrieval by the {@link #getMessage()} method.
     */
    public SftpPoolException(String message) {
        super(message);
    }

    /**
     * Constructs a new runtime exception with the specified detail message and
     * cause.  <p>Note that the detail message associated with
     * {@code cause} is <i>not</i> automatically incorporated in
     * this runtime exception's detail message.
     *
     * @param message the detail message (which is saved for later retrieval
     *                by the {@link #getMessage()} method).
     * @param cause   the cause (which is saved for later retrieval by the
     *                {@link #getCause()} method).  (A <tt>null</tt> value is
     *                permitted, and indicates that the cause is nonexistent or
     *                unknown.)
     * @since 1.4
     */
    public SftpPoolException(String message, Throwable cause) {
        super(message, cause);
    }

    /**
     * Constructs a new runtime exception with the specified cause and a
     * detail message of <tt>(cause==null ? null : cause.toString())</tt>
     * (which typically contains the class and detail message of
     * <tt>cause</tt>).  This constructor is useful for runtime exceptions
     * that are little more than wrappers for other throwables.
     *
     * @param cause the cause (which is saved for later retrieval by the
     *              {@link #getCause()} method).  (A <tt>null</tt> value is
     *              permitted, and indicates that the cause is nonexistent or
     *              unknown.)
     * @since 1.4
     */
    public SftpPoolException(Throwable cause) {
        super(cause);
    }

    /**
     * Constructs a new runtime exception with the specified detail
     * message, cause, suppression enabled or disabled, and writable
     * stack trace enabled or disabled.
     *
     * @param message            the detail message.
     * @param cause              the cause.  (A {@code null} value is permitted,
     *                           and indicates that the cause is nonexistent or unknown.)
     * @param enableSuppression  whether or not suppression is enabled
     *                           or disabled
     * @param writableStackTrace whether or not the stack trace should
     *                           be writable
     * @since 1.7
     */
    public SftpPoolException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
        super(message, cause, enableSuppression, writableStackTrace);
    }

}

config

SftpConfig.java

package com.vipsoft.sftp.config;

import com.vipsoft.sftp.pool.SftpFactory;
import com.vipsoft.sftp.pool.SftpPool;
import com.vipsoft.sftp.utils.SftpUtil;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
@EnableConfigurationProperties(SftpProperties.class)
public class SftpConfig {
    // 工廠
    @Bean
    public SftpFactory sftpFactory(SftpProperties properties) {
        return new SftpFactory(properties);
    }

    // 連接池
    @Bean
    public SftpPool sftpPool(SftpFactory sftpFactory) {
        return new SftpPool(sftpFactory);
    }

    // 輔助類
    @Bean
    public SftpUtil sftpUtil(SftpPool sftpPool) {
        return new SftpUtil(sftpPool);
    }
}

SftpProperties.java

package com.vipsoft.sftp.config;

import com.jcraft.jsch.ChannelSftp;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import org.springframework.boot.context.properties.ConfigurationProperties;

@ConfigurationProperties(prefix = "sftp")
public class SftpProperties {

    private String host;
    private int port = 22;
    private String username = "root";
    private String password = "root";
    private Pool pool = new Pool();

    public String getHost() {
        return host;
    }

    public void setHost(String host) {
        this.host = host;
    }

    public int getPort() {
        return port;
    }

    public void setPort(int port) {
        this.port = port;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public Pool getPool() {
        return pool;
    }

    public void setPool(Pool pool) {
        this.pool = pool;
    }

    public static class Pool extends GenericObjectPoolConfig<ChannelSftp> {

        private int maxTotal = DEFAULT_MAX_TOTAL;
        private int maxIdle = DEFAULT_MAX_IDLE;
        private int minIdle = DEFAULT_MIN_IDLE;

        public Pool() {
            super();
        }
        @Override
        public int getMaxTotal() {
            return maxTotal;
        }
        @Override
        public void setMaxTotal(int maxTotal) {
            this.maxTotal = maxTotal;
        }
        @Override
        public int getMaxIdle() {
            return maxIdle;
        }
        @Override
        public void setMaxIdle(int maxIdle) {
            this.maxIdle = maxIdle;
        }
        @Override
        public int getMinIdle() {
            return minIdle;
        }
        @Override
        public void setMinIdle(int minIdle) {
            this.minIdle = minIdle;
        }
    }
}

Pool

SftpFactory.java

package com.vipsoft.sftp.pool;

import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;
import com.vipsoft.sftp.config.SftpProperties;
import com.vipsoft.sftp.exception.SftpPoolException;
import org.apache.commons.pool2.BasePooledObjectFactory;
import org.apache.commons.pool2.PooledObject;
import org.apache.commons.pool2.impl.DefaultPooledObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Properties;

public class SftpFactory extends BasePooledObjectFactory<ChannelSftp> {

    private  final Logger logger = LoggerFactory.getLogger(this.getClass());

    private SftpProperties properties;

    public SftpProperties getProperties() {
        return properties;
    }

    public void setProperties(SftpProperties properties) {
        this.properties = properties;
    }

    public SftpFactory(SftpProperties properties) {
        this.properties = properties;
    }

    @Override
    public ChannelSftp create() {
        try {
            JSch jsch = new JSch();
            Session sshSession = jsch.getSession(properties.getUsername(), properties.getHost(), properties.getPort());
            sshSession.setPassword(properties.getPassword());
            Properties sshConfig = new Properties();
            sshConfig.put("StrictHostKeyChecking", "no");
            sshSession.setConfig(sshConfig);
            sshSession.connect();
            ChannelSftp channel = (ChannelSftp) sshSession.openChannel("sftp");
            channel.connect();
            return channel;
        } catch (JSchException e) {
            throw new SftpPoolException("連接sfpt失敗", e);
        }
    }

    @Override
    public PooledObject<ChannelSftp> wrap(ChannelSftp channelSftp) {
        return new DefaultPooledObject<>(channelSftp);
    }

    // 銷毀對象
    @Override
    public void destroyObject(PooledObject<ChannelSftp> p) {
        ChannelSftp channelSftp = p.getObject();
        channelSftp.disconnect();
    }
}

SftpPool.java

package com.vipsoft.sftp.pool;

import com.jcraft.jsch.ChannelSftp;
import org.apache.commons.pool2.impl.GenericObjectPool;

public class SftpPool<T> extends GenericObjectPool<ChannelSftp> {

    public SftpPool(SftpFactory factory) {
        super(factory,factory.getProperties().getPool());
    }

    /**
     * 獲取一個sftp連接對象
     * @return sftp連接對象
     */
    @Override
    public ChannelSftp borrowObject() throws Exception {
        return super.borrowObject();
    }

    /**
     * 歸還一個sftp連接對象
     * @param channelSftp sftp連接對象
     */
    @Override
    public void returnObject(ChannelSftp channelSftp) {
        if (channelSftp!=null) {
            super.returnObject(channelSftp);
        }
    }

}

Utils

ByteUtil.java

package com.vipsoft.sftp.utils;

import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.SftpException;
import com.vipsoft.sftp.exception.SftpPoolException;
import com.vipsoft.sftp.pool.SftpPool;

import java.io.InputStream;

public class SftpUtil {

    private SftpPool pool;

    public SftpUtil(SftpPool pool) {
        this.pool = pool;
    }

    /**
     * 下載文件
     *
     * @param dir  遠程目錄
     * @param name 遠程文件名
     * @return 文件字節(jié)數(shù)組
     */
    public byte[] download(String dir, String name) {
        ChannelSftp sftp = null;
        try {
            sftp = pool.borrowObject();
            sftp.cd(dir);
            InputStream in = sftp.get(name);
            return ByteUtil.inputStreamToByteArray(in);
        } catch (Exception e) {
            throw new SftpPoolException("sftp下載文件出錯", e);
        } finally {
            pool.returnObject(sftp);
        }
    }

    /**
     * 上傳文件
     *
     * @param dir  遠程目錄
     * @param name 遠程文件名
     * @param in   輸入流
     */
    public void upload(String dir, String name, InputStream in) {
        ChannelSftp sftp = null;
        try {
            sftp = pool.borrowObject();
            mkdirs(sftp, dir);
            sftp.cd(dir);
            sftp.put(in, name);
        } catch (Exception e) {
            throw new SftpPoolException("sftp上傳文件出錯", e);
        } finally {
            pool.returnObject(sftp);
        }
    }

    /**
     * 刪除文件
     *
     * @param dir  遠程目錄
     * @param name 遠程文件名
     */
    public void delete(String dir, String name) {
        ChannelSftp sftp = null;
        try {
            sftp = pool.borrowObject();
            sftp.cd(dir);
            sftp.rm(name);
        } catch (Exception e) {
            throw new SftpPoolException("sftp刪除文件出錯", e);
        } finally {
            pool.returnObject(sftp);
        }
    }

    /**
     * 遞歸創(chuàng)建多級目錄
     *
     * @param dir 多級目錄
     */
    private void mkdirs(ChannelSftp sftp, String dir) {
        String[] folders = dir.split("/");
        try {
            sftp.cd("/");
            for (String folder : folders) {
                if (folder.length() > 0) {
                    try {
                        sftp.cd(folder);
                    } catch (Exception e) {
                        sftp.mkdir(folder);
                        sftp.cd(folder);
                    }
                }
            }
        } catch (SftpException e) {
            throw new SftpPoolException("sftp創(chuàng)建目錄出錯", e);
        }
    }
}

Test

SftpTest.java

package com.vipsoft.sftp;

import com.vipsoft.sftp.utils.SftpUtil;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
public class SftpTest {

    @Autowired
    private SftpUtil sftpUtil;

    @Test
    void downloadTest() {
        byte[] dockerfiles = sftpUtil.download("/opt/demo/", "Dockerfile");
        System.out.println("FileSize =>" + dockerfiles.length);
    }

}

到此這篇關于Java GenericObjectPool 對象池化技術--SpringBoot sftp 連接池工具類的文章就介紹到這了,更多相關Java 對象池GenericObjectPool內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • Spring入門基礎之依賴注入

    Spring入門基礎之依賴注入

    Idea中使用@Autowire注解會出現(xiàn)提示黃線,強迫癥患者看著很難受,使用構造器注入或者setter方法注入后可解決,下面我們一起來看看
    2022-07-07
  • Java數(shù)據封裝樹形結構代碼實例

    Java數(shù)據封裝樹形結構代碼實例

    這篇文章主要介紹了Java數(shù)據封裝樹形結構代碼實例,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-01-01
  • 一文帶你揭秘SpringMvc參數(shù)值映射

    一文帶你揭秘SpringMvc參數(shù)值映射

    這篇文章主要給大家介紹了關于SpringMvc參數(shù)值映射的相關資料,文中通過實例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2022-01-01
  • Maven直接依賴、間接依賴、依賴沖突、依賴仲裁的實現(xiàn)

    Maven直接依賴、間接依賴、依賴沖突、依賴仲裁的實現(xiàn)

    本文主要介紹了Maven直接依賴、間接依賴、依賴沖突、依賴仲裁的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2023-09-09
  • SpringBoot@Aspect 打印訪問請求和返回數(shù)據方式

    SpringBoot@Aspect 打印訪問請求和返回數(shù)據方式

    這篇文章主要介紹了SpringBoot@Aspect 打印訪問請求和返回數(shù)據方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-09-09
  • Java實現(xiàn)畫圖的詳細步驟(完整代碼)

    Java實現(xiàn)畫圖的詳細步驟(完整代碼)

    今天給大家?guī)淼氖顷P于Java的相關知識,文章圍繞著Java實現(xiàn)畫圖的詳細步驟展開,文中有非常詳細的介紹及代碼示例,需要的朋友可以參考下
    2021-06-06
  • 探索HttpClient中的close方法及其對連接的影響

    探索HttpClient中的close方法及其對連接的影響

    這篇文章主要為大家介紹了HttpClient中的close方法及其對連接的影響探索分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-10-10
  • SpringBoot整合jasypt實現(xiàn)敏感信息的加密詳解

    SpringBoot整合jasypt實現(xiàn)敏感信息的加密詳解

    一般公司的核心業(yè)務代碼中,都會存在與數(shù)據庫、第三方通信的secret key等敏感信息,如果以明文的方式存儲,一旦泄露,那將會給公司帶來巨大的損失。本篇文章通過講解:Springboot集成Jasypt對項目敏感信息進行加密,提高系統(tǒng)的安全性
    2022-09-09
  • java鏈表應用--基于鏈表實現(xiàn)隊列詳解(尾指針操作)

    java鏈表應用--基于鏈表實現(xiàn)隊列詳解(尾指針操作)

    這篇文章主要介紹了java鏈表應用--基于鏈表實現(xiàn)隊列,結合實例形式分析了java基于鏈表實現(xiàn)隊列尾指針相關操作使用技巧,需要的朋友可以參考下
    2020-03-03
  • 深入理解SpringMVC中央調度器DispatcherServlet

    深入理解SpringMVC中央調度器DispatcherServlet

    這篇文章主要介紹了SpringMVC核心之中央調度器DispatcherServlet的相關知識,包括SpringMVC請求處理過程及SrpingMVC容器和spring?IOC容器關系,需要的朋友可以參考下
    2022-05-05

最新評論