【问题标题】:Jersey HK2 injection with a Generic class具有通用类的 Jersey HK2 注入
【发布时间】:2020-01-27 15:40:16
【问题描述】:

我有一个看起来像这样的通用类。

public class DAO<T> {

    private final Class<T> clazz;

    public DAO(Class<T> clazz) {
        this.clazz = clazz;
    }
}

我在由 Jersey 提供支持的 RestFull api 中使用它。 我经常使用它,我现在必须像这样实例化它:

private final DAO<Account> accountDAO = new DAO<>(Account.class);

我想使用 Jersey 的 HK2 注入库来实例化它。 像这样

@Inject
private final DAO<Account> accountDAO

我很难找到一种通过类型推断进行这种注入的方法。 我看过工厂(org.glassfish.hk2.api.Factory),但还没有找到处理推理的方法。

有什么想法可以做到吗?

【问题讨论】:

    标签: generics dependency-injection jersey-2.0 hk2


    【解决方案1】:

    我在这里假设您在 DAO 实现中实际上需要 clazz

    因为我总是有这个解决方案,所以我也将在这里提出建议:您可以定义一个自定义注入解析器来处理您的 DAO 的创建(确保将其注册到您的应用程序/活页夹) 使用泛型。如果您不需要clazz,代码可能会简化很多。

    不过,我希望有一个更简单的方法,但正如我所说,这是可行的:

    @Classes({ MyTest.TestInjectionResolver.class, MyTest.DAO.class })
    public class MyTest extends HK2Runner {
    
        @Inject
        private DAO<Integer> service;
    
        @Test
        public void doTest() {
            assertNotNull(service);
        }
    
        @Service
        public static class DAO<T> {
    
            private final Class<T> clazz;
    
            @Inject
            public DAO(final Class<T> clazz) {
                this.clazz = clazz;
            }
        }
    
        @Singleton
        @Rank(Integer.MAX_VALUE)
        @org.jvnet.hk2.annotations.Service
        public static class TestInjectionResolver
                implements org.glassfish.hk2.api.InjectionResolver<Inject> {
    
            private final org.glassfish.hk2.api.InjectionResolver<Inject> injectionResolver;
    
            @Inject
            public TestInjectionResolver(
                    @Named(org.glassfish.hk2.api.InjectionResolver.SYSTEM_RESOLVER_NAME) final org.glassfish.hk2.api.InjectionResolver<Inject> injectionResolver) {
                this.injectionResolver = injectionResolver;
            }
    
            @SuppressWarnings("unchecked")
            @Override
            public Object resolve(final Injectee injectee, final ServiceHandle<?> root) {
                final Type requiredType = injectee.getRequiredType();
                if (requiredType instanceof ParameterizedType) {
                    final Type rawType = ((ParameterizedType) requiredType).getRawType();
                    if (rawType.equals(DAO.class)) {
                        final Class<?> typeArg = (Class<?>) ((ParameterizedType) requiredType).getActualTypeArguments()[0];
                        try {
                            return ((Class<DAO<?>>) rawType).getConstructor(Class.class).newInstance(typeArg);
                        } catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException | NoSuchMethodException | SecurityException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                    }
                }
                return injectionResolver.resolve(injectee, root);
            }
    
            @Override
            public boolean isConstructorParameterIndicator() {
                return injectionResolver.isConstructorParameterIndicator();
            }
    
            @Override
            public boolean isMethodParameterIndicator() {
                return injectionResolver.isMethodParameterIndicator();
            }
    
        }
    
    }
    

    【讨论】:

      猜你喜欢
      • 2014-12-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-07-13
      • 1970-01-01
      • 1970-01-01
      • 2023-04-04
      相关资源
      最近更新 更多