【问题标题】:find package name - Spring Boot library查找包名 - Spring Boot 库
【发布时间】:2020-03-14 04:23:50
【问题描述】:

我正在制作一个与 Spring Boot 一起使用的库。这个库定义了一些可以在方法中使用的注解。

如何(在运行时)找到正在使用该库的应用程序包?
我需要这个来扫描带注释的方法。

【问题讨论】:

  • 你想创建 spring boot 启动器吗?
  • 你可以像 Spring 一样扫描 @ComponentScan(basePackages = "package.name") 下的所有类。或者提供另一个自定义注释添加到主类中,使用该库的客户端应用程序可以使用您的自定义注释来声明要扫描的包。
  • @codeMan 仅在必要时才能工作
  • @RajeshDwivedi 第一个怎么办?
  • Spring 已经有了这个代码。请通过 org.springframework.boot.autoconfigure.domain.EntityScanPackages 类。它可以提供更好的了解 spring 是如何处理它的。您可以在同一行上对齐您的实现。 github.com/spring-projects/spring-boot/blob/master/…

标签: spring-boot modularity component-scan


【解决方案1】:

你可以实现BeanFactoryPostProcessor:
1. 使用ConfigurableListableBeanFactory可以迭代BeanDefinition
2.判断bean的class是否有your注解
3.从bean的class名称中获取包

例子:

@Component
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        Set<String> packages = findAnnotationUsagePackages(MyAnnotation.class, beanFactory);
        ...
    }

    private Set<String> findAnnotationUsagePackages(Class<? extends Annotation> annotationClass,
                                                    ConfigurableListableBeanFactory beanFactory) {
        Set<String> annotationUsagePackages = new HashSet<>();

        for (String beanDefinitionName : beanFactory.getBeanDefinitionNames()) {
            BeanDefinition beanDefinition = beanFactory.getBeanDefinition(beanDefinitionName);

            if (beanDefinition instanceof ScannedGenericBeanDefinition) {
                ScannedGenericBeanDefinition genericBeanDefinition = (ScannedGenericBeanDefinition) beanDefinition;

                if (AnnotationUtils.isCandidateClass(genericBeanDefinition.getBeanClass(), annotationClass)) {
                    String beanClassName = genericBeanDefinition.getBeanClassName();

                    if (beanClassName != null) {
                        annotationUsagePackages.add(ClassUtils.getPackageName(beanClassName));

                    }
                }
            }
        }
        return annotationUsagePackages;
    }

}

关于AnnotationUtils.isCandidateClass()

确定给定类是否是携带指定注释的候选者(在类型、方法或字段级别)

另外关注AbstractBeanDefinition.getBeanClass()

抛出:IllegalStateException - 如果 bean 定义没有定义 bean 类,或者指定的 bean 类名尚未解析为实际的 Class

附:您也可以在AnnotationUtils.isCandidateClass 条件块中收集类或元信息

【讨论】:

  • 我的注释只适用于方法,它还能工作吗?
  • yes AnnotationUtils.isCandidateClass(beanClass, myAnnotationClass) 将找到您在方法上指定的注释(如文档中所述,我也检查过它是否有效)
猜你喜欢
  • 1970-01-01
  • 2019-06-03
  • 1970-01-01
  • 2020-01-25
  • 1970-01-01
  • 1970-01-01
  • 2021-10-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多