繁体   English   中英

@ComponentScan 在 Spring Boot AutoConfiguration 类中不起作用?

[英]@ComponentScan doesn't work in Spring boot AutoConfiguration class?

我正在尝试创建一个新的启动器。 我有一个业务模块,比如说 ProjectManager,它包含一些用 @Component 注释的类。 按照教程,我创建了一个自动配置模块,它包含一个 AutoConfiguration 类。 首先,我尝试使用 @ComponentSan 在我的业务模块中查找 bean。

@ComponentScan(value = {"com.foo.project"})
@ConditionalOnClass({Project.class})
@Configuration
public class ProjectAutoConfiguration {
    ....

}

但它不起作用。 我必须添加额外的配置类,如下所示:

@Configuration
@ComponentScan(value = {"com.foo.project"})
@MapperScan(value = {"com.foo.project"})
public class ProjectConfig {
}

然后将其导入到 AutoConfiguration 类中,如下所示:

@Import(ProjectConfig.class)
@ConditionalOnClass({Project.class})
@Configuration
public class ProjectAutoConfiguration {
    ....

}

那行得通。 但是根据 spring 文档

自动配置是用标准的@Configuration 类实现的

所以我的问题是,为什么 @ComponentScan 在这里不起作用? 我做错了什么吗? 还是设计使然?

您必须在主类中使用 compentscan 注释。 这是一个示例代码:

@SpringBootApplication
@ComponentScan("com.foo.project")
public class MainApplication extends SpringBootServletInitializer {

    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
        return application.sources(MainApplication.class);
    }

    public static void main(String[] args) {
        new MainApplication().configure(new SpringApplicationBuilder(MainApplication.class)).run(args);
    }
}

干杯

自动一切都需要 Application 类(用 @SpringBootApplication 注释)位于比您要扫描的组件“更高”的包中。

使用:

package com.example.foo;

用于您的应用程序并将组件放入一个包中,例如:

package com.example.foo.entities;

另见https://docs.spring.io/spring-boot/docs/current/reference/html/using-boot-using-springbootapplication-annotation.html

您可以尝试以下吗?

@ConditionalOnClass({Project.class})
@Configuration
@EnableAutoConfiguration
@ComponentScan(value = {"com.foo.project"})
public class ProjectAutoConfiguration {
    ....

}

我正在开发一个 SDK 项目。 它需要依赖SDK的应用程序在启动期间扫描SDK中特定包下的bean。

在 autowire 配置类上使用 @ComponentScan 进行注释不会生效。

然后我尝试使用@Import 批注导入类实现的接口ImportBeanDefinitionRegistrar (接口由在处理@Configuration 类时注册附加bean 定义的类型实现。在bean 定义级别操作时很有用(而不是@Bean 方法/实例级别)是需要的或必要的)。

在 ImportBeanDefinitionRegistrar 实现类中,我将一个用 @ComponentScan 注释的类注册为 bean。 再次运行应用程序,它按预期工作。

代码如下:

自动配置类:

@Configuration
@Import(TestConfigRegistar.Registrar.class)
public class TestClientAutoCofiguration {

}

注册类:

public class TestConfigRegistar {
public static class Registrar implements ImportBeanDefinitionRegistrar {
    private static final String BEAN_NAME = "componentScanConfig";

    @Override
    public void registerBeanDefinitions(AnnotationMetadata annotationMetadata, 
                                                 BeanDefinitionRegistry registry) {
        GenericBeanDefinition beanDefinition = new GenericBeanDefinition();
        beanDefinition.setBeanClass(ComponentScanConfig.class);
        beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
        beanDefinition.setSynthetic(true);
        registry.registerBeanDefinition(BEAN_NAME, beanDefinition);
    }
}
}

带有@ComponentScan 注释的类

// Leave an empty value of @ComponentScan will let spring scan
// current class package and all sub-packages
@ComponentScan
public class ComponentScanConfig {
}

我相信重点是必须在定义级别(而不是@Bean 方法/实例级别)定义用@ComponentScan 注释的bean。 如果我错了,请纠正我,谢谢。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM