문제

나는 많은 수업이 있으며,이 수업은 Java 반사를 사용하여 구성됩니다 (어떤 이유로 든). 이제 나는 주석이 달린 필드에 값을 사후에 주입해야합니다. @PostInject.

public class SomeClass {
  @PostInject
  private final String someString = null;

  public void someMethod() {
    // here, someString has a value.
  }
}

내 질문은 다음과 같습니다. 반사를 사용하여 필드를 설정하는 빠른 방법은 무엇입니까?
많은 수업에서 자주이 작업을 수행해야하므로 성능이 관련된 이유입니다.

직관으로 내가 할 일은이 의사 코드로 표시됩니다.

  • 수업의 모든 분야를 얻으십시오
    clazz.getFields();
  • @postinject로 주석이 달린 점검
    eachField.getAnnotation(PostInject.class);
  • 이 필드를 액세스 할 수 있도록하십시오
    eachAnnotatedField.setAccessible(true);
  • 특정 값으로 설정하십시오
    eachAnnotatedField.set(clazz, someValue);

모든 필드를 얻는 것이 가장 느린 일이라는 것이 두렵습니다.
처음부터 그것을 알면 누군가가 필드를 얻을 수 있습니까?

참고 : 클래스가 일부 인터페이스를 구현할 수는 없으므로 메소드를 사용하여 필드를 설정할 수 있습니다. 나는 필요하다 포조스.

참고 2 : 필드 포스트 필드 주입을 원하는 이유 : API 사용자의 관점에서 최종 필드를 사용할 수 있어야합니다. 또한, API에 의해 선험적으로 유형과 필드 수를 알 수없는 경우 인터페이스를 사용하여 필드 초기화를 달성하는 것은 불가능합니다.

Note2B : 사용자의 관점에서 최종 계약은 다음과 같습니다. ~ 아니다 고장난. 그것은 최종적으로 유지됩니다. 먼저 필드가 초기화되고 변경할 수 없습니다. 그건 그렇고 :이 개념을 사용하는 많은 API가 있습니다. 그 중 하나는 JAXB (JDK의 일부)입니다.

도움이 되었습니까?

해결책

객체를 구성하고 객체 자체에서 얻은 주석이 달린 필드 세트를 저장하거나 별도의 클래스 맵을 주석화 된 필드로 유지하여 1 ~ 3 단계를 수행하는 것은 어떻습니까?

그런 다음 객체에서 주입 된 필드를 업데이트해야 할 때 객체 또는 별도의 맵에서 세트를 검색하고 4 단계를 수행하십시오.

다른 팁

그것이 좋은지 모르겠지만 이 프로젝트 원하는대로 할 것 같습니다. 인용하다:

Java 1.5 및 제네릭과 호환되는 의존성이없는 클래스 및 해당 분야와 관련된 반사 유틸리티 및 기타 유틸리티 세트.

유틸리티는 고성능 작동을위한 반사 데이터를 캐시하지만 약한/소프트 캐싱을 사용하여 열린 클래스 로더를 유지하고 캐시가 메모리에 영구적으로 존재하게합니다. 캐싱 메커니즘을 자신의 것으로 무시할 수있는 능력이 지원됩니다.

또 다른 옵션은 처음부터 관련된 몇 가지 필드를 알고 있다고 말하면서 해당 필드 나 방법 만 요청하는 것입니다.

예 : 참조 getDeclaredMethod 또는 getDeclaredField 안에 Java/lang/class.html

객체 구성에 종속성을 주입 할 수있는 기존 프레임 워크를 악용 할 수 있습니다. 예를 들어 봄은 그렇게 할 수 있습니다 AspectJ 직조와 함께. 일반적인 아이디어는 스프링 레벨에서 Bean 의존성을 정의하고 객체 생성을 조언하기 위해 대상 클래스를 표시하는 것입니다. 실제 종속성 해상도 로직은 클래스 바이트 코드에 직접 주입됩니다 (컴파일 또는로드 타임 직조를 사용할 수 있음).

반사로 무엇이든 할 수있는 가장 빠른 방법은 가능한 한 실제 반사 API 클래스를 캐시하는 것입니다. 예를 들어, 나는 최근에 아주 최근에 다른 일이 아닌 지남 관리자를 만들었습니다. 저는 모든 사람들이 어떤 시점에서 내가 할 수있는 일 중 하나라고 생각합니다.

Object o = ...
BeanPropertyController c = BeanPropertyController.of(o);

for (String propertyName : c.getPropertyNames()) {
        if (c.access(propertyName) == null && 
            c.typeOf(propertyName).equals(String.class)) {
                c.mutate(propertyName, "");
        }
}

그것이 작동하는 방식은 기본적으로 콩의 모든 특성을 lazyload하는 하나의 컨트롤러 객체를 가지고 있다는 것입니다.참고 : 일부 마법이 관련되어 있습니다) 그런 다음 실제 컨트롤러 객체가 살아있는 한 재사용합니다. 내가 말할 수있는 것은 메소드 객체 자체를 저장함으로써 나는 그 물건을 망할 빠른 물건으로 바꿀 수 있다는 것입니다. 나는 그것을 매우 자랑스럽게 생각하고 심지어 저작권 등을 분류 할 수 있다고 가정하는 것을 고려하는 것도 고려합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top