2017-04-14 9 views
1

CrudSearchable이라는 사용자 지정 주석을 만들고 거기에 몇 가지 특성을 정의했습니다. 그러나 내가 지정하는 속성은 이미 bean에서 볼 수 있습니다. 수동으로 재정의하지 않고도이 값을 얻을 수있는 방법이 있습니까? 속성은 속성 이름이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; 
} 

는에 ParentClass는 주석을 사용하여 문자 클래스이며, applicatable 경우 매핑 된 클래스는 중첩 된 클래스 개체입니다.

답변

0

하는 데 도움이됩니다. 이것이 제가 찾고 있던 것입니다.

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

일단 내가 이것을 사용하면 내가 사용하는 주석을 변경하기 위해 아래의 생성자 메소드를 호출 할 수 있습니다.

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

사용자가 값을 정의하는 대신 값을 변경하는 것이 많은 것처럼 보이지만 코드가 사용자에게 더 친숙하게 느껴질 것이라고 생각합니다.

희망이 있으면 도움이됩니다. 이 게시물에 대한 답변을 찾았습니다 : Modify a class definition's annotation string parameter at runtime. 확인 해봐!

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

희망이 내가 다른 질문에 대한 답을 찾을

+0

게시물을 보내 주셔서 감사합니다. 그러나 값을 하드 코드 한 후에 이미 요소에 액세스 할 수 있지만 콩에서 볼 수있는 경우 클래스에서 볼 수있는 정보를 다시 표시하고 있습니다. 나는 이것을 주석에서 얻고 싶다. 이자형. g @CrudSearchable (attribute = "name", parentClass = MockUser.class) 문자열 이름. @CrudSearchable 문자열 이름으로 대체해야합니다. 어노테이션 코드 내부에서 애트리뷰트 이름과 클래스를 추론한다. 이것이 가능한가? – jDub9