我有一个已经使用Guice的大型现有java程序。我试图添加一个带有swagger文档的嵌入式网站。不知怎的,我需要用Guice连接它,但是当我尝试使用我在主程序中注入的东西时,我尝试的所有内容都会抛出空指针异常。我想也许我可以通过注射器并将其连接起来,使用注射器或创建子注射器。
我已经使用了实现此功能所需的代码创建了一个示例应用程序,其中一个URL可以正常工作但不会尝试使用我的主程序中的注入,而且一个不起作用尝试使用注射剂。
我试图在不需要web.xml的情况下通过以下方式完成所有这些:
private ContextHandler buildApiContext() {
ResourceConfig resourceConfig = new ResourceConfig();
// Replace EntityBrowser with your resource class
// io.swagger.jaxrs.listing loads up Swagger resources
resourceConfig.packages("web", ApiListingResource.class.getPackage().getName());
//apiServletContainer.reload(resourceConfig);
ServletContainer apiServletContainer = new ServletContainer(resourceConfig);
final ServletContextHandler apiContext = new ServletContextHandler(ServletContextHandler.SESSIONS);
apiContext.setContextPath("/api");
ServletHolder apiBrowser = new ServletHolder(apiServletContainer);
apiContext.addFilter(GuiceFilter.class, "/*", EnumSet.allOf(DispatcherType.class));
myGuiceServletContextListener.setMainInjector(blackboard.getMainInjector());
apiContext.addEventListener(myGuiceServletContextListener);
apiContext.addServlet(apiBrowser, "/*");
return apiContext;
}
和
public class MyGuiceServletContextListener extends GuiceServletContextListener {
@Inject private Blackboard blackboard;
@Override
protected Injector getInjector() {
return blackboard.getMainInjector();
}}
我也尝试过:
return blackboard.getMainInjector().createChildInjector();
在我的主要内容我开始使用以下主程序注入:
Config config = ReadConfig.createConfig();
Injector injector = Guice.createInjector(new Bindings(config));
BigProgramInterface bbInterface = injector.getInstance(BigProgramImpl.class);
bbInterface.start(injector);
其中Bindings看起来像
public class Bindings implements Module {
private Config config;
public Bindings(Config config) {
this.config = config;
}
public void configure(Binder binder) {
Integer fixedThreadPoolSize = 2;
Executor fixedExecutor = Executors.newFixedThreadPool(fixedThreadPoolSize, new FixedThreadFactory());
binder.bind(Executor.class).toInstance(fixedExecutor);
binder.bind(Config.class).toInstance(config);
binder.bind(Blackboard.class).asEagerSingleton();
binder.bind(BigProgramMain.class).asEagerSingleton();
binder.bind(EmbeddedWeb.class).asEagerSingleton();
//binder.bind(MyGuiceServletContextListener.class).asEagerSingleton();
}
黑板被注入,它正在进入主喷射器,但它无法使用。
工作的:
@Path("/test")
@Api (value = "/test")
public class TestSwagger {
private static final Logger log = LoggerFactory.getLogger(TestSwagger.class);
@GET
@Path("/get")
@ApiOperation(value = "a working test",
notes = "Returns my test class",
response = MyTest.class,
responseContainer="Class")
@Produces(MediaType.APPLICATION_JSON)
public Response getResult() {
MyTest myTest = new MyTest();
myTest.setMyTestString("this is a test");
return Response.ok().entity(myTest).build();
}}
不工作:
@Path("/testbad")
@Api (value = "/testbad")
public class TestSwaggerBad {
private static final Logger log = LoggerFactory.getLogger(TestSwaggerBad.class);
@Inject private Blackboard blackboard;
@GET
@Path("/get")
@ApiOperation(value = "a non - working test",
notes = "Returns my test class",
response = MyTest.class,
responseContainer="Class")
@Produces(MediaType.APPLICATION_JSON)
public Response getResult() {
MyTest myTest = new MyTest();
myTest.setMyTestString(blackboard.getBigProgramCounter().toString());
return Response.ok().entity(myTest).build();
}}
请参阅我的代码了解详细信息: https://github.com/phomlish/SwaggerSampleApiWebsite
答案 0 :(得分:1)
我仔细查看了您的代码,以下是您如何使用它:
将guice桥添加到你的pom:
<!-- https://mvnrepository.com/artifact/org.glassfish.hk2/guice-bridge -->
<dependency>
<groupId>org.glassfish.hk2</groupId>
<artifactId>guice-bridge</artifactId>
<version>2.5.0-b15</version>
</dependency>
将guice hk2桥接器添加到您的配置中。现在,您需要将其连接起来。为此,我们将创建一个功能,如本文所述:
Guice don't inject to Jersey's resources
@Priority(0)
public class GuiceFeature implements Feature {
private Injector i;
public GuiceFeature(Injector i) {
this.i = i;
}
@Override
public boolean configure(FeatureContext context) {
ServiceLocator locator = ServiceLocatorProvider.getServiceLocator(context);
GuiceBridge.getGuiceBridge().initializeGuiceBridge(locator);
GuiceIntoHK2Bridge guiceBridge = locator.getService(GuiceIntoHK2Bridge.class);
guiceBridge.bridgeGuiceInjector(i);
return true;
}
}
请注意,我将您创建的注入器传递给该功能。这很重要,因为您需要相同的注射器才能找到您的服务。绑定代码非常简单。
最后,您需要注册该功能。在您的EmbeddedWeb类中,添加:
EmbeddedWeb#buildApiContext:
resourceConfig.register(new GuiceFeature(myGuiceServletContextListener.getInjector()));
同样,我们使用您已创建的相同注射器。
最后,这就是您需要的一切,并且您的服务正确连线。
试验:
artur@pandaadb:~/dev/repo/SwaggerSampleApiWebsite$ curl "http://localhost:8080/api/testbad/get"
{"myTestString":"10"}
希望有所帮助,
阿图尔
编辑&#39;&#39;重要事项&#39;&#39;:
对于注射,您不能使用guice注释。泽西岛似乎没有认识到它们(可能是因为他们不想添加guice依赖项)。幸运的是,guice可以同时使用javax和guice注释。因此,在TestSwaggerBad类中,您还需要将导入更改为标准javax注释。