空指针异常 - 依赖注入 - Google Guice
Null Pointer Exception - Dependency Injection - Google Guice
我在 Jersey 的 reader 拦截器中注入依赖项时收到 NullPointerException,我创建该拦截器是为了拦截特定的传入请求。
这是我创建的 ReaderInterceptor 的代码,我试图在其中注入所需的依赖项。
public class RegisterServiceInterceptor implements ReaderInterceptor {
@Inject
private CustomerBackendManager customerBackendManager;
public static final Logger LOGGER = LoggerFactory.getLogger(RegisterServiceInterceptor.class);
@Override
public Object aroundReadFrom(ReaderInterceptorContext context) throws IOException, WebApplicationException {
InputStream is = context.getInputStream();
String body = new BufferedReader(new InputStreamReader(is)).lines().collect(Collectors.joining("\n"));
ObjectMapper mapper = new ObjectMapper();
try {
SampleObject sampleObject = mapper.readValue(body, SampleObject.class);
customerBackendManager.createDatabase(sampleObject.getDatabaseName());
} catch (JsonGenerationException | JsonMappingException e) {
LOGGER.info(e.getMessage());
}
InputStream in = new ByteArrayInputStream(body.getBytes(StandardCharsets.UTF_8));
context.setInputStream(in);
return context.proceed();
}
}
我在 customerBackendManager.createDatabase(...);
行收到 NPE。依赖项未注入此 class。
我已将此依赖项的配置定义为
public class ExampleAddonMicroserviceModule extends AbstractModule
implements ConfigurationAwareModule<ExampleAddonMicroserviceConfiguration> {
@Provides
@Singleton
public CustomerBackendManager customerBackendManager(DBI dbi, Injector injector) {
CustomerBackendManager manager = dbi.onDemand(CustomerBackendManagerImpl.class);
injector.injectMembers(manager);
return manager;
}
@Provides
@Singleton
public RegisterServiceInterceptor registerServiceInterceptor(DBI dbi, Injector injector) {
RegisterServiceInterceptor manager = dbi.onDemand(RegisterServiceInterceptor.class);
injector.injectMembers(manager);
return manager;
}
}
我需要添加什么额外的配置才能将此依赖项添加到此 class?
我找到了解决这个问题的方法。
问题是 Jersey 需要配置中的拦截器 class,它需要在满足拦截条件时调用它,这导致 RegisterServiceInterceptor class 被初始化两次。因此,RegisterServiceInterceptor class.
中的 NPE
我在单独的配置文件中定义了该配置
@Provider
public class ResourceFilteringConfiguration implements DynamicFeature {
@Override
public void configure(ResourceInfo resourceInfo, FeatureContext context) {
if (RegistrationService.class.equals(resourceInfo.getResourceClass())
&& resourceInfo.getResourceMethod().getName().equals("register")) {
context.register(RegisterServiceInterceptor.class);
}
}
}
在 context.register(RegisterServiceInterceptor.class);
行中,我传递了 RegisterServiceInterceptor class 本身,这导致它在达到依赖项配置(问题中提到的)之前进行初始化。所以,这个拦截器被初始化了两次,这导致了这个问题。我把配置文件代码改成了
@Provider
public class ResourceFilteringConfiguration implements DynamicFeature {
@Inject
private RegisterServiceInterceptor registerServiceInterceptor;
@Override
public void configure(ResourceInfo resourceInfo, FeatureContext context) {
if (RegistrationService.class.equals(resourceInfo.getResourceClass())
&& resourceInfo.getResourceMethod().getName().equals("register")) {
context.register(registerServiceInterceptor);
}
}
}
您一定已经注意到,我所做的更改是将 RegisterServiceInterceptor 的对象传递给配置,它开始正常工作。
我在 Jersey 的 reader 拦截器中注入依赖项时收到 NullPointerException,我创建该拦截器是为了拦截特定的传入请求。
这是我创建的 ReaderInterceptor 的代码,我试图在其中注入所需的依赖项。
public class RegisterServiceInterceptor implements ReaderInterceptor {
@Inject
private CustomerBackendManager customerBackendManager;
public static final Logger LOGGER = LoggerFactory.getLogger(RegisterServiceInterceptor.class);
@Override
public Object aroundReadFrom(ReaderInterceptorContext context) throws IOException, WebApplicationException {
InputStream is = context.getInputStream();
String body = new BufferedReader(new InputStreamReader(is)).lines().collect(Collectors.joining("\n"));
ObjectMapper mapper = new ObjectMapper();
try {
SampleObject sampleObject = mapper.readValue(body, SampleObject.class);
customerBackendManager.createDatabase(sampleObject.getDatabaseName());
} catch (JsonGenerationException | JsonMappingException e) {
LOGGER.info(e.getMessage());
}
InputStream in = new ByteArrayInputStream(body.getBytes(StandardCharsets.UTF_8));
context.setInputStream(in);
return context.proceed();
}
}
我在 customerBackendManager.createDatabase(...);
行收到 NPE。依赖项未注入此 class。
我已将此依赖项的配置定义为
public class ExampleAddonMicroserviceModule extends AbstractModule
implements ConfigurationAwareModule<ExampleAddonMicroserviceConfiguration> {
@Provides
@Singleton
public CustomerBackendManager customerBackendManager(DBI dbi, Injector injector) {
CustomerBackendManager manager = dbi.onDemand(CustomerBackendManagerImpl.class);
injector.injectMembers(manager);
return manager;
}
@Provides
@Singleton
public RegisterServiceInterceptor registerServiceInterceptor(DBI dbi, Injector injector) {
RegisterServiceInterceptor manager = dbi.onDemand(RegisterServiceInterceptor.class);
injector.injectMembers(manager);
return manager;
}
}
我需要添加什么额外的配置才能将此依赖项添加到此 class?
我找到了解决这个问题的方法。
问题是 Jersey 需要配置中的拦截器 class,它需要在满足拦截条件时调用它,这导致 RegisterServiceInterceptor class 被初始化两次。因此,RegisterServiceInterceptor class.
中的 NPE我在单独的配置文件中定义了该配置
@Provider
public class ResourceFilteringConfiguration implements DynamicFeature {
@Override
public void configure(ResourceInfo resourceInfo, FeatureContext context) {
if (RegistrationService.class.equals(resourceInfo.getResourceClass())
&& resourceInfo.getResourceMethod().getName().equals("register")) {
context.register(RegisterServiceInterceptor.class);
}
}
}
在 context.register(RegisterServiceInterceptor.class);
行中,我传递了 RegisterServiceInterceptor class 本身,这导致它在达到依赖项配置(问题中提到的)之前进行初始化。所以,这个拦截器被初始化了两次,这导致了这个问题。我把配置文件代码改成了
@Provider
public class ResourceFilteringConfiguration implements DynamicFeature {
@Inject
private RegisterServiceInterceptor registerServiceInterceptor;
@Override
public void configure(ResourceInfo resourceInfo, FeatureContext context) {
if (RegistrationService.class.equals(resourceInfo.getResourceClass())
&& resourceInfo.getResourceMethod().getName().equals("register")) {
context.register(registerServiceInterceptor);
}
}
}
您一定已经注意到,我所做的更改是将 RegisterServiceInterceptor 的对象传递给配置,它开始正常工作。