Guice动态注入自定义注释

wen*_*ner 7 java inject inversion-of-control guice

我有一些资源,但我不能迭代它并将它们全部绑定,我必须使用密钥来请求资源.所以,我必须动态注入.

我定义了一个注释

@Target({ METHOD, CONSTRUCTOR, FIELD })
@Retention(RUNTIME)
@Documented
@BindingAnnotation
public @interface Res
{
    String value();// the key of the resource
}
Run Code Online (Sandbox Code Playgroud)

像这样用

public class Test
{
    @Inject
    @Res("author.name")
    String name;
    @Inject
    @Res("author.age")
    int age;
    @Inject
    @Res("author.blog")
    Uri blog;
}
Run Code Online (Sandbox Code Playgroud)

我必须处理注释注入@Res,我需要知道注入字段和注释.

这有可能Guice吗?如何?即使是spi?

wen*_*ner 5

我按照CustomInjections进行锻炼

像这样的代码

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);
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)