EJB - 使用 @Produces 注入 @Schedule @Singleton 失败;没有调度程序运行

问题描述 投票:0回答:1

我想定期调用此方法来清理 EJB 上下文中的 Apache HTTP 连接池。为此,我创建了这个调度程序类:

@DependsOn("PoolingHttpClientConnectionManager")
public class IdleConnectionMonitor {
    private static final Logger LOGGER = LoggerFactory.getLogger(IdleConnectionMonitor.class);
    @Inject
    private PoolingHttpClientConnectionManager poolingHttpClientConnectionManager;

    public IdleConnectionMonitor(PoolingHttpClientConnectionManager poolingHttpClientConnectionManager) {
        this.poolingHttpClientConnectionManager = poolingHttpClientConnectionManager;
    }

    @Schedule(second = "30")
    public void cleanUpPool() {
        LOGGER.debug("PoolStats counters meaning: max: total connections count; free: available to be reused/free/idle; leased: currently executing requests; waiting: the requests being blocked awaiting a free connection");
        tracePoolStats("HTTP client pool stats in the beginning: ");
        tracePoolStats("HTTP client pool stats before recycling:");
        poolingHttpClientConnectionManager.closeExpiredConnections();
        poolingHttpClientConnectionManager.closeIdleConnections(30, TimeUnit.SECONDS);
        tracePoolStats("HTTP client pool stats after recycling:");
    }
    private void tracePoolStats(String messagePrefix) {
        if (LOGGER.isDebugEnabled()) {
            PoolStats poolStats = poolingHttpClientConnectionManager.getTotalStats();
            LOGGER.debug(messagePrefix + "(max/free/leased/waiting): {} | {} | {} | {}",
                    poolStats.getMax(), poolStats.getAvailable(), poolStats.getLeased(), poolStats.getPending());
        }
    }
}

但它没有启动。我找不到日志。

如果我在上面加上

@Singleton
,JBoss EAP 会告诉我它必须有一个默认构造函数,但对我来说,它取决于连接管理器,缺少它当然无法工作。所以我不能将它定义为
@Stateless
@Singleton

我还应该做什么才能让它发挥作用?

PoolingHttpClientConnectionManager
来自另一个 Producer 类,该类是
@Produces
实例。

public class RestServiceProducer {

    @Produces
    public PoolingHttpClientConnectionManager poolingHttpClientConnectionManager() {
        if (poolingHttpClientConnectionManager == null) {
            this.poolingHttpClientConnectionManager = new PoolingHttpClientConnectionManager();
            poolingHttpClientConnectionManager.setMaxTotal(MAX_CONNECTIONS);
            poolingHttpClientConnectionManager.setDefaultMaxPerRoute(MAX_CONNECTIONS);
            poolingHttpClientConnectionManager.setDefaultSocketConfig(
                    SocketConfig.copy(SocketConfig.DEFAULT)
                            .setSoTimeout(SOCKET_TIMEOUT_MS)
                            .build()
            );
        }
        return poolingHttpClientConnectionManager;
    }
}

当第一个请求启动时,它会延迟创建实例。不过,我可以毫无问题地添加

@StartUp

scheduler apache-httpclient-4.x ejb-3.1 java-ee-8
1个回答
0
投票

最后我发现可以像平常一样

@Inject
PoolingConnectionManager
,并且我需要将这个类定义为
@Startup @Singleton
PoolingConnectionManager
可以来自
@Produces
方法。

@Singleton
@Startup
public class IdleConnectionMonitor {
    private static final Logger LOGGER = LoggerFactory.getLogger(IdleConnectionMonitor.class);

    @Inject
    private PoolingHttpClientConnectionManager poolingHttpClientConnectionManager;

    @Schedule(second = "*/30", minute = "*", persistent = false, hour = "*")
    public void cleanUpPool() {
        LOGGER.debug("PoolStats counters meaning: max: total connections count; free: available to be reused/free/idle; leased: currently executing requests; waiting: the requests being blocked awaiting a free connection");
        tracePoolStats("Job Manager HTTP client pool stats in the beginning: ", poolingHttpClientConnectionManager);
        tracePoolStats("Job Manager HTTP client pool stats before recycling:", poolingHttpClientConnectionManager);
        poolingHttpClientConnectionManager.closeExpiredConnections();
        poolingHttpClientConnectionManager.closeIdleConnections(30, TimeUnit.SECONDS);
        tracePoolStats("Job Manager HTTP client pool stats after recycling:", poolingHttpClientConnectionManager);
    }

    private void tracePoolStats(String messagePrefix, PoolingHttpClientConnectionManager poolingHttpClientConnectionManager) {
        if (LOGGER.isDebugEnabled()) {
            PoolStats poolStats = poolingHttpClientConnectionManager.getTotalStats();
            LOGGER.debug(messagePrefix + "(max/free/leased/waiting): {} | {} | {} | {}",
                    poolStats.getMax(), poolStats.getAvailable(), poolStats.getLeased(), poolStats.getPending());
        }
    }
}

制作人:

@ApplicationScoped
public class RestServiceProducer {
    ...
    @Produces
    public PoolingHttpClientConnectionManager poolingHttpClientConnectionManager() {
        
        if (this.poolingHttpClientConnectionManager == null) { // this can be guarded better with `@ConcurrencyControl(CONTAINER)`
            LOGGER.debug("Creating new PoolingHttpClientConnectionManager");
            this.poolingHttpClientConnectionManager = new PoolingHttpClientConnectionManager();
            poolingHttpClientConnectionManager.setMaxTotal(MAX_CONNECTIONS);
            poolingHttpClientConnectionManager.setDefaultMaxPerRoute(MAX_CONNECTIONS);
            poolingHttpClientConnectionManager.setDefaultSocketConfig(
                    SocketConfig.copy(SocketConfig.DEFAULT)
                            .setSoTimeout(SOCKET_TIMEOUT_MS)
                            .build()
            );
        } else {
            LOGGER.debug("Returning old PoolingHttpClientConnectionManager");
        }
        return poolingHttpClientConnectionManager;
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.