2017-04-14 4 views
1

Inferieren Ich habe eine benutzerdefinierte Annotation namens CrudSearchable erstellt und dort einige Attribute definiert. Die Attribute, die ich zuweise, sind jedoch bereits von der Bean aus sichtbar. Gibt es eine Möglichkeit, diese Werte zu erfassen, ohne sie manuell neu definieren zu müssen?Wie Informationen in benutzerdefinierte Annotation mit Java

// Bean 
public class MockUser { 

    @CrudSearchable(attribute = "name", 
        parentClass = MockUser.class) 
    private String name; 

    @CrudSearchable(attribute = "group", 
        parentClass = MockUser.class, 
        mappedClass = MockGroup.class) 
    private MockGroup group; 

    // Get/Set, Equals/Hashcode, etc... 
} 

// Annotation Class 
@Retention(RetentionPolicy.RUNTIME) 
@Target(ElementType.FIELD) 
public @interface CrudSearchable { 

    String attribute(); 

    boolean searchable() default true; 

    Class<?> mappedClass() default CrudSearchable.class; 

    Class<?> parentClass() default Object.class; 
} 

Wo Attribut der Attributname ist, ist Parent die Klasse wörtliche die Anmerkung verwenden, und kartiert Klasse ist das verschachtelte Klasse-Objekt, wenn applicatable.

Antwort

0

ich die Antwort auf eine andere Frage. Das ist, was ich gesucht habe.

// Put in Reflector.java 

/** 
* Changes the annotation value for the given key of the given annotation to newValue and returns 
* the previous value. 
*/ 
@SuppressWarnings("unchecked") 
public static Object changeAnnotationValue(Annotation annotation, String key, Object newValue){ 
    Object handler = Proxy.getInvocationHandler(annotation); 
    Field f; 
    try { 
     f = handler.getClass().getDeclaredField("memberValues"); 
    } catch (NoSuchFieldException | SecurityException e) { 
     throw new IllegalStateException(e); 
    } 
    f.setAccessible(true); 
    Map<String, Object> memberValues; 
    try { 
     memberValues = (Map<String, Object>) f.get(handler); 
    } catch (IllegalArgumentException | IllegalAccessException e) { 
     throw new IllegalStateException(e); 
    } 
    Object oldValue = memberValues.get(key); 
    if (oldValue == null || oldValue.getClass() != newValue.getClass()) { 
     throw new IllegalArgumentException(); 
    } 
    memberValues.put(key,newValue); 
    return oldValue; 
} 

Sobald ich dies habe, kann ich die Methode unten im Konstruktor aufrufen, um die Anmerkungen zu ändern, die ich verwende.

// Put in Service Class 

public void modifySearchable(Class<?> clazz) { 
    for(Field f : clazz.getDeclaredFields()){ 
     CrudSearchable[] searchableArray = f.getDeclaredAnnotationsByType(CrudSearchable.class); 

     for(CrudSearchable searchable : searchableArray){ 
      if(searchable == null){ 
       continue; 
      } 

      Reflector.alterAnnotation(searchable, "attribute", f.getName()); 
      Reflector.alterAnnotation(searchable, "parentClass", clazz); 

      if(!(searchable.mappedAttribute().equals(""))){ 
       String mappedGetter = "get" + 
         searchable.mappedAttribute().substring(0, 1).toUpperCase() + 
         searchable.mappedAttribute().substring(1); 

       Reflector.alterAnnotation(searchable, "mappedClass", f.getType()); 
       Reflector.alterAnnotation(searchable, "mappedGetter", mappedGetter); 
      } 
     } 
    } 
} 

// Changed Bean 

@Id 
@GeneratedValue 
@Column(name = "MOCK_USER_ID") 
private Long id; 

@Column(name = "MOCK_USER_NAME") 
@CrudSearchable 
private String name; 

@ManyToOne 
@JoinColumn(name = "MOCK_GROUP", nullable = false) 
@CrudSearchable(mappedAttribute = "name") 
private MockGroup group; 

public MockUser(){ 
    super(); 
    new Searchable<>().modifySearchable(this.getClass()); 
} 

scheint wie eine Menge, die Werte zu ändern, anstatt die Benutzer definieren sie zu haben, aber ich glaube, dass es den Code benutzerfreundlicher machen.

Ich hoffe, das hilft jemandem. Ich habe die Antwort auf diesen Beitrag gefunden: Modify a class definition's annotation string parameter at runtime. Hör zu!

0
MockUser obj = new MockUser(); 
Class<?> c = obj.getClass(); 
Field[] fields = c.getDeclaredFields();  
CrudSearchable annotation = fields[0].getAnnotation(CrudSearchable.class); 
System.out.println("attribute: " + annotation.attribute() + 
        "searchable: " + annotation.searchable()); 

hoffe, das hilft

+0

Vielen Dank für Ihren Beitrag, aber ich bin bereits in der Lage, auf die Elemente zuzugreifen, sobald ich die Werte fest codiere, aber wenn Sie in der Bohne sehen, bin ich die Informationen aus der Klasse. Ich möchte das aus der Annotation holen. e. g @CrudSearchable (Attribut = "Name", ParentClass = MockUser.class) String-Name; sollte mit @CrudSearchable String name ersetzt werden; und ich schließe den Attributnamen und die Klasse aus dem Annotationscode ab. Ist das möglich? – jDub9

Verwandte Themen