我有一些资源,但我无法对其进行迭代并将它们全部绑定, 我必须使用密钥来请求资源。所以,我必须动态注入。
我定义了一个像
这样的注释@Target({ METHOD, CONSTRUCTOR, FIELD })
@Retention(RUNTIME)
@Documented
@BindingAnnotation
public @interface Res
{
String value();// the key of the resource
}
像这样使用
public class Test
{
@Inject
@Res("author.name")
String name;
@Inject
@Res("author.age")
int age;
@Inject
@Res("author.blog")
Uri blog;
}
我必须处理由@Res
注释的注入,我需要知道
注入字段和注释。
这可能在Guice
以及如何实现?即使是spi?
答案 0 :(得分:4)
像这样的代码
public class PropsModule extends AbstractModule
{
private final Props props;
private final InProps inProps;
private PropsModule(Props props)
{
this.props = props;
this.inProps = InProps.in(props);
}
public static PropsModule of(Props props)
{
return new PropsModule(props);
}
@Override
protected void configure()
{
bindListener(Matchers.any(), new TypeListener()
{
@Override
public <I> void hear(TypeLiteral<I> type, TypeEncounter<I> encounter)
{
Class<? super I> clazz = type.getRawType();
if (!clazz.isAnnotationPresent(WithProp.class))
return;
for (Field field : clazz.getDeclaredFields())
{
Prop prop = field.getAnnotation(Prop.class);
if (prop == null)
continue;
encounter.register(new PropInjector<I>(prop, field));
}
}
});
}
class PropInjector<T> implements MembersInjector<T>
{
private final Prop prop;
private final Field field;
PropInjector(Prop prop, Field field)
{
this.prop = prop;
this.field = field;
field.setAccessible(true);
}
@Override
public void injectMembers(T instance)
{
try {
Class<?> targetType = field.getType();
Object val = inProps.as(prop.value(), targetType);
field.set(instance, val);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
}
}
}