【问题标题】:Getting Class annotation for a given Spring Bean获取给定 Spring Bean 的类注解
【发布时间】:2020-01-31 12:23:12
【问题描述】:

我有两个自定义注释,如下所述。

  • CustomAnnotationMain 是一个基于 Spring 组件的注解。
  • CustomAnnotationChild 是一个基于 Spring Bean 的注解。

下面是使用 2 个自定义注解的代码 sn-p。

@CustomAnnotationMain(value = "parent") 
public class MainClass{

    @CustomAnnotationChild(value = "child1")
    public ObjectBuilder getObject1() {
        // logic
    }

    @CustomAnnotationChild(value = "child2")
    public ObjectBuilder getObject2() {
        // logic
    }
}

问题:如何获取所有 CustomAnnotationMain 注释类的列表以及作为组件一部分可用的所有 bean + 注释信息?

我执行了以下操作以获取所有使用 @CustomAnnotationChild 注释的 bean。但我不确定如何访问 bean 可用的类。我需要访问给定 bean 的 @CustomAnnotationMain。

    allBuilders = context.getBeansOfType(ObjectBuilder.class);

PS:这不是基于 Spring Boot 的项目。我只使用弹簧核心库。

【问题讨论】:

    标签: spring spring-bean


    【解决方案1】:

    我做了类似的事情。引入了 Proxyable 接口,需要找到所有带有该接口注解的 bean 或者为所有定义的接口创建 proxy。

    https://github.com/StanislavLapitsky/SpringSOAProxy/blob/master/core/src/main/java/org/proxysoa/spring/service/ProxyableScanRegistrar.java

    在您的情况下,您应该将 Proxyable 替换为您的 CustomAnnotationMain。

    可以更改 ClassPathScanningCandidateComponentProvider 定义的逻辑以反映您的过滤器(我只需要那里的接口)。

    public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {
        LOG.debug("Registering @Proxyable beans");
        // Get the ProxyableScan annotation attributes
        Map<String, Object> annotationAttributes = metadata.getAnnotationAttributes(ProxyableScan.class.getCanonicalName());
    
        if (annotationAttributes != null) {
            String[] basePackages = (String[]) annotationAttributes.get("value");
    
            if (basePackages.length == 0) {
                // If value attribute is not set, fallback to the package of the annotated class
                basePackages = new String[]{((StandardAnnotationMetadata) metadata).getIntrospectedClass().getPackage().getName()};
            }
    
            // using these packages, scan for interface annotated with Proxyable
            ClassPathScanningCandidateComponentProvider provider = new ClassPathScanningCandidateComponentProvider(false, environment) {
                // Override isCandidateComponent to only scan for interface
                @Override
                protected boolean isCandidateComponent(AnnotatedBeanDefinition beanDefinition) {
                    AnnotationMetadata metadata = beanDefinition.getMetadata();
                    return metadata.isIndependent() && metadata.isInterface();
                }
            };
            provider.addIncludeFilter(new AnnotationTypeFilter(Proxyable.class));
    
            ControllerFactory factory = getControllerFactory((DefaultListableBeanFactory) registry);
    
            // Scan all packages
            for (String basePackage : basePackages) {
                for (BeanDefinition beanDefinition : provider.findCandidateComponents(basePackage)) {
                    try {
                        Class c = this.getClass().getClassLoader().loadClass(beanDefinition.getBeanClassName());
                        if (!hasImplementingClass(c, basePackages)) {
                            //creating missing beans logic is skipped
                        }
                    } catch (ClassNotFoundException e) {
                        throw new SOAControllerCreationException("cannot create proxy for " + beanDefinition.getBeanClassName());
                    }
                }
            }
        }
    }
    

    希望对你有帮助

    【讨论】:

    • 感谢您的回复。我假设您建议修改我当前的类以实现一个接口以使其工作。但不幸的是,我不能那样做。 :(
    • 您可以查看ClassPathScanningCandidateComponentProviderprotected boolean isCandidateComponent(AnnotatedBeanDefinition beanDefinition)AnnotationMetadata 有方法 boolean hasAnnotation(String annotationName)boolean hasMetaAnnotation(String metaAnnotationName)。看起来是你的情况
    猜你喜欢
    • 1970-01-01
    • 2014-02-21
    • 2016-10-31
    • 2017-02-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多