首页 > 解决方案 > @ComponentScan 注解适用于非 @Configuration 类

问题描述

Spring 参考文档说明如下:

Spring 可以自动检测原型类并使用 ApplicationContext 注册相应的 BeanDefinition 实例...

要自动检测这些类并注册相应的 bean,您需要将 @ComponentScan 添加到您的 @Configuration 类...

我创建了一个简单的示例来测试 Spring 框架的自动检测功能:

/**
 * Java-based configuration class which defines root package to start scanning from.
 */
@ComponentScan
public class ComponentScanPackageMarker {
}

/**
 * Class annotated with <b>stereotype</b> annotation is a candidate for automatic detection and registering as
 * {@link BeanDefinition} instance.
 */
@Component
public class Pen {

    private Ink ink;

    @Autowired
    public Pen(Ink ink) {
        this.ink = ink;
    }
}

/**
 * Auto-detected class which will be used as auto-wiring candidate for another auto-detected component.
 */
@Component
public class Ink {
}

ComponentScanPackageMarker类故意省略了@Configuration 注释。我已经测试了组件扫描和自动装配功能。令我惊讶的是,一切都很顺利:

@Test
public void shouldAutoDetectAndRegisterBeans() {
    try (AnnotationConfigApplicationContext context =
                 new AnnotationConfigApplicationContext(ComponentScanPackageMarker.class)) {
        Pen pen = context.getBean(Pen.class);
        Assert.assertNotNull(pen);
        Ink ink = context.getBean(Ink.class);
        Assert.assertNotNull(ink);
    }
}

这种组件扫描行为是故意的吗?为什么即使没有 @Configuration 注释它也能工作?

标签: javaspringspring-ioc

解决方案


是的。我认为@ComponentScan 的工作是扫描给定的包并注册使用 Stereotype 注释(@Component、@Configuration、@Service、@Repository)注释的 bean,如果发现任何 @Configuration 的工作是注册方法(用 @Bean 注释)返回值作为容器中的 bean。

如果我错了,请纠正我。


推荐阅读