I have a generic class that looks like this.
public class DAO<T> {
private final Class<T> clazz;
public DAO(Class<T> clazz) {
this.clazz = clazz;
}
}
I use it within a RestFull api powered by Jersey. I use it very often and I have to instanciate it like this for now :
private final DAO<Account> accountDAO = new DAO<>(Account.class);
I would like instantiate it using Jersey's HK2 injection library. Like this
@Inject
private final DAO<Account> accountDAO
I am having trouble finding a way to do that kind of injection with type inference. I have looked at factories (org.glassfish.hk2.api.Factory), but haven't found a way to handle inference.
Any ideas how it could be done?
I am making the assumption here that you actually need clazz
in your DAO
implementation
As I always have this solution up my sleeve, I am going to suggest it here as well: You could define a custom Injection Resolver that handles the creation of your DAO
(make sure to register it with your application/binder) using generics. If you dont need the clazz
, the code could probably be simplified a lot.
Still, I hope there is an easier way, but as I said, this works:
@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();
}
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.