将Guice与嵌入式Tomcat一起使用?

时间:2014-12-04 13:45:56

标签: tomcat guice spring-jdbc jersey-2.0 hk2

我有一个球衣2项目,Guice用于DI(通过hk2桥)。 Spring JDBC用于数据库调用,并通过Guice进行配置。我用嵌入式tomcat在本地运行它。 此设置适用于应用程序,即我可以访问我的球衣资源中的数据库

现在我想为需要数据库访问以进行初始设置的应用程序编写测试用例,但我在注入的对象上获得 NullPointerException

主文件(此处注入为空值)

public class StartApp {
    @Inject
    private JdbcTemplate jdbcTemplate;

    public static void main(String[] args) throws Exception {
        startTomcat();
    }

    private static void startTomcat() throws Exception {
        String webappDirLocation = "src/main/webapp/";
        Tomcat tomcat = new Tomcat();
        String webPort = System.getProperty("app.port", "8080");
        tomcat.setPort(Integer.valueOf(webPort));
        tomcat.addWebapp("/", new File(webappDirLocation).getAbsolutePath());
        tomcat.start();
        new StartApp().initDatabase();
        tomcat.getServer().await();
    }

    public void initDatabase() throws Exception {
        String sql = new String(Files.readAllBytes(Paths.get(StartApp.class.getClassLoader().getResource("db_base.sql").toURI())), "UTF-8");
        jdbcTemplate.execute(sql);
    }
}

JdbcTemplate注入失败。在实际的球衣资源中,它运作良好。

web.xml(仅显示guice部分)

<filter>
    <filter-name>Guice Filter</filter-name>
    <filter-class>com.google.inject.servlet.GuiceFilter</filter-class>
</filter>

<filter-mapping>
    <filter-name>Guice Filter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

<listener>
    <listener-class>MyGuiceServletContextListener</listener-class>
</listener>

MyGuiceServletContextListener

public class MyGuiceServletContextListener extends GuiceServletContextListener {
    @Override
    protected Injector getInjector() {
        return Guice.createInjector(new AbstractModule() {

            @Override
            protected void configure() {
                bind(JdbcTemplate.class).toProvider(JdbcTemplateProvider.class).in(Scopes.SINGLETON);
            }
        });
    }
}

JerseyConfig

public class JerseyConfig extends ResourceConfig {
    @Inject
    public JerseyConfig(ServiceLocator serviceLocator, ServletContext servletContext) {
        packages("resources");

        GuiceBridge.getGuiceBridge().initializeGuiceBridge(serviceLocator);
        GuiceIntoHK2Bridge guiceBridge = serviceLocator.getService(GuiceIntoHK2Bridge.class);
        guiceBridge.bridgeGuiceInjector((Injector) servletContext.getAttribute(Injector.class.getName()));
    }
}

1 个答案:

答案 0 :(得分:0)

由于tomcat在不同的进程中启动,因此在StartApp中无法访问在Jersey App中创建的guice注入器。必须在StartApp中创建Guice注入器才能获得JdbcTemplate instamnce

JdbcTemplate jdbcTemplate = Guice.createInjector(new PaymentGatewayModule()).getInstance(JdbcTemplate.class);