Java 如何将数据库连接工厂服务注入Jersey应用程序

Java 如何将数据库连接工厂服务注入Jersey应用程序,java,unit-testing,dependency-injection,jersey,Java,Unit Testing,Dependency Injection,Jersey,我有一个jersey应用程序,我正在编写单元测试来测试我的dao方法,事实证明,当我的应用程序运行时注入依赖项非常复杂 这是我的web.xml。你可以看到我正在使用包扫描 <?xml version="1.0" encoding="UTF-8"?> <!-- This web.xml file is not required when using Servlet 3.0 container, see implementation details http://jers

我有一个jersey应用程序,我正在编写单元测试来测试我的dao方法,事实证明,当我的应用程序运行时注入依赖项非常复杂

这是我的web.xml。你可以看到我正在使用包扫描

<?xml version="1.0" encoding="UTF-8"?>
<!-- This web.xml file is not required when using Servlet 3.0 container,
     see implementation details http://jersey.java.net/nonav/documentation/latest/jax-rs.html -->

<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
  <servlet>
    <servlet-name>myapp</servlet-name>
    <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
    <init-param>
      <param-name>javax.ws.rs.Application</param-name>
      <param-value>my.package.MyApplication</param-value>
    </init-param>
    <init-param>
      <param-name>jersey.config.server.provider.packages</param-name>
      <param-value>
        my.package
      </param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
  </servlet>

  <servlet-mapping>
    <servlet-name>myapp</servlet-name>
    <url-pattern>/api/v1/*</url-pattern>
  </servlet-mapping>
</web-app>
我有一个简单的单元测试:

Dao dao = new Dao();
dao.setConnectionFactory(new DriverManagerConnectionFactory("jdbc:hsqldb:mem:mymemdb:user=SA;"));
...
我可以轻松地运行我的单元测试。问题是,现在我的应用程序已损坏b/c我不知道在启动应用程序或通过URI调用控制器方法时如何注入我的DataSourceConnectionFactory


Jersey文档到处都是,含糊不清,并且没有提供我能够遵循的任何真实示例。

如果您使用的是Jersey 2.x,据我所知,他们在这里介绍了Jersey资源的依赖注入:

老实说,对于使用jersey的小型应用程序,我将自己的依赖项注入到工厂中,而不是使用JSR-330注释或其他DI机制。我的jersey资源构造一个POJO实例(比如AccountManager)来完成这项工作,POJO构造函数对它有依赖关系(比如说IAccountDAO),jersey资源只是去POJO工厂获取依赖关系。这使得本例中的AccountManager POJO易于进行单元测试,因为它在构造函数中提供了一个DAO,而不是直接耦合到DAO,不需要DI框架和注释来遍历代码。基本上它仍然是DI,但没有框架。我只会为非常小的应用程序这么做——我只是觉得用GoogleGuice或SpringDI打每一个应用程序可能有点过火——DI的概念在这些工具之前就已经存在了

下面是一个示例资源

DependenciesFactory是一个POJO,它为您的环境构建具有适当依赖关系的类。例如,如果“TeacherDirectory”需要向其注入一个数据源,或者向其注入一个DAO,而DAO又在其中注入了一个数据源,则工厂将处理该问题。当你这样做的时候,你必须考虑单身或者不单身,但这是非常容易管理的。您还经常需要一种方法来告诉您所处的环境——或者至少可能是本地开发人员箱与部署的环境——这对于任何DI都是正确的。DIs可以管理多个配置,因此,如果您需要多个配置,并且手动滚动您自己的配置,您需要处理这些配置

@Path("/teachers")
public class TeacherResource {
    private final ITeacherDirectory teacherDirectory;

    public TeacherResource() {
        this.teacherDirectory = DependenciesFactory.getTeacherDirectory();
    }

    @GET
    @Path("/")
    @Produces(MediaType.APPLICATION_JSON)
    public List<Provider> getTeachers(@QueryParam("teacherId") String teacherId, 
                                       @QueryParam("firstName") String firstName, 
                                       @QueryParam("lastName") String lastName) {

        return this.teacherDirectory.findTeachers(teacherId, firstName, lastName);
    }
@Path(“/teachers”)
公共课教师资源{
私有最终iTacherDirectory教师目录;
公共教师资源(){
this.teacherDirectory=DependenciesFactory.getTeacherDirectory();
}
@得到
@路径(“/”)
@产生(MediaType.APPLICATION_JSON)
公共列表getTeachers(@QueryParam(“teacherId”)字符串teacherId,
@QueryParam(“firstName”)字符串firstName,
@QueryParam(“lastName”)字符串(lastName){
返回此.teacherDirectory.findTeachers(teacherId、firstName、lastName);
}

我同意你的看法。你能提供一个代码示例来说明你是如何做到这一点的吗?@Catfish-当然-尽管我会再次谨慎地使用手动滚动DI-对于一个非常大的应用程序,它可能会变得很麻烦。堆栈溢出注释可能不是示例代码的最佳方式-我今天稍后会用一个示例添加另一个答案。你应该我只是用一些示例代码编辑你的答案,而不是写另一个答案。你不会相信的,但我昨天把上面的示例代码放在了错误的问题上。看那个问题的人一定想知道我到底出了什么问题。。。。
@Path("/teachers")
public class TeacherResource {
    private final ITeacherDirectory teacherDirectory;

    public TeacherResource() {
        this.teacherDirectory = DependenciesFactory.getTeacherDirectory();
    }

    @GET
    @Path("/")
    @Produces(MediaType.APPLICATION_JSON)
    public List<Provider> getTeachers(@QueryParam("teacherId") String teacherId, 
                                       @QueryParam("firstName") String firstName, 
                                       @QueryParam("lastName") String lastName) {

        return this.teacherDirectory.findTeachers(teacherId, firstName, lastName);
    }