Jersey:检测控制器类何时创建

时间:2017-01-13 13:41:25

标签: java rest jax-rs jersey-2.0

我使用Jersey 2.24实现了一个JAX-RS服务器应用程序。

我使用Guice-HK2网桥,以便控制器类(注释为@Path)注入来自Guice的依赖项,而不是Jersey / HK2。

但是,HK2仍会创建@Path注释类本身的实例。

有没有办法可以插入Jersey / HK2,以便在创建@Path注释类时通知我?像某种生命周期的听众?每当Jersey / HK2创建@Path注释类时,我想对该类进行一些注册/记录。

如果Guice正在实际创建@Path带注释的类,我想我可以使用泛型Provider来做,但在这种情况下不可用,因为Jersey / HK2正在创建实际的实例

谢谢!

1 个答案:

答案 0 :(得分:0)

我认为最不干扰的方式就是使用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

中的完整示例

另见: