2014-09-09 3 views
0

싱글 톤 빈을 사용하여 데이터베이스에 저장되어있는 구성 값을 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(); 
    } 
} 

프로듀서

날 값 여기에 예를 들어

@Inject 
@ConfigurationValue 
private Instance<String> endpoint; 

이 데이터베이스에서 endpont를로드

public class ConfigurationProducer { 

    @Inject 
    private ConfigurationProvider configProvider; 

    @Produces 
    @ConfigurationValue 
    public String getConfiguration(InjectionPoint ip) { 
    String key = createKey(ip); 
    return configProvider.getConfiguration(key); 
    } 

를 주입 할 수 있습니다. 테스트 목적으로, 값은 변경 가능해야합니다. 그래서 본 것은 ejb 모듈의 일부입니다.

값을 다시로드하려면 기능을 제공하는 REST-Interface를 만들었습니다. 이 REST 서비스는 하나의 ear 파일에 ejb 모듈과 함께 패키지 된 추가 WAR의 일부입니다.

@Path("/configuration") 
public class ConfigurationResource { 

    @EJB 
    private ConfigurationProvider configurationProvider; 

    @GET 
    @Path("/current") 
    @Produces({ "application/json" }) 
    public Collection<ConfigurationEntity> getCurrentConfiguration() { 
    return configurationProvider.getCurrentConfigurationState(); 
    } 
} 

그러나 문제는 전쟁에 구성 제공자의 인스턴스가 있다는 것입니다. 그래서 나는 '캐시'를 다시로드 할 수 없습니다. 같은 귀에 내 싱글 톤 인스턴스가 두 개있는 이유는 무엇입니까?

답변

0

그런 식으로 ConfigurationProvider EJB를 사용할 수 있다고 생각하지 않습니다. 그 EJB는 원격 인터페이스를 가져야하며 외부 WAR에서 원격 EJB로 액세스 할 수 있습니다. 외부 WAR에는 다른 클래스 로더가 있으므로 EAR 싱글 톤 EJB를 찾지 않습니다.

+0

안녕 bitkot, 두 모듈은 동일한 귀 파일에 있습니다. – boskop

0

CDI의 @Inject와 EJB의 @EJB를 모두 사용하여 ConfigurationProvider 인스턴스를 삽입하는 것으로 보입니다. 맵에 대한 액세스를 동기화하지 않는다고 생각하고 스레드 안전하지 않은 EntityManager를 사용하고 있다면, 반드시 @EJB를 사용해야합니다. 말했다

, 당신은 당신의 코드에서 단지 약간의 변화가 필요합니다

public class ConfigurationProducer { 
    @EJB 
    private ConfigurationProvider configProvider; 

    @Produces 
    @ConfigurationValue 
    public String getConfiguration(InjectionPoint ip) { 
     String key = createKey(ip); 
     return configProvider.getConfiguration(key); 
} 
0

솔루션 :

메이븐 EJB 모듈 전쟁의 lib 폴더에 두 번째 패키지. 제공된 pom.xml의 범위를 설정해야했습니다. ejb 모듈을 사용하면 어떤 외침도없이 작동하지만 전쟁의 경우 수동으로해야합니다.

이제 작동합니다.