泽西岛:检测何时创建控制器 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 系统中注册 InterceptionServiceConstructorInterceptor

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

中的完整示例

另请参阅: