我有一个使用Jersey 2.25的项目(HK2 2.5-b30)。最初,我使用的是HK2-Guice Bridge。但是,在某些情况下,这似乎意外地失败了(特别是,当Guice正在执行注入时,使用Guice中配置的自定义注释对字符串进行注释的情况将正常工作,但在HK2执行注入时会无声地失败)。因为同一个物体的注入方式可能会有所不同,所以我很害怕同时使用它们。
我现在正在改变一切使用HK2,但遗憾的是,在某些Guice成功的情况下,HK2似乎失败了。特别是,似乎HK2不喜欢注入没有明确配置类型的地方。 Guice很高兴只是创建这些类的新实例并递归注入,但HK2并没有那么多。例如,
1. org.glassfish.hk2.api.UnsatisfiedDependencyException: There was no object available for injection at SystemInjecteeImpl(requiredType=TimeRangeRequestValidator,parent=GetWatchlistEventsImpl,qualifiers={},position=-1,optional=false,self=false,unqualified=null,1218743359)
如您所见,错误消息根本不是很有帮助。它应该能够创建一个TimeRangeRequestValidator
,它引用了一些其他对象,Guice能够毫无问题地创建所有这些对象。在HK2和Guice之间是否有一些不同的行为列表,所以我可以找出为什么这不起作用?
请注意TimeRangeRequestValidator
是一个用@Singleton
注释的类(不是接口),它有一个默认的公共构造函数和一个用Inject
注释的字段。 Guice在实例化时没有任何问题。
答案 0 :(得分:2)
你也可以使用贪婪的JustInTimeResolver。我在下面写了一篇:
@Singleton
@Visibility(DescriptorVisibility.LOCAL)
public class GreedyResolver implements JustInTimeInjectionResolver {
private final ServiceLocator locator;
@Inject
private GreedyResolver(ServiceLocator locator) {
this.locator = locator;
}
@Override
public boolean justInTimeResolution(Injectee failedInjectionPoint) {
Type type = failedInjectionPoint.getRequiredType();
if (type == null) return false;
Class<?> clazzToAdd = null;
if (type instanceof Class) {
clazzToAdd = (Class<?>) type;
}
else if (type instanceof ParameterizedType) {
Type rawType = ((ParameterizedType) type).getRawType();
if (rawType instanceof Class) {
clazzToAdd = (Class<?>) rawType;
}
}
if (clazzToAdd == null) return false;
if (clazzToAdd.isInterface()) return false;
ServiceLocatorUtilities.addClasses(locator, clazzToAdd);
return true;
}
}
使用上面的解析器时应该小心,因为它会在ServiceLocator中添加您可能没想到的内容。注入像Strings或其他类似的东西也可能不会很好。不过,可能适用于您的用例。
如果您的注射点正在注入接口,则无效!
答案 1 :(得分:1)
有a few extra steps you need个配置HK2来自动填充您的服务:
@Contract
注释了您的界面,并使用@Service
ServiceLocator
个实例。请注意,具体或如何适用于您取决于您使用的框架(如球衣)。请参阅Using HK2 with Jersey。