gpt4 book ai didi

java - 将 GuiceServletContextListener 连接到现有的注入(inject)器

转载 作者:行者123 更新时间:2023-11-30 08:33:30 25 4
gpt4 key购买 nike

我有一个已经在使用 Guice 的大型现有 Java 程序。我正在尝试添加一个带有 swagger 文档的嵌入式网站。我需要以某种方式将它与 Guice 连接起来,但是当我尝试使用我在主程序中注入(inject)的东西时,我尝试的一切都会抛出空指针异常。我想也许我可以通过注入(inject)器并以这种方式连接它,使用注入(inject)器或创建一个子注入(inject)器。

我创建了一个示例应用程序,仅使用使其正常工作所需的代码,其 URL 有效但不尝试从我的主程序中获取注入(inject),而无效的 URL 尝试使用注入(inject)。

我正在尝试通过以下方式在不需要 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();

在我的 main 中,我开始主程序注入(inject):

Config config = ReadConfig.createConfig();
Injector injector = Guice.createInjector(new Bindings(config));
BigProgramInterface bbInterface = injector.getInstance(BigProgramImpl.class);
bbInterface.start(injector);

绑定(bind)的样子

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();
}

黑板注入(inject)了,正在获取主注入(inject)器,但是不能使用

作品:

@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

最佳答案

我仔细看了你的代码,下面是你如何让它工作的:

将 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;
}

}

请注意,我将您创建的注入(inject)器传递给该功能。这很重要,因为您将需要相同的注入(inject)器才能找到您的服务。绑定(bind)代码相当简单。

最后,您需要注册该功能。在您的 EmbeddedWeb 类中,您添加:

嵌入式网络#buildApiContext:

resourceConfig.register(new GuiceFeature(myGuiceServletContextListener.getInjector()));

同样,我们使用的是您已经创建的同一个注入(inject)器。

最后,这就是您所需要的,并且您的服务已正确连接。

测试:

artur@pandaadb:~/dev/repo/SwaggerSampleApiWebsite$ curl "http://localhost:8080/api/testbad/get"
{"myTestString":"10"}

希望对你有帮助,

艺术

编辑“重要”:

对于注入(inject),不能使用guice注解。 Jersey 似乎无法识别它们(可能是因为它们不想添加 guice 依赖项)。幸运的是,guice 可以同时使用 javax 和 guice 注释。因此,在您的 TestSwaggerBad 类中,您还需要将导入更改为标准 javax 注释。

关于java - 将 GuiceServletContextListener 连接到现有的注入(inject)器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39449996/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com