복붙노트

[SPRING] 봄철 자바 주석 스캐닝

SPRING

봄철 자바 주석 스캐닝

이름에 주석을다는 데 필요한 클래스가 거의 없으므로 주석을 다음과 같이 정의했습니다.

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface JsonUnmarshallable {
    public String value();
}

이제이 주석이 필요한 클래스는 다음과 같이 정의됩니다.

@JsonUnmarshallable("myClass")
public class MyClassInfo {
<few properties>
}

특수 효과를 스캔하기 위해 아래 코드를 사용했습니다.

private <T> Map<String, T> scanForAnnotation(Class<JsonUnmarshallable> annotationType) {
    GenericApplicationContext applicationContext = new GenericApplicationContext();
    ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(applicationContext, false);
    scanner.addIncludeFilter(new AnnotationTypeFilter(annotationType));
    scanner.scan("my");
    applicationContext.refresh();
    return (Map<String, T>) applicationContext.getBeansWithAnnotation(annotationType);
}

문제는 리턴 된 맵에 [ "myClassInfo"-> MyClassInfo의 오브젝트]가 있지만 "myClass"를 키로 포함해야한다는 것입니다. 이는 bean 이름이 아닌 Annotation의 값입니다.

이 일을하는 방법이 있습니까?

해결법

  1. ==============================

    1.주석 객체를 가져 와서 값을 꺼내십시오.

    주석 객체를 가져 와서 값을 꺼내십시오.

    Map<String,T> tmpMap = new HashMap<String,T>();
    JsonUnmarshallable ann;
    for (T o : applicationContext.getBeansWithAnnotation(annotationType).values()) {
        ann = o.getClass().getAnnotation(JsonUnmarshallable.class);
        tmpMap.put(ann.value(),o);
    }
    return o;
    

    그게 확실하지 않으면 알려줘.

  2. ==============================

    2.내 경우에는 아래와 같이 썼다.

    내 경우에는 아래와 같이 썼다.

    ClassPathScanningCandidateComponentProvider scanner = new ClassPathScanningCandidateComponentProvider(false);
    scanner.addIncludeFilter(new AnnotationTypeFilter(JsonUnmarshallable.class));
    Set<BeanDefinition> definitions = scanner.findCandidateComponents("base.package.for.scanning");
    
    for(BeanDefinition d : definitions) {
        String className = d.getBeanClassName();
        String packageName = className.substring(0,className.lastIndexOf('.'));
        System.out.println("packageName:" + packageName + " , className:" + className);
    }
    
  3. ==============================

    3.어쩌면 http://scannotation.sourceforge.net/ 프레임 워크를 사용하여이를 구현할 수 있습니다.

    어쩌면 http://scannotation.sourceforge.net/ 프레임 워크를 사용하여이를 구현할 수 있습니다.

    희망이 도움이됩니다.

  4. ==============================

    4.커스텀 BeanNameGenerator를 ClassPathBeanDefinitionScanner에 제공 할 수 있습니다. ClassPathBeanDefinitionScanner는 주석의 값을 찾아이를 bean 이름으로 반환 할 수 있습니다.

    커스텀 BeanNameGenerator를 ClassPathBeanDefinitionScanner에 제공 할 수 있습니다. ClassPathBeanDefinitionScanner는 주석의 값을 찾아이를 bean 이름으로 반환 할 수 있습니다.

    이 라인을 따라 구현하면 효과가 있다고 생각합니다.

    package org.bk.lmt.services;
    
    import java.util.Map;
    import java.util.Set;
    
    import org.springframework.context.annotation.AnnotationBeanNameGenerator;
    public class CustomBeanNameGenerator extends AnnotationBeanNameGenerator{
        @Override
        protected boolean isStereotypeWithNameValue(String annotationType,
                Set<String> metaAnnotationTypes, Map<String, Object> attributes) {
    
            return annotationType.equals("services.JsonUnmarshallable");
        }
    }
    

    이전 스캐너 코드에 다음을 추가하십시오. scanner.setBeanNameGenerator (새 CustomBeanNameGenerator ());

  5. from https://stackoverflow.com/questions/10549458/java-annotation-scanning-with-spring by cc-by-sa and MIT license