我正在尝试创建一个新的启动器。我有一个业务模块,比如ProjectManager,它包含一些用@Component注释的类。在本教程之后,我创建了一个autoconfigure模块,它包含一个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 {
....
}
有效。但根据春天doc。
使用标准的@Configuration类实现自动配置
所以我的问题是,为什么@ComponentScan在这里不起作用?我做错了什么?或者是设计?
答案 0 :(得分:10)
您必须将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);
}
}
干杯
答案 1 :(得分:6)
自动化所有内容要求Application类(使用@SpringBootApplication注释)位于比要扫描的组件更高的“更高”包中。
使用:
package com.example.foo;
用于您的应用程序并将组件放在如下的包中:
package com.example.foo.entities;
答案 2 :(得分:0)
你可以试试以下吗?
@ConditionalOnClass({Project.class})
@Configuration
@EnableAutoConfiguration
@ComponentScan(value = {"com.foo.project"})
public class ProjectAutoConfiguration {
....
}
答案 3 :(得分:0)
我正在开发一个 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 {
}
我认为重点是使用@ComponentScan 注释的bean 必须在定义级别(而不是@Bean 方法/实例级别)进行定义。如果我错了,请纠正我,谢谢。