I have some resource, but I can not iterator it and bind them all, I have to use the key to request the resource.So, I have to dynamic inject.
I define an annotation like
@Target({ METHOD, CONSTRUCTOR, FIELD })
@Retention(RUNTIME)
@Documented
@BindingAnnotation
public @interface Res
{
String value();// the key of the resource
}
use like this
public class Test
{
@Inject
@Res("author.name")
String name;
@Inject
@Res("author.age")
int age;
@Inject
@Res("author.blog")
Uri blog;
}
I have to handle the injection annotated by @Res
and I need to know the
inject field and the annotation.
Is this possible in Guice
and how ? even with spi ?
I work out follow CustomInjections
Code like this
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);
}
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With