Spring   发布时间:2022-04-09  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了java – 如何从@ComponentScan包获取接口列表大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。

我想实现类似于Spring Data的东西.

开发人员可以定义一些接口,向接口添加自定义注释以标记它们(我的代码将为接口创建代理实例)并通过@Autowire将它们用于必要的服务.

在spring初始化期间,我需要获得所有接口的列表(正确注释)<为接口创建动态代理并将它们注入必要的位置. 代理创建,创建bean注入很好.现在的问题是:="" 如何查找所有接口的列表?="">一个单独的罐子里)并且有任何名称.扫描类路径上存在的所有类需要太多时间. 我找到了the question,但它需要基础包才能启动.

试过一个基于思解决方案,但它再次需要基础包或者从root开始需要非常大的时间来扫描所有可用的类.

Reflections reflections = new Reflections("...");
Set<>

所以我需要一个完整的基础包列表Spring扫描在包中找到我的接口(必须要快得多).

信息在SpringContext中绝对可用.我试图调试并看看basePackages []是如何初始化的,但是有很多私有类/方法用于初始化,我只是没有看到如何从ApplicationContext正确访问basePackages.

最佳答案
解决方案1:春天的方式

最简单的答案是遵循spring子项目(引导,数据……)如何实现这种类型的要求.它们通常定义一个自定义组合注释,该注释启用该功能并定义一组要扫描的包.

例如,给出这个注释:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Import({MyInterfaceScanRegistrar.class})
public @interface MyInterfaceScan {

  String[] value() default {};
}

其中value定义要扫描的包,而@Import启用MyInterfaceScan检测.

然后创建ImportBeanDefinitionRegistrar.这个类将能够创建bean定义

public class MyInterfaceScanRegistrar implements ImportBeanDeFinitionRegistrar,EnvironmentAware {
  private Environment environment;

  @Override
  public void setEnvironment(Environment environment) {
    this.environment = environment;
  }

  @Override
  public void registerBeanDeFinitions(AnnotationMetadata Metadata,BeanDeFinitionRegistry registry) {
    // Get the MyInterfaceScan Annotation attributes
    MapMetadata.getAnnotationAttributes(MyInterfaceScan.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 MyCustomBean
      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(MyCustomBean.class));

      // Scan all packages
      for (String basePackage : basePackages) {
        for (BeanDeFinition beanDeFinition : provider.findCandidateComponents(basePackagE)) {
          // Do the stuff about the bean deFinition
          // For example,redefine it as a bean factory with custom atribute... 
          // then register it
          registry.registerBeanDeFinition(generateAName(),beanDeFinition);
          System.out.println(beanDeFinition);
        }
      }
    }
  }
}

这是逻辑的核心. bean定义可以被操作并重新定义为具有属性的bean工厂,或者使用来自接口的生成类重新定义.

@H_79_1@myCustomBean是一个简单的注释:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyCustomBean {

}

哪个可以注释一个接口:

@myCustomBean
public interface Class1 {

}

解决方案2:提取组件扫描

提取@ComponentScan中定义的包的代码会更复杂.

你应该创建一个@L_673_44@并模仿ConfigurationClassPostProcessor

>使用具有ComponentScan属性的声明类(例如,从ConfigurationClassPostProcessor中提取)迭代bean注册表以获取bean定义:

public void postProcessBeanDeFinitionRegistry(BeanDeFinitionRegistry registry) {
  List<>FinitionHolder> configCandidates = new ArrayList<>FinitionHolder>();
  String[] candidatenames = registry.getBeanDeFinitionNames();
  for (String beAnname : candidatenames) {
    if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef,this.MetadataReaderFactory)) {
      // Extract component scan
    }
  }
}

>像Spring一样提取这些属性

SetfigUtils.attributesForRepeatable(
        sourceClass.getMetadata(),ComponentScans.class,ComponentScan.class);

>然后扫描包并注册bean定义,就像第一个解决方案一样

大佬总结

以上是大佬教程为你收集整理的java – 如何从@ComponentScan包获取接口列表全部内容,希望文章能够帮你解决java – 如何从@ComponentScan包获取接口列表所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。