Why is @ComponentScan behaving this way?

Viewed 36

I created a simple Spring Boot app. In the main() method I commented @SpringBootApplication annotation and SpringApplication.run(Main.class, args) call. I added a class A and annotated it with @Component.

I then created a context and tried to retrieve a bean with Spring Core but for some reason which I do not understand, it behaves in different ways:

  • If I have the configuration class in the same package as main class and I name the bean as the component (component is A and bean method is A a()), then the bean will be retrieved, without @ComponentScan.
  • If I have the configuration class in the same package as main class and I name the bean some other name than the component but still return component type (component is A and bean method is A getA()), then the bean will be retrieved only if I provide @ComponentScan with the value to the current package or no value at all. For some reason, it creates the object 2 times also.
  • If I have the configuration class in a different package than main class, I will be able to retrieve a bean only if I provide @ComponentScan to the package with the beans (@ComponentScan("com.example.demo")).

Now some of this makes sense to me, as you need to tell Spring through @ComponentScan where are the beans.

But why using @ComponentScan with no value is telling Spring to use current package?

Also, why is it creating the object 2 times?

Why a() works without @ComponentScan and getA() only with @ComponentScan?

CASE 1:

package com.example.lame;

import ...

@Configuration
public class Config {
    @Bean
    public A a() {
        return new A();
    }
}

CASE 2:

package com.example.lame;

import ...

@Configuration
@ComponentScan
public class Config {
    @Bean
    public A getA() {
        return new A();
    }
}

CASE 3:

package com.example.lame.config;

import ...

@Configuration
@ComponentScan("com.example.lame")
public class Config {
    @Bean
    public A getA() {
        return new A();
    }
}

0 Answers
Related