Guice启动数据库查询

我需要在play框架启动时执行数据库查询以检索服务器信息 . 我写了一个ServerInstanceModule即 .

public class ServerInstanceModule extends AbstractModule {
ServerInstance serverInstance;

@Override
protected void configure() {

}

@Provides
@Inject
ServerInstance provideServerInstance(Configuration configuration){
    if (serverInstance == null) {
        String serverInstanceId = configuration.getString("instance.db.id");
        try {
            if (serverInstanceId != null) {
                serverInstance = models.managemend.ServerInstance.find.byId(Long.parseLong(serverInstanceId));
            }
        } catch (Throwable e) {
            Logger.error(e.getMessage(), e);
        }
    }
    return serverInstance;
}}

这是正确的方法吗?我尝试编写服务,将其声明为单例并且急切地加载它,即 .

@Singleton public class ServerInstanceService {
@Inject
private Configuration configuration;

ServerInstance serverInstance;

public ServerInstance get() {
    if (serverInstance == null) {
        String serverInstanceId = configuration.getString("instance.db.id");
        try {
            if (serverInstanceId != null) {
                serverInstance = ServerInstance.find.byId(Long.parseLong(serverInstanceId));
            }
        } catch (Throwable e) {
            Logger.error(e.getMessage(), e);
        }
    }
    return serverInstance;
}}

但是有些guice会以错误开头,因为serverinstance为null . 有没有人有任何建议我如何解决这个问题?我真的想使用服务而不是模块 .

回答(1)

2 years ago

您正面临竞争条件和线程安全问题 . 这是实现它的最简单方法,但 serverInstance 不是线程安全的,因为它可能有mutator .

@Singleton
public class ServerInstanceService implements IServerInstanceService {

    private final ServerInstance servcerInstance;

    @Inject
    public ServerInstanceService(Configuration config) {
        Long id = // ..
        servcerInstance = ServerInstance.findById(id);
    }

}