泽西岛:检测何时创建控制器 Class
Jersey: Detect when Controller Class is Created
我已经使用 Jersey 2.24 实现了一个 JAX-RS 服务器应用程序。
我使用 Guice-HK2 桥,这样控制器 classes(那些用 @Path
注释的)注入了来自 Guice 的依赖项,而不是 Jersey/HK2.
然而,HK2 仍然创建 @Path
注释的 classes 本身的实例。
有没有一种方法可以插入 Jersey/HK2,以便在创建 @Path
注释 class 时通知我?像某种生命周期监听器?每次 Jersey/HK2 创建一个 @Path
注释 class 我想做一些 registering/logging class.
如果 Guice 正在实际创建 @Path
注释 class 我想我可以使用通用 Provider
来完成它,但在这种情况下不可用,因为 Jersey/HK2 正在创建实际实例。
谢谢!!
我认为侵入性最小的方法是只使用 AOP。 HK2 提供 AOP。您可以做的是创建一个 ConstructorInterceptor
。像
public class LoggingConstructorInterceptor implements ConstructorInterceptor {
private static final Logger LOG
= Logger.getLogger(LoggingConstructorInterceptor.class.getName());
@Override
public Object construct(ConstructorInvocation invocation) throws Throwable {
Constructor ctor = invocation.getConstructor();
LOG.log(Level.INFO, "Creating: {0}", ctor.getDeclaringClass().getName());
// returned instance from constructor invocation.
Object instance = invocation.proceed();
LOG.log(Level.INFO, "Created Instance: {0}", instance.toString());
return instance;
}
}
然后创建一个 InterceptorService
以仅使用带有 @Path
注释的 类 的拦截器
public class PathInterceptionService implements InterceptionService {
private static final ConstructorInterceptor CTOR_INTERCEPTOR
= new LoggingConstructorInterceptor();
private final static List<ConstructorInterceptor> CTOR_LIST
= Collections.singletonList(CTOR_INTERCEPTOR);
@Override
public Filter getDescriptorFilter() {
return BuilderHelper.allFilter();
}
@Override
public List<MethodInterceptor> getMethodInterceptors(Method method) {
return null;
}
@Override
public List<ConstructorInterceptor> getConstructorInterceptors(Constructor<?> ctor) {
if (ctor.getDeclaringClass().isAnnotationPresent(Path.class)) {
return CTOR_LIST;
}
return null;
}
}
然后只需在 DI 系统中注册 InterceptionService
和 ConstructorInterceptor
new ResourceConfig()
.register(new AbstractBinder(){
@Override
public void configure() {
bind(PathInterceptionService.class)
.to(InterceptionService.class)
.in(Singleton.class);
bind(LoggingConstructorInterceptor.class)
.to(ConstructorInterceptor.class)
.in(Singleton.class);
}
});
请参阅 this Gist
中的完整示例
另请参阅:
我已经使用 Jersey 2.24 实现了一个 JAX-RS 服务器应用程序。
我使用 Guice-HK2 桥,这样控制器 classes(那些用 @Path
注释的)注入了来自 Guice 的依赖项,而不是 Jersey/HK2.
然而,HK2 仍然创建 @Path
注释的 classes 本身的实例。
有没有一种方法可以插入 Jersey/HK2,以便在创建 @Path
注释 class 时通知我?像某种生命周期监听器?每次 Jersey/HK2 创建一个 @Path
注释 class 我想做一些 registering/logging class.
如果 Guice 正在实际创建 @Path
注释 class 我想我可以使用通用 Provider
来完成它,但在这种情况下不可用,因为 Jersey/HK2 正在创建实际实例。
谢谢!!
我认为侵入性最小的方法是只使用 AOP。 HK2 提供 AOP。您可以做的是创建一个 ConstructorInterceptor
。像
public class LoggingConstructorInterceptor implements ConstructorInterceptor {
private static final Logger LOG
= Logger.getLogger(LoggingConstructorInterceptor.class.getName());
@Override
public Object construct(ConstructorInvocation invocation) throws Throwable {
Constructor ctor = invocation.getConstructor();
LOG.log(Level.INFO, "Creating: {0}", ctor.getDeclaringClass().getName());
// returned instance from constructor invocation.
Object instance = invocation.proceed();
LOG.log(Level.INFO, "Created Instance: {0}", instance.toString());
return instance;
}
}
然后创建一个 InterceptorService
以仅使用带有 @Path
public class PathInterceptionService implements InterceptionService {
private static final ConstructorInterceptor CTOR_INTERCEPTOR
= new LoggingConstructorInterceptor();
private final static List<ConstructorInterceptor> CTOR_LIST
= Collections.singletonList(CTOR_INTERCEPTOR);
@Override
public Filter getDescriptorFilter() {
return BuilderHelper.allFilter();
}
@Override
public List<MethodInterceptor> getMethodInterceptors(Method method) {
return null;
}
@Override
public List<ConstructorInterceptor> getConstructorInterceptors(Constructor<?> ctor) {
if (ctor.getDeclaringClass().isAnnotationPresent(Path.class)) {
return CTOR_LIST;
}
return null;
}
}
然后只需在 DI 系统中注册 InterceptionService
和 ConstructorInterceptor
new ResourceConfig()
.register(new AbstractBinder(){
@Override
public void configure() {
bind(PathInterceptionService.class)
.to(InterceptionService.class)
.in(Singleton.class);
bind(LoggingConstructorInterceptor.class)
.to(ConstructorInterceptor.class)
.in(Singleton.class);
}
});
请参阅 this Gist
中的完整示例另请参阅: