@ComponentScan在Spring Boot自动配置类中无效?

14

我正在尝试创建一个新的启动器。我有一个业务模块,比如ProjectManager,它包含一些用@Component注释的类。按照教程,我创建了一个自动配置模块,其中包含一个AutoConfiguration类。首先,我尝试使用@ComponentScan查找我的业务模块中的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在这里不起作用?我做错了什么吗?还是这是设计上的问题?

4个回答

15

您需要在主类中使用“@ComponentScan”注释。以下是示例代码:

@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);
    }
}

干杯


你的意思是带有主方法的类吗? - Dongqing
将其添加到主类确实有效。那么您的意思是@SpringBoot中的@ComponentScan只能与主类一起使用吗? - Dongqing
我不这么认为。但这样更好。主类位于项目的根目录中。因此,组件扫描会扫描包,并且这些包位于根目录的子文件夹中。 - emoleumassi

8

很好。不要添加扫描注释。你的答案非常好。 - Kumaresan Perumal

0

你能试一下以下的代码吗?

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

}

0

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

使用@Autowired配置类上的@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 {
}

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接