有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java如何实现每30分钟登录一次的客户端?

我正在编写一个应用程序,使用atlassian的JiraRestClient。我无法在每次Jira交互上创建这个客户端,所以我想到了缓存这个客户端

这个客户端每35分钟执行一次登录,所以我想缓存它30分钟,然后再次执行登录

为此,我需要这个客户端的一个实例,以便Jira交互的所有线程都可以使用它。我创建了一个provider类,如果实例的创建时间超过30分钟,它将保持时间跟踪并执行登录,确保实例始终登录

public class JiraRestClientProvider {
private static JiraRestClient jiraRestClient;
private static final long EXPIRATION_TIME = 1800L;
private static long creationTime = Instant.now().getEpochSecond();

public static synchronized JiraRestClient getJiraRestClient() {
    if (jiraRestClient == null || Instant.now().getEpochSecond() > creationTime + EXPIRATION_TIME) {
        return createJiraRestClient();
    }
    return jiraRestClient;
}

其中createJiraRestClient是一个私有方法,它读取凭证,更新创建时间,并更新私有静态变量jiraRestClient

另一个类使用这个JiraRestClientProvider类来执行Jira操作,如创建问题或对问题进行评论等,如下所示:

JiraRestClientProvider.getJiraRestClient().
getIssueClient().createIssue(issueInput).claim().getKey();

或者

JiraRestClientProvider.getJiraRestClient().getIssueClient()
            .getIssue(issueKey).claim().getCommentsUri().toString();

现在,在为使用该方法的类编写单元测试时,我不能模拟静态方法getJiraRestClient,因此无法编写单元测试。 (此外,我不能使用PowerMock)

我的问题是,有没有一种方法可以让我编写我的provider类,这样所有线程都只有一个新的JiraRestClient实例,而且我还可以对它进行单元测试


共 (1) 个答案

  1. # 1 楼答案

    是的,你可以。但不是你的设计

    无论何时打电话:

    JiraRestClientProvider.getJiraRestClient() 
    

    自动将任何类与单例紧密耦合,这意味着每次在单元测试中调用被测方法时,它都会调用单例。没有办法解决这个问题,除非你想实现PowerMock:)

    一个快速的成功方法是将你的单例封装在一个接口下,并使用依赖注入将它注入到你的类中

    编写完整的普通代码

     interface IJiraClientProvider { 
        JiraRestClient getJiraRestClient();
     }
    
     class Wrapper implements IJiraClientProvider  { 
        JiraRestClient getJiraRestClient()  {
             return JiraRestClientProvider.getJiraRestClient();
         }
     } 
    
     class YourClass {  
     private IJiraClientProvider jiraClientProvider
     public YourClass(IJiraClientProvider jiraClientProvider)  {
         this.jiraClientProvider = jiraClientProvider; 
     }
    
     // now you can unit test your code and mock the dependency  
    } 
    

    实例化YourClass时,必须传递包装器:

     YourClass cls = new YourClass(new Wrapper());