Java guice:自动绑定泛型类
是否可以自动化泛型类的绑定? 考虑这一点: 通用接口:Java guice:自动绑定泛型类,java,dependency-injection,guice,Java,Dependency Injection,Guice,是否可以自动化泛型类的绑定? 考虑这一点: 通用接口: public interface IAction<T> { T echo(T inst); } public class LongAction implements IAction<Long> { @Override public Long echo(Long inst) {return inst;} } public class StringAction implements
public interface IAction<T> {
T echo(T inst);
}
public class LongAction implements IAction<Long> {
@Override
public Long echo(Long inst) {return inst;}
}
public class StringAction implements IAction<String> {
@Override
public String echo(String inst) {return inst;}
}
公共接口接口接口{
T回声(T仪器);
}
长子类型:
public interface IAction<T> {
T echo(T inst);
}
public class LongAction implements IAction<Long> {
@Override
public Long echo(Long inst) {return inst;}
}
public class StringAction implements IAction<String> {
@Override
public String echo(String inst) {return inst;}
}
public类LongAction实现IAction{
@凌驾
公共长回声(长指令){返回指令;}
}
字符串子类型:
public interface IAction<T> {
T echo(T inst);
}
public class LongAction implements IAction<Long> {
@Override
public Long echo(Long inst) {return inst;}
}
public class StringAction implements IAction<String> {
@Override
public String echo(String inst) {return inst;}
}
public类StringAction实现IAction{
@凌驾
公共字符串回显(字符串指令){return inst;}
}
自定义模块:
公共类CustomModule扩展了AbstractModule{
@Override
protected void configure() {
//do this automagically?
bind(new TypeLiteral<IAction<String>>() {}).to(StringAction.class);
bind(new TypeLiteral<IAction<Long>>() {}).to(LongAction.class);
//
}
@覆盖
受保护的void configure(){
//这是自动的吗?
绑定(new-TypeLiteral(){}).to(StringAction.class);
绑定(new-TypeLiteral(){}).to(LongAction.class);
//
}
}
Main
// i know i can obtain the correct instance
IAction<String> is = injector.getInstance(new Key<IAction<String>>(){});
//我知道我可以获得正确的实例
IAction is=injector.getInstance(新键(){});
是否可以通过某种方式(例如:基本抽象类、反射或其他方式)自动绑定
StringAction
和LongAction
类的绑定?我尝试过使用反射,但没有效果。如果不想显式列出实现,则必须进行某种类路径扫描。例如,番石榴在其类中有一些支持
请注意,类路径扫描在某种程度上与Guice的设计理念背道而驰。为您编写的每一个实现向模块添加一行代码真的需要付出这么多额外的努力吗?我设法欺骗了编译器
class CustomModule extends AbstractModule {
static class Holder<T> {
Class<T> param;
Class<IAction<T>> klass;
Holder(Class<?> p, Class<IAction<T>> k) {
param = (Class<T>) p;
klass = k;
}
}
// this would be similar to the result of classpath scanning
List<IAction<?>> stuff;
public <T> void bindSome(Class<T> typeParameter, Class<IAction<T>> implementation) {
Type parameterizedType = Types.newParameterizedType(IAction.class, typeParameter);
bind((TypeLiteral<IAction<T>>) TypeLiteral.get(parameterizedType)).to(implementation);
}
public CustomModule() {
stuff = new ArrayList<>();
stuff.add(new StringAction());
stuff.add(new LongAction());
}
@Override
protected void configure() {
for (IAction<?> act : stuff) {
System.out.printf("Configuring %s for %s\n", act.getTypeArguments(), act.getClass());
//the following doesn't work because the compiler cannot understand that
//the 1st argument T is the same T in 2nd argument Class<T>
//bindSome(act.getTypeArguments(), act.getClass());
//w00t? compiler is tricked?? <String> is erased, but the holder preserves proper class?
Holder<String> holder = new Holder(act.getTypeArguments(), (Class<IAction<String>>) act.getClass());
bindSome(holder.param, holder.klass);
//this is what I want to avoid doing manually
//bind(new TypeLiteral<IAction<String>>() {}).to(StringAction.class);
}
}
}
类CustomModule扩展了AbstractModule{
静态类持有者{
类参数;
克拉斯类;
支架(p类、k类){
参数=(类)p;
klass=k;
}
}
//这将类似于类路径扫描的结果
列表您想如何自动发现LongAction
、StringAction
等?它们是在一个特定的包中还是什么?如果两个类实现了IAction
?@TavianBarnes它们在一个特定的包中呢?我不介意假设现在没有两个impl用于同一个t
,所以不会有两个IAction
问题不在于类路径扫描。问题在于泛型类型。啊,我没有意识到。你已经找到了解决方案,但我之前已经给出了,例如:谢谢,我在谷歌上搜索了它,但没有找到你的答案。