Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
不同的Java对象引用相同的内存位置?_Java_Spring - Fatal编程技术网

不同的Java对象引用相同的内存位置?

不同的Java对象引用相同的内存位置?,java,spring,Java,Spring,这可能是个新手问题,但我找不到原因。我有一个RetryOneException类来控制某些任务的重试次数。我有不同的任务要控制,因此我创建了这个类的不同对象 问题是,如果我调用一个对象的ErrorOccursed,那么我所有对象的numberOfTriesLeft都会更改。在我看来,所有对象都只是引用同一个对象 这是怎么发生的?我该如何解决 @Component public class RetryOnException { private int numberOfRetries;

这可能是个新手问题,但我找不到原因。我有一个RetryOneException类来控制某些任务的重试次数。我有不同的任务要控制,因此我创建了这个类的不同对象

问题是,如果我调用一个对象的ErrorOccursed,那么我所有对象的numberOfTriesLeft都会更改。在我看来,所有对象都只是引用同一个对象

这是怎么发生的?我该如何解决

@Component
public class RetryOnException {

    private int numberOfRetries;    // retries
    private int numberOfTriesLeft;  // retries
    private long timeToWait;        // PauseMs

    @Autowired
    public RetryOnException(@Value("${exception.retries}") int numberOfRetries,
            @Value("${exception.pauseMs}") long timeToWait) {
        this.numberOfRetries = numberOfRetries;
        this.numberOfTriesLeft = numberOfRetries;
        this.timeToWait = timeToWait;
    }

    @Value("${exception.retries}")
    private int defaultRetries;

    /**
     * @return true if there are tries left
     */
    public boolean shouldRetry() {
        return numberOfTriesLeft > 0;
    }

    public void errorOccured() throws Exception {
        numberOfTriesLeft--;
        if (!shouldRetry()) {

            throw new Exception("Retry Failed: Total " + numberOfRetries
                    + " attempts made at interval " + getTimeToWait()
                    + "ms");
        }
        waitUntilNextTry();
    }

    public long getTimeToWait() {
        return timeToWait;
    }

    private void waitUntilNextTry() {
        try {
            Thread.sleep(getTimeToWait());
        } catch (InterruptedException ignored) {
        }
    }

    public void resetRetryCount() {
        numberOfTriesLeft = defaultRetries;
    }

}

似乎您正在使用SpringIoC容器来创建RetryOneException对象。请注意,bean的默认作用域是。这意味着整个应用程序共享一个bean实例。

您还没有将代码粘贴到使用RetryOneException类的位置,因此我将假设您是如何使用它的。基于它是用@Component注释的事实,我假设您正在使用@Autowired将这个类注入到您正在使用它的其他类中

这样做只会使用该类的一个实例,即new RetryOnException只会被调用一次,并且在使用@Autowired的任何地方都会使用相同的实例。这是因为您已将RetryOneException设置为spring管理的单例

为了确保使用该类的所有实例都具有独立的行为,在使用该类时需要手动实例化该类,因此不需要使用@Autowired,而是需要实例化该类并手动将值传递到构造函数中,如:

RetryOnException retryOnException = new RetryOnException(numberOfRetries, timeToWait);

您可以让消费类访问@值,并将这些值传递到此构造函数。

您似乎使用了Spring。当您通过@Autowired annotation创建此类对象时,这意味着您将始终获得该对象的一次安装。您可以阅读更多有关Spring中单例模式和it实现的信息,以了解使用@Component和@Autowired注释时发生的情况。

Spring中的@Component注释类默认为单例,即只会创建一个对象,并使用@Autowired注释将其自动连接到使用它的每个位置

我建议您在春季学习scopes的快速教程


快速切入:您可以尝试使用@Scopeprototype和@Component将范围设置为prototype,这与singleton完全相反,即它将使用@Autowired为每个引用它的地方创建新实例。但是在这种情况下,您必须自己将实例传递到希望传递现有对象的每个位置

如何创建RetryOneException对象?这是否回答了您的问题?菲利克斯:那些物体是自动连线的吗@组件将该类转换为Springbean,从而转换为Singleton。将@Scope'protype'放入您的RetryOneException类中。谢谢大家!是的,我正在使用@Autowired创建对象。将@Scopeprototype注释到我的类之后,它就可以正常工作了。真的学到了一些东西!感谢