Difference between <context:annotation-config> vs <context:component-scan>

1. Overview

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>.

2. Bean Definitions

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.

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.

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.

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.

3. Annotation Activation by <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.

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

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 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
.

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.

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

<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:

@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:

<context:annotation-config/>

4. Annotation Activation by <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
.

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.

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

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:

<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.

5. Conclusion

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

Code samples, as always, are
over on
GitHub
.

Leave a Reply

Your email address will not be published.