java - HK2:使用即时范围绑定到接口的实现
问题描述
我正在构建一个将在 Jetty Server 上运行的应用程序。我的主类是从ResourceConfig扩展来启动的,“javax.ws.rs.Application”的init参数设置为这个类。我还使用 ServiceLocator 按需返回服务实例;还使用 AbstractBinder 将类与 Singleton & Immediate 范围绑定。
我的与依赖注入相关的 ResourceConfig 类代码如下所示:
public class MyServer extends ResourceConfig {
@Inject
public MyServer() {
packages("My.REST");
}
public static void main(String[] args) {
final Server server = new Server(MythreadPool);
HttpConfiguration httpConfig = new HttpConfiguration();
httpConfig.addCustomizer(new ForwardedRequestCustomizer());
ServerConnector connector = new ServerConnector(server, new HttpConnectionFactory(httpConfig));
//Code for connector porperties
server.addConnector(connector);
ContextHandlerCollection contexts = new ContextHandlerCollection();
server.setHandler(contexts);
final WebAppContext webApp = setupWebAppContext(contexts, conf);
ServiceLocator serviceLocator = ServiceLocatorFactory.getInstance().create("my-locator");
ServiceLocatorUtilities.enableImmediateScope(serviceLocator);
ServiceLocatorUtilities.bind(
sharedServiceLocator,
new AbstractBinder() {
@Override
protected void configure() {
bind(ClassA.class).to(InterfaceService.class).in(Immediate.class);
}
});
}
webApp.addEventListener(
new ServletContextListener() {
@Override
public void contextInitialized(ServletContextEvent servletContextEvent) {
servletContextEvent
.getServletContext()
.setAttribute(ServletProperties.SERVICE_LOCATOR, serviceLocator);
}
@Override
public void contextDestroyed(ServletContextEvent servletContextEvent) {}
});
setupRestApiContextHandler(webApp, conf);
try {
server.start();
} catch (Exception e) {
LOG.error("Error while running jettyServer", e);
System.exit(-1);
}
}
private static WebAppContext setupWebAppContext(ContextHandlerCollection contexts, Configuration conf) {
WebAppContext webApp = new WebAppContext();
webApp.setContextPath(conf.getServerContextPath());
webApp.addServlet(new ServletHolder(new DefaultServlet()), "/*");
contexts.addHandler(webApp);
webApp.addFilter(new FilterHolder(MyFilter.class), "/*", EnumSet.allOf(DispatcherType.class));
webApp.setInitParameter("org.eclipse.jetty.servlet.Default.dirAllowed","true");
return webApp;
}
private static void setupRestApiContextHandler(WebAppContext webapp, Configuration conf) {
final ServletHolder servletHolder =
new ServletHolder(new org.glassfish.jersey.servlet.ServletContainer());
servletHolder.setInitParameter("javax.ws.rs.Application", MyServer.class.getName());
servletHolder.setName("rest");
servletHolder.setForcedPath("rest");
webapp.setSessionHandler(new SessionHandler());
webapp.addServlet(servletHolder, "/api/*");
webapp.setInitParameter("shiroConfigLocations", "ShiroFilePathURI");
webapp
.addFilter(ShiroFilter.class, "/MyRestApiPath/*", EnumSet.allOf(DispatcherType.class))
.setInitParameter("staticSecurityManagerEnabled", "true");
webapp.addEventListener(new EnvironmentLoaderListener());
}
}
我的 ClassA 看起来像这样:
public class ClassA implements InterfaceService {
@Inject
public ClassA(SomeClass instances){
//initialize some variable
}
}
有一个注入 InterfaceService 的 REST 类:
@Path("/my_rest")
@Produces("application/json")
@Singleton
public class RestApi {
private InterfaceService interfaceService;
@Inject
public RestApi(InterfaceService interfaceService) {
this.interfaceService = interfaceService;
}
}
当我运行这段代码时,我得到了这个异常:
“javax.servlet.ServletException:MultiException 有 4 个异常。它们是:1. java.lang.IllegalStateException:找不到 org.glassfish.hk2.api.Immediate 的活动上下文 2.java.lang.IllegalStateException:尝试时为 SystemDescriptor 创建服务( implementation=ClassA contract={InterfaceService}"
在 MyServer 类中,当我将类与 Singleton 范围绑定时,它按预期工作。IE
bind(ClassA.class).to(InterfaceService.class).in(Singleton.class);
然后,如果我将我的 RestApi 类更新到下面
@Path("/my_rest")
@Produces("application/json")
@Singleton
public class RestApi {
private ClassA classA;
@Inject
public RestApi(ClassA classA) {
this.classA = classA;
}
}
然后一切都按预期工作,即时范围也是如此。
对我来说,需要将范围更改为立即,因为我需要在服务器启动时在类中执行某些操作。另外,我不能使用ClassA
RestApi 中的引用,因为将来会有其他InterfaceService
接口的实现,所以我需要在RestApi
. 关于我需要做什么以使代码在即时范围内工作的任何线索,并将其绑定到InterfaceService
解决方案
推荐阅读
- docker - Docker 作曲家和卷
- typescript - 如果创建了新的后端请求,则取消先前的后端请求
- angular - 带有角度材料工具提示的 ag 网格
- android - 未设置环境变量 ANDROID_HOME
- makefile - DEVC++ Makefile.win 已更改。从磁盘重新加载?错误
- c# - .net 核心 Web 应用程序 - 什么在使用所有这些内存?小可枚举 vs 大可枚举 vs 流响应
- angular - 在命令提示符下找不到模块“@angular/compiler”
- kubernetes - ./kvtctl.sh 处的 vitess 安装失败远程错误:rpc 错误:代码 = 不可用 desc = 传输正在关闭
- jquery - 在溢出隐藏区域中向上滑动的文本效果
- templates - 在 Vue 中跨组件共享模板