如何控制客户的CMT注入?

时间:2015-09-25 13:33:11

标签: java-ee ejb cdi

假设我有一个EJB。

@Stateless
public class PersistenceService {

    @PersistenceContext(unitName="dependent")
    private transient EntityManager entityManager;
}

有没有办法控制客户端的unitName值?

@RequestScoped
@Path("/persistence")
public class PersistenceResource {

    //"some"
    @Inject
    private transient PersistenceService somePU;

    //"other"
    @Inject
    private transient PersistenceService otherPU;
}

1 个答案:

答案 0 :(得分:1)

1)为您的PU创建2个CDI qualifiers

@Qualifier
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD, ElementType.TYPE, ElementType.METHOD})
public @interface SomePC {
}

@Qualifier
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD, ElementType.TYPE, ElementType.METHOD})
public @interface OtherPC {
}

2)然后将您的PU暴露为CDI bean

@ApplicationScoped
public class EntityManagerProducer {


@Produces
@PersistenceContext(unitName = "somePU")
@SomePC
private EntityManager em;

@Produces
@PersistenceContext(unitName = "otherPU")
@OtherPC
private EntityManager em;
}

3)在您的服务中注入两个EM:

@Stateless
public class PersistenceService {

    @Inject 
    @SomePC
    private emSome;

    @Inject 
    @OtherPC
    private emOther;

    public SeomthingUseful doSomething(Context myContext){
      getEntityManager(myContext);
      ... 
    }   

    private EntityManager getEntityManager(Context myContext){
      if(myContext == SOME_PU)
        return emSome;
      return emOther;
    }
}

4)从您的客户端,您可以传递将用于选择适当PU的上下文(您也可以为此创建一个RequestScoped bean,在这种情况下,您不必使用方法参数):< / p>

@RequestScoped
@Path("/persistence")
public class PersistenceResource {

   @Inject
   PersistenceService service;

   public void myMethod(){
      service.doSomething(myContext.SOME_PU);
   }


}

Context可以是一个包含您需要的不同值的枚举(SOME_PU,OTHER_PU)。作为替代方案,您可以通过执行以下操作动态注入服务中的所有EM bean:

@Inject @Any Instance<EntityManager> emSource;

如果您遵循此路径,则会解释所有内容here