Джерси HK2 для инъекций класса Generi c - PullRequest
2 голосов
/ 27 января 2020

У меня есть обобщенный класс c, который выглядит следующим образом.

public class DAO<T> {

    private final Class<T> clazz;

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

Я использую его в API RestFull, работающем на Джерси. Я использую его очень часто, и сейчас мне нужно создать его следующим образом:

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

Я хотел бы создать его экземпляр с помощью библиотеки инъекций HK2 Джерси. Вот так

@Inject
private final DAO<Account> accountDAO

У меня возникли проблемы с поиском способа сделать такую ​​инъекцию с выводом типа. Я посмотрел на фабрики (org.glassfi sh .hk2.api.Factory), но не нашел способа справиться с выводом.

Есть идеи, как это можно сделать?

1 Ответ

0 голосов
/ 29 января 2020

Я предполагаю, что вам действительно нужно clazz в вашей DAO реализации

Поскольку у меня всегда есть это решение в моем рукаве, я собираюсь предложить его и здесь: вы могли бы определите пользовательский Injection Resolver, который обрабатывает создание вашего 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();
        }

    }

}
...