Difference between context:annotation-config vs context:component-scan – context:annotation-config与context:component-scan之间的区别

最后修改: 2019年 9月 11日

中文/混合/英文(键盘快捷键:t)

1. Overview

1.概述

In this tutorial, we’re going to learn about the differences between two major XML configuration elements of Spring: <context:annotation-config> and <context:component-scan>.

在本教程中,我们将学习Spring的两个主要XML配置元素之间的区别。<context:annotation-config><context:component-scan>

2. Bean Definitions

2.Bean的定义

As we all know, Spring provides us with two ways to define our beans and dependencies: XML configuration and Java annotations. We can also categorize Spring’s annotations under two groups: dependency injection annotations and bean annotations.

众所周知,Spring为我们提供了两种方法来定义我们的beans和依赖关系。XML 配置和 Java 注释。我们还可以将Spring的注解归为两组。依赖注入注释bean注释

Prior to annotations, we had to manually define all our beans and dependencies in XML configuration files. Now thanks to Spring’s annotations, it can automatically discover and wire all our beans and dependencies for us. So, we can at least eliminate the XML needed for beans and dependencies.

在有注解之前,我们必须在XML配置文件中手动定义所有的Bean和依赖关系。现在多亏了Spring的注解,它可以自动为我们发现和连接所有的Bean和依赖关系。因此,我们至少可以消除Bean和依赖关系所需的XML。

However, we should remember that annotations are useless unless we activate them. In order to activate them, we can add either <context:annotation-config> or <context:component-scan> on top of our XML file.

然而,我们应该记住,注释是无用的,除非我们激活它们为了激活它们,我们可以在我们的XML文件上面添加<context:annotation-config>或者<context:component-scan>

In this section, we’ll see how <context:annotation-config> and <context:component-scan> differ from each other in terms of their ways of activating annotations.

在这一节中,我们将看到<context:annotation-config><context:component-scan>在激活注释的方式上有什么不同。

3. Annotation Activation by <context:annotation-config>

3.通过<context:annotation-config>激活注释

The <context:annotation-config> annotation is mainly used to activate the dependency injection annotations. @Autowired, @Qualifier@PostConstruct, @PreDestroy, and @Resource are some of the ones that <context:annotation-config> can resolve.

<context:annotation-config>注解主要用于激活依赖注入注解。@Autowired@Qualifier@PostConstruct@PreDestroy,和@Resource是一些<上下文。annotation-config> 可以解决。

Let’s make a simple example to see how <context:annotation-config> can simplify the XML configuration for us.

让我们做一个简单的例子,看看<context:annotation-config>如何为我们简化XML配置。

First, let’s create a class with a dependency field:

首先,让我们创建一个具有依赖性字段的类。

public class UserService {
    @Autowired
    private AccountService accountService;
}
public class AccountService {}

Now, let’s define our beans.

现在,让我们来定义我们的Bean。

<bean id="accountService" class="AccountService"></bean>

<bean id="userService" class="UserService"></bean>

Before going further let’s point out that we still need to declare beans in the XML. That is because <context:annotation-config> activates the annotations only for the beans already registered in the application context.

在进一步讨论之前,让我们指出,我们仍然需要在XML中声明Bean。这是因为<context:annotation-config>只为已经在应用上下文中注册的Bean激活注释

As can be seen here, we annotated the accountService field using @Autowired. @Autowired tells Spring that this field is a dependency that needs to be automatically wired by a matching bean.

从这里可以看出,我们使用@Autowired注释了accountService字段。@Autowired告诉Spring,这个字段是一个依赖关系,需要由一个匹配的Bean自动连接。

If we didn’t use @Autowired, then we would need to set the accountService dependency manually:

如果我们不使用@Autowired,那么我们就需要手动设置accountService依赖性。

<bean id="userService" class="UserService">
    <property name="accountService" ref="accountService"></property>
</bean>

Now, we can refer to our beans and dependencies in a unit test:

现在,我们可以在单元测试中引用我们的bean和依赖关系。

@Test
public void givenContextAnnotationConfig_whenDependenciesAnnotated_thenNoXMLNeeded() {
    ApplicationContext context
      = new ClassPathXmlApplicationContext("classpath:annotationconfigvscomponentscan-beans.xml");

    UserService userService = context.getBean(UserService.class);
    AccountService accountService = context.getBean(AccountService.class);

    Assert.assertNotNull(userService);
    Assert.assertNotNull(accountService);
    Assert.assertNotNull(userService.getAccountService());
}

Hmm, something is wrong here. It looks like Spring isn’t wiring the accountService even though we annotated it by @Autowired. It looks like @Autowired is not active. In order to solve this issue, we’ll simply add the following line on top of our XML file:

嗯,这里有些不对劲。看起来Spring并没有为accountService布线,尽管我们用@Autowired注释了它。看起来@Autowired没有被激活。为了解决这个问题,我们只需在我们的XML文件上面添加以下一行。

<context:annotation-config/>

4. Annotation Activation by <context:component-scan>

4.通过<context:component-scan>激活注释

As similar to <context:annotation-config>, <context:component-scan> can recognize and process the dependency injection annotations too. Moreover, <context:component-scan> recognizes bean annotations that <context:annotation-config> doesn’t detect.

<context:annotation-config>类似,<context:component-scan>也可以识别和处理依赖注入注释。此外,<context:component-scan>可以识别<context:annotation-config>没有检测到的bean注解

Basically, <context:component-scan> detects the annotations by package scanning. To put it differently, it tells Spring which packages need to be scanned to look for the annotated beans or components.

基本上,<context:component-scan>通过包扫描检测注释。换句话说,它告诉Spring哪些包需要被扫描以寻找被注释的Bean或组件。

@Component@Repository, @Service, @Controller, @RestController, and @Configuration are several ones that <context:component-scan> can detect.

@Component, @Repository, @Service,@Controller, @RestController, 和 @Configuration 是几个 <上下文。component-scan>可以检测到

Now let’s see how we can simplify our previous example:

现在我们来看看如何简化我们之前的例子。

@Component
public class UserService {
    @Autowired
    private AccountService accountService;
}

@Component
public class AccountService {}

Here, the @Component annotation marks our classes as beans. Now, we can clean out all the bean definitions from our XML file. And of course, we need to keep the <context:component-scan> on top of it:

这里,@Component注解将我们的类标记为Bean。现在,我们可以从我们的XML文件中清理出所有的bean定义。当然,我们还需要在上面保留<context:component-scan>

<context:component-scan
  base-package="com.baeldung.annotationconfigvscomponentscan.components" />

Finally, let’s note that Spring will look for the annotated beans and dependencies under the package indicated by the base-package attribute.

最后,让我们注意到,Spring将在base-package属性所指示的包下寻找注释的Bean和依赖。

5. Conclusion

5.总结

In this tutorial, we looked through the differences between <context:annotation-config> and <context:component-scan>.

在本教程中,我们研究了<context:annotation-config><context:component-scan>之间的区别。

Code samples, as always, are over on GitHub.

一如既往,代码样本在GitHub上