Java 如何从非容器管理的类访问容器管理的对象

Java 如何从非容器管理的类访问容器管理的对象,java,jpa,cdi,Java,Jpa,Cdi,有没有办法从一个不是由容器创建或管理的类访问通常由容器创建和管理的对象?换句话说,当有容器时,代码可以处理容器管理的类实例,当没有容器时,代码可以处理常规POJO 对我来说,关键是测试类不知道它得到的类是来自容器还是来自存根。 我可能是老派,但我想使用一个可配置的工厂类来访问我的数据库。在进行生产或集成测试时,它将返回我的DAL接口的容器注入实现。当进行单元测试时,我希望去掉DAL并返回静态值 这可能吗 怎样才能做到呢 这就是我目前所处的位置,但仍然没有快乐 工厂级 @Stateless pub

有没有办法从一个不是由容器创建或管理的类访问通常由容器创建和管理的对象?换句话说,当有容器时,代码可以处理容器管理的类实例,当没有容器时,代码可以处理常规POJO

对我来说,关键是测试类不知道它得到的类是来自容器还是来自存根。

我可能是老派,但我想使用一个可配置的工厂类来访问我的数据库。在进行生产或集成测试时,它将返回我的DAL接口的容器注入实现。当进行单元测试时,我希望去掉DAL并返回静态值

这可能吗

怎样才能做到呢

这就是我目前所处的位置,但仍然没有快乐

工厂级

@Stateless
public class DALFactory
{
   @Inject
   private static DALInterface DAL;

   public static void init(String fqcn)
   {
      // use reflect to create unit test instance
   }

   public static DALInterface getDAL()
   {
      return DAL;
   }
}
测试班

public class test
{
   public void testDALAccess()
   {
      Table t = new Table(); // Instance of class representing a table
      DALFactory.getDAL().persist(t);
   }
}
当我提供testDAL时,这很好,因为我使用FQCN调用init(),但当我尝试使用容器管理的实例时,它失败得很惨

你可能会猜到我对CDI和JPA有些陌生


仅供参考,我将
DALFactory
标记为
@无状态
的唯一原因是,当有容器时,它可以由容器管理。

因此,我最终采取了一些措施来解决这个问题。在我这样做之后,我能够隔离依赖于注入的代码和相关的容器,以便在没有容器的情况下测试它

注意——我仍然愿意使用其他方法来解决这个问题,这样我就可以在容器执行注入的情况下测试相同的代码

//达尔工厂

public class DALFactory
{
   private static DALInterface DAL;

   public static void setDAL(DALInterface di)
   {
      DAL = di;
   }

   public static void init(String fqcn)
   {
      // use reflect to create unit test instance
   }

   public static DALInterface getDAL()
   {
      return DAL;
   }
}
//根可注入类,它必须是可注入树的顶部

@Stateless
public MainClass
{
  @Inject
  ProdDAL dal;

  @PostConstruct
  public void postConstruct()
  {
      DALFactory.setDAL(new DALWrapper(this.dal));
  }
}
//花环

public DALWrapper implements DALInterface
{
   private ProdDAL dal;

   public DALWrapper(ProdDAL prodDAL)
   {
      this.dal = prodDal;
   }

... rest of interface goes here
}

您可能有一个错误的概念,CDI的一个主要点是获取静态属性。此外,EJB和CDI是不同的技术,尽管非常相似
@Stateless
正在将该类标记为EJB,但
@Inject
正在寻找CDI注入。如果这是工作,这是好的,但你可能会发现一些不希望的行为线。(如果您想保持一致,您应该使用
@SessionScoped
而不是
@Stateless
,或者
@EJB
而不是
@Inject
。@AnthonyRaymond好的,那么您如何为单元测试注入接口的测试存根实现呢?我不想在部署到不同的环境之前修改代码,因为我想从存根转移到完整的实现……注入不应该是单元测试的一部分。单元测试是关于验证方法或类(“单元”)的行为;外部依赖项通常使用JMockit、Mockito或EasyMock等工具进行模拟,而不是注入。如果您指的是集成测试,那么我建议使用Arquillian之类的工具在容器中运行它们。@dcsohl好的,但是如何编写代码,以便您不需要注入?以我的具体示例为例——如何编写一个类,以便在不向其中注入任何内容的情况下对其进行测试?当调用“testDALAccess()”方法试图访问数据库,但我目前没有提供数据库的容器时,如何测试我的“test”类?