Java 我应该使用自动连接的静态变量吗?

Java 我应该使用自动连接的静态变量吗?,java,spring,spring-boot,Java,Spring,Spring Boot,我试图实现一个带有缓存特性的单例模式。起初,MySingleton只是一个POJO,事情也很简单,但后来我需要添加一个新功能,这也需要自动连接bean。(MyComponent实际上是数据存储库的接口) 我将@Component注释放在MySingleton上,以触发自动连线(尽管它总是被称为静态方式),并创建了一个私有构造函数,将MyComponent引用传递给new创建的对象。这段代码似乎有效,但我不完全理解为什么 我的问题:我觉得我做错了,但我是吗? (您是否批准此代码库拉取请求?) im

我试图实现一个带有缓存特性的单例模式。起初,MySingleton只是一个POJO,事情也很简单,但后来我需要添加一个新功能,这也需要自动连接bean。(
MyComponent
实际上是数据存储库的接口)

我将
@Component
注释放在
MySingleton
上,以触发自动连线(尽管它总是被称为静态方式),并创建了一个私有构造函数,将
MyComponent
引用传递给new创建的对象。这段代码似乎有效,但我不完全理解为什么

我的问题:我觉得我做错了,但我是吗? (您是否批准此代码库拉取请求?)

import static org.junit.jupiter.api.Assertions.assertNotNull;
导入org.junit.jupiter.api.Test;
导入org.springframework.boot.test.context.SpringBootTest;
@春靴测试
公共类MySingletonTest{
@试验
公开无效测试(){
assertNotNull(MySingleton.getInstance().getMyComponent());
}
}
// ----------------------------------------------------------------------------- //
导入java.util.Calendar;
导入java.util.concurrent.AtomicReference;
导入org.springframework.beans.factory.annotation.Autowired;
导入org.springframework.stereotype.Component;
@组成部分
公共课米辛格尔顿{
私有静态最终长缓存\u超时=60*60*1000;//1小时
私有静态最终AtomicReference实例=新的AtomicReference();
私有最终日历时间戳;//注意:这不是静态的!
@自动连线
私有静态MyComponent MyComponent;
私有MySingleton(MyComponent MyComponent){
this.timestamp=Calendar.getInstance();
MySingleton.myComponent=myComponent;//我不明白为什么需要这一行
}
私有布尔值isTimeout(){
返回Calendar.getInstance().getTimeInMillis()-timestamp.getTimeInMillis()>缓存超时;
}
公共静态同步MySingleton getInstance(){
if(INSTANCE.get()==null | | INSTANCE.get().isTimeout()){
set(新的MySingleton(myComponent));
}
返回INSTANCE.get();
}
公共MyComponent getMyComponent(){
返回myComponent;
}
}
// ----------------------------------------------------------------------------- //
导入org.springframework.stereotype.Component;
@组成部分
公共类MyComponent{
}

如果您使用spring,bean在默认情况下是单例的(除非您给它原型范围),那么为什么您需要所有单例逻辑呢?将日志记录放在构造函数中。你会感到惊讶的。将有两个例子,这是一个很好的观点!我真的不需要它。我正在从JavaEE过渡到Spring,并认为
@Autowired
类似于
@Inject
。今天我知道不是。我只是删除了凌乱的代码,并用
@PostConstruct
注释了我的初始化方法,一切都正常工作。干杯。你不能自动连接一个
静态
变量,这样它无论如何都会失败。@M.Deinum我同意,它应该失败,但不会。代码示例有效。正如talex所指出的,有两个实例,尽管它是一个静态变量,但在测试第二个实例时它不为null。如果使用spring,bean默认为单例(除非您为它提供原型范围),那么为什么需要所有单例逻辑呢?将日志记录到构造函数中。你会感到惊讶的。将有两个例子,这是一个很好的观点!我真的不需要它。我正在从JavaEE过渡到Spring,并认为
@Autowired
类似于
@Inject
。今天我知道不是。我只是删除了凌乱的代码,并用
@PostConstruct
注释了我的初始化方法,一切都正常工作。干杯。你不能自动连接一个
静态
变量,这样它无论如何都会失败。@M.Deinum我同意,它应该失败,但不会。代码示例有效。正如talex所指出的,有两个实例,尽管它是一个静态变量,但在测试第二个实例时它不为null。
import static org.junit.jupiter.api.Assertions.assertNotNull;

import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
public class MySingletonTest {
    @Test
    public void test() {
        assertNotNull(MySingleton.getInstance().getMyComponent());
    }
}

// ----------------------------------------------------------------------------- //

import java.util.Calendar;
import java.util.concurrent.atomic.AtomicReference;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class MySingleton {

    private static final long CACHE_TIMEOUT = 60 * 60 * 1000; // 1 hour
    private static final AtomicReference<MySingleton> INSTANCE = new AtomicReference<MySingleton>();
    private final Calendar timestamp; // NOTE: this is NOT static!

    @Autowired
    private static MyComponent myComponent;

    private MySingleton(MyComponent myComponent) {
        this.timestamp = Calendar.getInstance();
        MySingleton.myComponent = myComponent; // I do not understand why this line is needed
    }

    private boolean isTimeout() {
        return Calendar.getInstance().getTimeInMillis() - timestamp.getTimeInMillis() > CACHE_TIMEOUT;
    }

    public static synchronized MySingleton getInstance() {
        if ( INSTANCE.get() == null || INSTANCE.get().isTimeout() ) {
            INSTANCE.set(new MySingleton(myComponent));
        }
        return INSTANCE.get();
    }

    public MyComponent getMyComponent() {
        return myComponent;
    }
}

// ----------------------------------------------------------------------------- //

import org.springframework.stereotype.Component;

@Component
public class MyComponent {

}