2014-06-12 36 views
6

Ho alcune risorse, ma non posso iterarlo e legarle tutte, Devo usare la chiave per richiedere la risorsa. Quindi, devo iniettare dinamicamente.Guice dynamic injection con annotazione personalizzata

mi definiscono un'annotazione come

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

uso come questo

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

devo gestire l'iniezione annotato da @Res e ho bisogno di sapere il campo iniettare e l'annotazione.

E 'possibile in Guice e come? anche con spi?

+0

possibile duplicato di https://stackoverflow.com/questions/5704918/custom-guice-binding-annotations-with-parameters e https : //stackoverflow.com/questions/41958321/guicebinding-annotations-with-attributes – Phil

risposta

3

mi alleno seguire CustomInjections

codice come questo

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); 
      } 
     } 
    } 
}