球衣注入 AbstractBinder 没有调用配置
jersey injection AbstractBinder isn't calling configure
答案:
非常感谢所有看过这篇文章的人,尤其是@Andbdrew。在他的帮助下,我让它工作了,代码在 https://github.com/dabraham02124/injection/tree/feature 。我将看看我是否可以减少它 "annotations do magic",并且实际上有代码调用其他代码,但它正在 "feature" 分支上工作。
原问题:
我正在尝试在 jersey 2.7 应用程序中注入资源。它不工作。我收到以下错误:
2019-04-20 22:06:06,004 WARN [qtp1142020464-16] o.e.j.s.ServletHandler -
javax.servlet.ServletException: A MultiException has 3 exceptions. They are:
1. org.glassfish.hk2.api.UnsatisfiedDependencyException: There was no object available for injection at Injectee(requiredType=StringHolder,parent=EntryPoint,qualifiers={}),position=-1,optional=false,self=false,unqualified=null,1295211193)
2. java.lang.IllegalArgumentException: While attempting to resolve the dependencies of org.sweatshop.injection.EntryPoint errors were found
3. java.lang.IllegalStateException: Unable to perform operation: resolve on org.sweatshop.injection.EntryPoint
我已经遵循了我在所有教程中看到的所有内容,例如但不限于;
- https://riptutorial.com/jersey/example/23632/basic-dependency-injection-using-jersey-s-hk2 .
- https://mjremijan.blogspot.com/2016/09/cdi-inject-beans-into-path-jax-rs.html
- https://jersey.github.io/documentation/2.7/ioc.html
我试过在不同的地方添加各种注释,我已经阅读了我能找到的所有 Whosebug 页面,我没有看到任何变化。
最小的例子可以在 https://github.com/dabraham02124/injection 找到。第一次提交没有注入,并且有效。第二次提交确实有注入和抛出。
对于那些想查看此页面上的代码的人,这里是我认为 重要的部分:
资源class
@Path("/")
@RequestScoped
public class EntryPoint {
@Inject
public StringHolder stringHolder;
@GET
@Produces(MediaType.TEXT_HTML)
public Response homePage() {
return Response.ok(stringHolder.getString()).build();
}
}
应用class
@ApplicationPath("/")
public class App extends ResourceConfig {
private final MyServer jettyServer;
private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(App.class);
public App(MyServer jettyServer) {
this.jettyServer = jettyServer;
}
public static void main(String[] args) throws Exception {
final ServletContextHandler context = getContext();
final MyServer jettyServer = new MyServer(8080, context);
prepJettyServlet(context);
log.info("about to start up");
new App(jettyServer).runServer();
}
private void register() {
log.info("start register");
register(EntryPoint.class);
register(StringHolder.class);
register(new AbstractBinder() {
@Override
protected void configure() {
log.info("start bind singleton"); //These three lines never get called
bind(new StringHolder("injected string")).to(StringHolder.class);
log.info("end bind singleton");
}
});
log.info("end register");
}
注入单例class
@RequestScoped
public class StringHolder {
private final String string;
public StringHolder(String string) {
this.string = string;
}
public String getString() {
return string;
}
}
有趣的是,日志显示我在 Binder 上调用 register,但我从未看到 configure
被调用的证据。
帮忙?我正在拔头发,我已经秃了...
您可以使用 Feature
来完成此操作,如 this answer 中所述(我无法让他们的第一种方法与您的球衣版本相匹配)。
@Provider
public final class StartupListener implements Feature {
private final ServiceLocator serviceLocator;
@Inject
public StartupListener(ServiceLocator serviceLocator) {
this.serviceLocator = serviceLocator;
}
@Override
public boolean configure(FeatureContext context) {
ServiceLocatorUtilities.bind(serviceLocator, new AbstractBinder() {
@Override
protected void configure() {
bind(new StringHolder("injected string")).to(StringHolder.class);
}
});
return true;
}
}
答案:
非常感谢所有看过这篇文章的人,尤其是@Andbdrew。在他的帮助下,我让它工作了,代码在 https://github.com/dabraham02124/injection/tree/feature 。我将看看我是否可以减少它 "annotations do magic",并且实际上有代码调用其他代码,但它正在 "feature" 分支上工作。
原问题:
我正在尝试在 jersey 2.7 应用程序中注入资源。它不工作。我收到以下错误:
2019-04-20 22:06:06,004 WARN [qtp1142020464-16] o.e.j.s.ServletHandler - javax.servlet.ServletException: A MultiException has 3 exceptions. They are: 1. org.glassfish.hk2.api.UnsatisfiedDependencyException: There was no object available for injection at Injectee(requiredType=StringHolder,parent=EntryPoint,qualifiers={}),position=-1,optional=false,self=false,unqualified=null,1295211193) 2. java.lang.IllegalArgumentException: While attempting to resolve the dependencies of org.sweatshop.injection.EntryPoint errors were found 3. java.lang.IllegalStateException: Unable to perform operation: resolve on org.sweatshop.injection.EntryPoint
我已经遵循了我在所有教程中看到的所有内容,例如但不限于;
- https://riptutorial.com/jersey/example/23632/basic-dependency-injection-using-jersey-s-hk2 .
- https://mjremijan.blogspot.com/2016/09/cdi-inject-beans-into-path-jax-rs.html
- https://jersey.github.io/documentation/2.7/ioc.html
我试过在不同的地方添加各种注释,我已经阅读了我能找到的所有 Whosebug 页面,我没有看到任何变化。
最小的例子可以在 https://github.com/dabraham02124/injection 找到。第一次提交没有注入,并且有效。第二次提交确实有注入和抛出。
对于那些想查看此页面上的代码的人,这里是我认为 重要的部分:
资源class
@Path("/")
@RequestScoped
public class EntryPoint {
@Inject
public StringHolder stringHolder;
@GET
@Produces(MediaType.TEXT_HTML)
public Response homePage() {
return Response.ok(stringHolder.getString()).build();
}
}
应用class
@ApplicationPath("/")
public class App extends ResourceConfig {
private final MyServer jettyServer;
private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(App.class);
public App(MyServer jettyServer) {
this.jettyServer = jettyServer;
}
public static void main(String[] args) throws Exception {
final ServletContextHandler context = getContext();
final MyServer jettyServer = new MyServer(8080, context);
prepJettyServlet(context);
log.info("about to start up");
new App(jettyServer).runServer();
}
private void register() {
log.info("start register");
register(EntryPoint.class);
register(StringHolder.class);
register(new AbstractBinder() {
@Override
protected void configure() {
log.info("start bind singleton"); //These three lines never get called
bind(new StringHolder("injected string")).to(StringHolder.class);
log.info("end bind singleton");
}
});
log.info("end register");
}
注入单例class
@RequestScoped
public class StringHolder {
private final String string;
public StringHolder(String string) {
this.string = string;
}
public String getString() {
return string;
}
}
有趣的是,日志显示我在 Binder 上调用 register,但我从未看到 configure
被调用的证据。
帮忙?我正在拔头发,我已经秃了...
您可以使用 Feature
来完成此操作,如 this answer 中所述(我无法让他们的第一种方法与您的球衣版本相匹配)。
@Provider
public final class StartupListener implements Feature {
private final ServiceLocator serviceLocator;
@Inject
public StartupListener(ServiceLocator serviceLocator) {
this.serviceLocator = serviceLocator;
}
@Override
public boolean configure(FeatureContext context) {
ServiceLocatorUtilities.bind(serviceLocator, new AbstractBinder() {
@Override
protected void configure() {
bind(new StringHolder("injected string")).to(StringHolder.class);
}
});
return true;
}
}