1

我是 Java 的 AutoClosable 接口的新手(但不是 Java 的新手)。我正在尝试强制请求实例的客户端代码在完成使用后WebDriver关闭driver它(通过调用driver.quit()

我想要一种方法来强制任何实例化实例的方法WebDriver关闭它。

所以我创建了一个实现的新类AutoClosable

public class WebDriverLauncher implements AutoCloseable {

WebDriver driver;

public WebDriverLauncher()
{
    driver = new FirefoxDriver();
}

public WebDriver getDriver()
{
    return driver;
}



@Override
public void close() throws Exception {
    driver.quit();

    }

}

现在,我不是直接实例化 WebDriver ( WebDriver driver = new FirefoxDriver()),而是实例化这个类的实例,并让它返回一个实例,WebDriver如下例所示:

public WebDriver launchDriver()
{
    WebDriverLauncher webDriverLauncher = new WebDriverLauncher();

    WebDriver driver = webDriverLauncher.getDriver();

    return driver;
}

当我这样做时,我收到一个警告/错误:Resource leak: 'webDriverLauncher' is never closed

由于我无法关闭此方法中的资源,因为WebDriver调用者方法中正在使用资源(即 ),我想强制调用者launchDriver()关闭driver.

因此,我决定让该方法返回一个实例WebDriverLauncher- 例如以下示例:

public WebDriverLauncher launchDriver()
{
     WebDriverLauncher webDriverLauncher = new WebDriverLauncher();
     return webDriverLauncher;
}

这样,调用者将可以访问driver(通过调用webDriverLauncher .getDriver())并被警告关闭资源(所以我想)。

但是,当我尝试这样做时,警告消息完全消失了。换句话说,我不再看到关闭资源的警告——无论是在launchDriver()类/方法中,还是在调用者/客户端类中(正如我所提到的,我希望出现警告,所以任何调用此方法的人都会被警告关闭资源)

我想了解的是以下内容:

1)为什么警告没有传播到调用者类(如果资源从未关闭过)?

2)为什么当我返回时警告消失,但当我返回webDriverLauncher时没有driver

3)有没有办法修改代码以强制警告传播到调用者?(从而警告该方法的调用者关闭资源)

4)如果无法做到这一点,可以做些什么来强制客户端关闭WebDriver

谢谢!

4

2 回答 2

0

这个问题我迟到了。但是,如果我们想强制客户谨慎使用资源,这是我的看法。我们可以限制资源的创建(私有构造函数+通过为 jar 启用属性 -Djava.security.manager 来禁用反射访问)并允许客户端仅向资源工厂提供对该资源调用的方法。

public class MyResource implements AutoCloseable{
public static class ResourceFactory{
    public static void useResourceSafely(Consumer<MyResource> work) {
        try(MyResource res = new MyResource()){
        work.accept(res);
        }
        catch(Exception e)
        {
            e.printStackTrace();
            //you may even check for Suppressed exceptions
        }
    }
}

private MyResource() {
    System.out.println("Resource created");
}
public void doWork() {
    System.out.println("resource in use");
}
@Override
public void close() throws Exception {
    System.out.println("Closing myResource");
    
}   

}

客户端代码可能如下所示:

public static void main(String[] args) throws Exception{     
        ResourceFactory.useResourceSafely(s->{
            s.doWork();
            System.out.println("Check 1");
            s.doWork();
            System.out.println("Check 2");
        });
    }

PS:这可能不是推荐的方式,而只是尝试这样做。

于 2020-07-16T13:47:26.807 回答
-1

使用Try-with-resources 语句:</p>

 try (WebDriverLauncher webDriverLauncher = new WebDriverLauncher(){
     //Your Code Here
 }//webDriverLauncher.close() will be called after here weather throw any exception in try...catch block or not.

在其他世界中,AutoClosable接口是确定可以使用哪种类型的约束Try-with-resources statement

于 2018-05-11T02:01:57.100 回答