我正在使用单例bean将存储在数据库中的配置值提供给我的Java EE应用程序。
@Singleton
public class ConfigurationProvider {
private final Map<String, ConfigurationEntity> configMap = new HashMap<>();
@PersistenceContext(unitName = DatabaseConstants.PERSISTENCE_UNIT)
private EntityManager em;
public String getConfiguration(String key) {
if (configMap.containsKey(key)) {
return configMap.get(key).getValue();
}
ConfigurationEntity config = em.find(ConfigurationEntity.class, key);
em.detach(config);
if (config == null) {
throw new RuntimeException("Configuration not found for " + key);
}
configMap.put(key, config);
return config.getValue();
}
public void clear() {
configMap.clear();
}
public Collection<ConfigurationEntity> getCurrentConfigurationState() {
return configMap.values();
}
}
生产者让我注入值
public class ConfigurationProducer {
@Inject
private ConfigurationProvider configProvider;
@Produces
@ConfigurationValue
public String getConfiguration(InjectionPoint ip) {
String key = createKey(ip);
return configProvider.getConfiguration(key);
}
这是一个例子
@Inject
@ConfigurationValue
private Instance<String> endpoint;
这会从数据库加载endpont。出于测试原因,该值应该是可更改的。 所以你看到的是ejb模块的一部分。
为了重新加载这些值,我创建了一个提供该功能的REST接口。此REST服务是与ejb模块一起打包在一个ear文件中的附加WAR的一部分。
@Path("/configuration")
public class ConfigurationResource {
@EJB
private ConfigurationProvider configurationProvider;
@GET
@Path("/current")
@Produces({ "application/json" })
public Collection<ConfigurationEntity> getCurrentConfiguration() {
return configurationProvider.getCurrentConfigurationState();
}
}
但问题是,战争有它自己的配置提供者实例。所以我无法实现'缓存'。 为什么我的同一个耳中有两个单身实例?
答案 0 :(得分:0)
我认为你不能以这种方式使用ConfigurationProvider EJB。 EJB需要具有远程接口,您可以从外部WAR访问它作为任何远程EJB。外部WAR具有不同的类加载器,因此它不会找到EAR单例EJB。
答案 1 :(得分:0)
您似乎正在使用CDI的@Inject和EJB的@EJB来注入您的ConfigurationProvider实例。考虑到你没有同步访问map并且你正在使用不是线程安全的EntityManager,你应该使用@EJB。
也就是说,您只需要对代码进行一些小改动:
public class ConfigurationProducer {
@EJB
private ConfigurationProvider configProvider;
@Produces
@ConfigurationValue
public String getConfiguration(InjectionPoint ip) {
String key = createKey(ip);
return configProvider.getConfiguration(key);
}
答案 2 :(得分:0)
解决方案:
Maven第二次在war的lib文件夹中打包了ejb模块。我必须在pom.xml中设置范围才能提供。使用ejb模块,它可以毫无排除地运行,但对于战争,你必须手动完成。
现在可行。