春天@Autowired和Singletons

sky*_*man 9 spring

我有一个Spring应用程序,它使用持久存储在数据库中的各种配置参数.为了最大限度地减少数据库访问周期,我创建了一个Singleton类,它将参数保存在Properties对象中.有时在运行应用程序期间需要刷新Properties对象,因此为此我有一个load()方法和一个reload()方法.为了访问数据库,我有一个@Autowired服务对象.简化一点:

public class AppConfig {
    private static AppConfig instance = null;
    private Properties appProperties;

    @Autowired ConfiguraitonService configService;

    protected AppConfig() {
        load();
    }

    public static AppConfig getInstance() {
        if (instance == null) {
            instance = new AppConfig();
        }
        return instance;
    }

    public void reload() {
        load();
    }

    private void load() {
        List<Configuration> configList configService.findAll()

        for (Configuration myConfiguration : configList) {
          if (myConfiguration != null && myConfiguration.getAttribute() != null) {
                appProperties.setProperty(myConfiguration.getAttribute(),myConfiguration.getValue());
            }
        }
    }

public String getValue(String key) {
    return appProperties.getProperty(key);
}
Run Code Online (Sandbox Code Playgroud)

在Spring配置文件中,我有:

<bean id="appConfigBean" class="foo.bar.AppConfig"></bean>
Run Code Online (Sandbox Code Playgroud)

对此Singleton调用'getValue'会生成空指针异常.据我所知,虽然我不明白为什么,但这与@Autowired有关并且无法正确初始化.我想我的问题与解决这个问题的最佳方法有关.

对于其他人来说,这是修改后的代码:

public class AppConfig {
    private static Properties myProperties = new Properties();

    @Autowired
    private ConfigurationService configService;
    private static AppConfig instance = null;

    protected AppConfig() {
    }

    public static AppConfig getInstance() {
        if (instance == null) {
            instance = new AppConfig();
        }
        return instance;
    }

    @PostConstruct
    public void load() {        
        List<Configuration> configList = configService.findAll();

        for (Configuration myConfiguration : configList) {
            if (myConfiguration != null && myConfiguration.getAttribute() != null) {
                myProperties.setProperty(myConfiguration.getAttribute(), myConfiguration.getValue());
            }
        }
    }
Run Code Online (Sandbox Code Playgroud)

Dir*_*ski 8

当构造函数调用load()时,Autowired依赖项仍然是无连接的.接线在构造器完成后进行.要么使用configService final并使用构造函数自动装配,要么从构造函数中删除load(),但使用@PostConstruct注释load().