Я мигрирую Jetty - Resteasy в Guice
У меня есть сеть. xml для настройки Resteasy
она указывает на подкласс javax.ws.rs.Application
класса для загрузки ресурсов
<listener>
<listener-class>org.jboss.resteasy.plugins.server.servlet.ResteasyBootstrap</listener-class>
</listener>
<servlet>
<servlet-name>Resteasy</servlet-name>
<servlet-class>
org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher
</servlet-class>
<init-param>
<param-name>javax.ws.rs.Application</param-name>
<param-value>com.test.MyWebApplication</param-value>
</init-param>
<init-param>
<param-name>cacheControl</param-name>
<param-value>no-cache, no-store, must-revalidate</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Resteasy</servlet-name>
<url-pattern>/api/*</url-pattern>
<url-pattern>/service/*</url-pattern>
</servlet-mapping>
и в MyWebApplication
Я использую отражение для загрузки всех классов в указанном c пакете
try {
final Set<Class<?>> apiEndpoints = getApiEndpoints();
for (Class<?> endpoint :apiEndpoints) {
singletons.add(endpoint.newInstance());
}
// Initialisation for resteasy ProxyFactory
RegisterBuiltin.register(ResteasyProviderFactory.getInstance());
} catch( Throwable e ) {
...
}
...
public static Set<Class<?>> geApiEndpoints(){
final ConfigurationBuilder builder = new ConfigurationBuilder()
.filterInputsBy(new FilterBuilder().includePackage("com.test.web"))
.setUrls(ClasspathHelper.forPackage("com.test.web"))
.setScanners(new SubTypesScanner(), new TypeAnnotationsScanner());
final Reflections reflectionUtil = builder.build();
return reflectionUtil.getTypesAnnotatedWith(Path.class);
}
Чтобы начать поддерживать Guice, я изменил слушателя и добавил ContextParam
<listener>
<listener-class>org.jboss.resteasy.plugins.guice.GuiceResteasyBootstrapServletContextListener</listener-class>
</listener>
<!-- Guice -->
<context-param>
<param-name>resteasy.guice.modules</param-name>
<param-value>com.test.MyAppModule,org.jboss.resteasy.plugins.guice.ext.JaxrsModule</param-value>
</context-param>
В MyAppModule есть несколько привязок для моих сервисов
bind(AService.class).to(AServiceImpl.class);
bind(BPersistenceService.class).to(BPersistenceServiceImpl.class);
requestStaticInjection(InjectorUtil.class);
То, что я не делаю и ожидаю, что обработчик запросов будет обрабатывать, привязывает ресурсы.
Поскольку GuiceResteasyBootstrapServletContextListener
является расширением ResteasyBootstrap
, я думал, что он позаботится о внедрении служб Guice в конечные точки отдыха после того, как они будут созданы и загружены для повторного использования. но это не так.
Я получаю нулевой указатель на aService в своем классе ресурсов
@Path("/foo")
public class Foo{
private AService aService;
@Inject
public setAServuce(final AService aService){
aService = aService;
}
@GET
@Path(/{id})
public getA(@PathParam("id") String id){
return this.aService.get(id);
}
}
Это будет работать, если я снова переберу все остальные конечные точки и сделаю привязку к ним в AppModule
try {
final Set<Class<?>> apiEndpoints = getApiEndpoints();
for (Class<?> endpoint :apiEndpoints) {
bind(endpoint);
}
// Initialisation for resteasy ProxyFactory
...
}
Но я не хочу загружать классы дважды.
Какие изменения я должен сделать, чтобы Guice вставлял экземпляры в Ресурсы Отдыха?
в примечании, я хочу избежать привязки каждого класса ресурсов в модуле по отдельности.
Заранее спасибо.