Over a million developers have joined DZone.

A Use Case for Spring Component Scan

DZone's Guide to

A Use Case for Spring Component Scan

In most cases, you might want to use explicit bean creation over Spring magic for a variety of reasons. But sometimes, that same Spring magic is exactly what you need.

· Java Zone ·
Free Resource

Download Microservices for Java Developers: A hands-on introduction to frameworks and containers. Brought to you in partnership with Red Hat.

Regular readers of my work know I’m a big proponent of the Spring framework, but I’m quite opinionated in the way it should be used. For example, I favor explicit object instantiation and explicit component wiring over self-annotated classes, component scanning, and autowiring.


Though those concepts are used by many Spring developers, my experience has taught me they are not always fully understood. Some explanation is in order.

Self-Annotated Classes

Self-annotated classes are classes which define how they will be instantiated by Spring via annotations on the classes themselves. @Component, @Controller, @Service and @Repository are the usual self-annotated classes found in most Spring projects.

class MySelfAnnotatedClass

The main disadvantage of self-annotated classes is the hard coupling between the class and the bean. For example, it’s not possible to instantiate 2 singleton beans of the same class, as in explicit creation. Worse, it also couples the class to the Spring framework itself.

Note that @Configuration classes are also considered to be self-annotated.

Component Scanning

Self-annotated classes need to be listed and registered in the context. This can be done explicitly:

class MyConfig {
    fun myClass() = MySelfAnnotatedClass()

However, the most widespread option is to let the Spring framework search for every self-annotated class on the project classpath and register them according to the annotations.

@Configuration @ComponentScan
class MyConfig


Some beans require dependencies in order to be initialized. Wiring the dependency into the dependent bean can be either:

  • explicit: it’s the developer’s responsibility to tell which beans will fulfill the dependency.
  • implicit (or auto): the Spring framework is responsible to provide the dependency. In order to do that, a single bean must be eligible.

Regarding the second option, please re-read an old post of mine for its related problems.

Sometimes, however, there’s no avoiding autowiring. When bean Bean1 defined in configuration fragment Config1 depends on bean Bean2 defined in fragment Config2, the only possible injection option is autowiring.

class Config2 {

    fun bean2() = Bean2()

class Config1 {

    @Bean @Autowired
    fun bean1(bean2: Bean2) = Bean1(bean2)

In the above snippet, autowiring is used without self-annotated classes.

Reinventing the Wheel

This week, I found myself re-implementing Spring Boot’s actuator in a legacy non-Spring Boot application.

The architecture is dead simple: the HTTP endpoint returns a Java object (or a list of them) serialized through the Jackson library. Every endpoint might return a different object, and each can be serialized using a custom serializer.

I’ve organized the project in a package-per-endpoint way (as opposed to package-per-layer), and have already provided several endpoints. I’d like people to contribute other endpoints, and I want it to be as simple as possible. In particular, they should only:

  1. Declare controllers
  2. Declare configuration classes
  3. Instantiate Jackson serializers

The rest should be taken care of by generic code written by me.

The Right Usage of Autowiring

Controllers and configuration classes are easily taken care of by using @ComponentScan on the main configuration class located in the project’s main package. But what about serializers?

Spring is able to collect all beans of a specific class registered into a context into a list. That means that every package will declare its serializers independently, and common code can take care of the registration:

@Configuration @EnableWebMvc @ComponentScan
class WebConfiguration : WebMvcConfigurerAdapter() {

    private lateinit var serializers: List<StdSerializer<*>>

    override fun configureMessageConverters(converters: MutableList<HttpMessageConverter<*>>) {
        converters.add(MappingJackson2HttpMessageConverter().apply {
            objectMapper.registerModule(SimpleModule().apply {
                serializers.forEach { addSerializer(it) }

The magic happens on lines 6 and 7 above. This configuration class has already been written, and new packages don’t need to do anything, serializers will be part of the list.

Here’s an example of such a configuration class, declaring a serializer bean:

class FooConfiguration {

    fun fooSerializer()  = FooSerializer()

class FooSerializer : StdSerializer<Foo>(Foo::class.java) {

Even better, if packages need to be modularized further into full-fledged JARs, this setup will work in the exact same way without any change.


A better understanding of self-annotated classes, component scanning, and autowiring is beneficial to all Spring developers.

Moreover, while they have a lot of drawbacks in “standard” beans class, it’s not only perfectly acceptable but even an advantage to do so within the scope of configuration classes. In projects designed in a package-by-feature way, it improves modularization and decoupling.

Download Building Reactive Microservices in Java: Asynchronous and Event-Based Application Design. Brought to you in partnership with Red Hat

spring autowired ,spring component scan ,spring beans ,java ,tutorial ,modularization

Published at DZone with permission of

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}