๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
Spring

[Spring] Component Scan๊ณผ Function์„ ์‚ฌ์šฉํ•œ ๋นˆ ๋“ฑ๋ก ๋ฐฉ๋ฒ•

by Leica 2020. 3. 2.
๋ฐ˜์‘ํ˜•

[Spring] Component Scan๊ณผ Function์„ ์‚ฌ์šฉํ•œ ๋นˆ ๋“ฑ๋ก ๋ฐฉ๋ฒ•

1. @ComponentScan

@ComponentScan ์• ๋…ธํ…Œ์ด์…˜์€ spring 3.1๋ถ€ํ„ฐ ๋„์ž…๋์œผ๋ฉฐ ์„ค์ •๋œ ์‹œ์ž‘ ์ง€์ ๋ถ€ํ„ฐ ์ปดํฌ๋„ŒํŠธ ํด๋ž˜์Šค๋ฅผ scanningํ•˜์—ฌ ๋นˆ์œผ๋กœ ๋“ฑ๋กํ•ด์ฃผ๋Š” ์—ญํ• ์„ ํ•œ๋‹ค.

์ปดํฌ๋„ŒํŠธ ํด๋ž˜์Šค๋Š” ๋‹ค์Œ ์• ๋…ธํ…Œ์ด์…˜์ด ๋ถ™์€ ํด๋ž˜์Šค๋ฅผ ์˜๋ฏธํ•œ๋‹ค.

 

  • @Component
  • @Repository
  • @Service
  • @Controller
  • @Configuration

 

@ComponentScan์˜ ๊ฐ€์žฅ ์ค‘์š”ํ•œ ๋‘ ๊ฐ€์ง€ ์†์„ฑ์€ component๋ฅผ scanํ•  ์‹œ์ž‘ ์ง€์ ์„ ์„ค์ •ํ•˜๋Š” ์†์„ฑ๊ณผ scanํ•œ component ์ค‘ ๋นˆ์œผ๋กœ ๋“ฑ๋กํ•˜์ง€ ์•Š์„ ํด๋ž˜์Šค๋ฅผ ์ œ์™ธํ•˜๋Š” ํ•„ํ„ฐ ์†์„ฑ์ด๋‹ค.

 

1) Scan ์‹œ์ž‘ ์ง€์  ์„ค์ • - basePackages()์™€ basePackageClasses()

basePackages()์™€ basePackageClasses()๋Š” component๋ฅผ scanํ•  ์‹œ์ž‘ ์ง€์ ์„ ์„ค์ •ํ•˜๋Š” ์†์„ฑ์ด๋‹ค.

basePackages()์—๋Š” scan์„ ์‹œ์ž‘ํ•  ํŒจํ‚ค์ง€๋ฅผ ๋ฌธ์ž์—ด๋กœ ์ง€์ •ํ•˜๊ณ  basePackageClasses()์—๋Š” scan์„ ์‹œ์ž‘ํ•  ํด๋ž˜์Šค ํƒ€์ž…์„ ์ง€์ •ํ•œ๋‹ค.

๋‘˜ ์ค‘ ํ•˜๋‚˜์˜ ์†์„ฑ์„ ํƒํ•˜์—ฌ scan ์‹œ์ž‘ ์ง€์ ์„ ์„ค์ •ํ•˜๋ฉด ๋œ๋‹ค.

 

basePackages ์„ค์ • ์˜ˆ

์œ„์™€ ๊ฐ™์ด ์„ค์ •ํ•˜๋ฉด scan ์‹œ์ž‘ ํŒจํ‚ค์ง€๊ฐ€ com.atoz_develop.demospring51๋กœ ์„ค์ •๋œ๋‹ค.

com.atoz_develop.demospring51 ํŒจํ‚ค์ง€์™€ ํฌํ•จ๋œ ํ•˜์œ„ ํŒจํ‚ค์ง€์˜ ๋ชจ๋“  component๋ฅผ scanํ•ด์„œ ๋นˆ์œผ๋กœ ๋“ฑ๋กํ•ด์ค€๋‹ค.

 

basePackageClasses ์„ค์ • ์˜ˆ

์œ„์™€ ๊ฐ™์ด ์„ค์ •ํ•˜๋ฉด ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ scan ์‹œ์ž‘ ํŒจํ‚ค์ง€๊ฐ€ com.atoz_develop.demospring51๋กœ ์„ค์ •๋œ๋‹ค.

TestConfiguration ํด๋ž˜์Šค๊ฐ€ ํฌํ•จ๋œ ํŒจํ‚ค์ง€๊ฐ€ ์‹œ์ž‘ ํŒจํ‚ค์ง€๊ฐ€ ๋œ๋‹ค.

 

๋‘˜ ์ค‘ basePackageClasses()๋กœ ์„ค์ •ํ•˜๋Š” ๊ฒƒ์ด ๋” type safeํ•œ ๋ฐฉ๋ฒ•์ด๋‹ค.

 

basePackages()๋‚˜ basePackageClasses()๋ฅผ ์„ค์ •ํ•ด์ฃผ์ง€ ์•Š์œผ๋ฉด ๊ธฐ๋ณธ์ ์œผ๋กœ @ComponentScan์ด ๋ถ™์–ด์žˆ๋Š” configuration ํด๋ž˜์Šค๊ฐ€ ์ž๋™์œผ๋กœ ์‹œ์ž‘ ์ง€์ ์ด ๋œ๋‹ค.

 

๋”ฐ๋ผ์„œ ์œ„ ์„ธ ๊ฐ€์ง€ ์˜ˆ์ œ๋Š” ๋ชจ๋‘ scan ์‹œ์ž‘ ์ง€์ ์ด ๋™์ผํ•˜๋ฉฐ out ํŒจํ‚ค์ง€์— ์žˆ๋Š” ํด๋ž˜์Šค๋Š” scan ๋Œ€์ƒ์ด ์•„๋‹ˆ๊ฒŒ ๋œ๋‹ค.

 

2) ๋นˆ ํ•„ํ„ฐ๋ง - excludeFilters

Component scan์„ ํ†ตํ•ด ๋นˆ์„ ๋“ฑ๋กํ•  ๋•Œ execludeFilters ์†์„ฑ์„ ์‚ฌ์šฉํ•ด์„œ ํŠน์ • ๋นˆ์€ ๋“ฑ๋ก๋˜์ง€ ์•Š๋„๋ก ์„ค์ •ํ•  ์ˆ˜ ์žˆ๋‹ค. ์„ค์ • ๋ฐฉ๋ฒ•์€ ๋‹ค์–‘ํ•˜๋ฉฐ ๋‹ค์Œ์€ ์• ๋…ธํ…Œ์ด์…˜์„ ์ด์šฉํ•ด์„œ ํ•„ํ„ฐ๋งํ•˜๋Š” ๋ฐฉ๋ฒ•์ด๋‹ค.

 

IgnoreDuringScan ์• ๋…ธํ…Œ์ด์…˜์„ ์ƒˆ๋กœ ์ •์˜ํ•œ๋‹ค.

์ด ์• ๋…ธํ…Œ์ด์…˜์ด ๋ถ™์€ ์ปดํฌ๋„ŒํŠธ๋Š” ํ•„ํ„ฐ๋งํ•˜์—ฌ ๋นˆ์œผ๋กœ ๋“ฑ๋กํ•˜์ง€ ์•Š์„ ๊ฒƒ์ด๋‹ค.

 

1
2
3
4
5
6
7
8
9
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
 
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface IgnoreDuringScan {
}
cs

 

ํ•„ํ„ฐ๋งํ•  ์ปดํฌ๋„ŒํŠธ ํด๋ž˜์Šค์— @IgnoreDuringScan ์• ๋…ธํ…Œ์ด์…˜์„ ๋ถ™์ธ๋‹ค.

1
2
3
4
5
6
import org.springframework.stereotype.Service;
 
@Service
@IgnoreDuringScan
public class AnotherBookService {
}
cs

 

@Service ์• ๋…ธํ…Œ์ด์…˜์ด ๋ถ™์–ด์žˆ์œผ๋ฏ€๋กœ ๊ธฐ๋ณธ์ ์œผ๋กœ ํ•„ํ„ฐ๋ง ์„ค์ •์ด ์—†์œผ๋ฉด ์ด ํด๋ž˜์Šค๋Š” ๋นˆ์œผ๋กœ ๋“ฑ๋ก๋œ๋‹ค.

 

Configuration์— ํ•„ํ„ฐ ์„ค์ •์„ ์ถ”๊ฐ€ํ•œ๋‹ค.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
import org.springframework.context.annotation.ComponentScan.Filter;
 
@Configuration
@ComponentScan(
        basePackageClasses = ApplicationConfig.class,
        excludeFilters = @Filter(
                type = FilterType.ANNOTATION,
                classes = {IgnoreDuringScan.class}
        )
)
public class ApplicationConfig {
}
cs

excludeFilters ์†์„ฑ์„ ์‚ฌ์šฉํ•ด @IgnoreDuringScan ์• ๋…ธํ…Œ์ด์…˜์ด ๋ถ™์–ด์žˆ๋Š” ์ปดํฌ๋„ŒํŠธ ํด๋ž˜์Šค๋Š” ๋นˆ์œผ๋กœ ๋“ฑ๋กํ•˜์ง€ ์•Š๋„๋ก ํ•œ๋‹ค.

 

์„ค์ •ํ•œ ๋Œ€๋กœ AnotherBookService๊ฐ€ ๋นˆ์œผ๋กœ ๋“ฑ๋ก๋˜์ง€ ์•Š์•˜๋Š”์ง€ ํ™•์ธํ•ด๋ณด๊ธฐ ์œ„ํ•ด Application ํด๋ž˜์Šค์—์„œ ์ถœ๋ ฅํ•ด๋ณด์ž.

 

1
2
3
4
5
6
7
8
9
10
11
12
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
 
import java.util.Arrays;
 
public class Demospring52Application {
 
    public static void main(String[] args) {
        ApplicationContext context = new AnnotationConfigApplicationContext(ApplicationConfig.class);
        System.out.println(context.containsBean("anotherBookService"));
    }
}
cs

ApplicationContext์˜ containsBean()์€ ์ง€์ •ํ•œ ๋นˆ์ด IoC์— ๋“ฑ๋ก๋ผ์žˆ๋Š”์ง€ ์—ฌ๋ถ€๋ฅผ ๋ฆฌํ„ดํ•œ๋‹ค.

 

์‹คํ–‰ ๊ฒฐ๊ณผ


2. Function์„ ์‚ฌ์šฉํ•œ ๋นˆ ๋“ฑ๋ก ๋ฐฉ๋ฒ•

Function์„ ์‚ฌ์šฉํ•ด์„œ ๋นˆ์„ ๋“ฑ๋กํ•˜๋Š” ๋ฐฉ๋ฒ•์€ spring 5๋ถ€ํ„ฐ ์ถ”๊ฐ€๋˜์—ˆ๋‹ค.

๋นˆ ๋“ฑ๋ก ๋ฐฉ๋ฒ•์€ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

 

Spring boot ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๊ตฌ๋™ํ•˜๋Š” ๋ฐฉ๋ฒ•์—๋Š” SpringApplication.run()๊ณผ ๊ฐ™์ด static ๋ฉ”์†Œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๋ฐฉ๋ฒ• ์™ธ์— ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•ด์„œ ๊ตฌ๋™ํ•˜๋Š” ๋ฐฉ๋ฒ•์ด ์žˆ๋‹ค.

Application ํด๋ž˜์Šค๋ฅผ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ˆ˜์ •ํ•œ๋‹ค.

Local ๋ณ€์ˆ˜ var๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” JDK 10 ์ด์ƒ์ด ํ•„์š”ํ•˜๋‹ค.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
 
@SpringBootApplication
public class Demospring52Application {
 
    public static void main(String[] args) {
//        SpringApplication.run(Demospring52Application.class, args);
        var app = new SpringApplication(Demospring52Application.class);
        // ์—ฌ๊ธฐ์— ๋นˆ ๋“ฑ๋ก ์ฝ”๋“œ ์ž‘์„ฑ
        app.run(args);
    }
}
cs

๊ธฐ์กด์— run() ํ˜ธ์ถœ๋ถ€๋ฅผ ์ฃผ์„์ฒ˜๋ฆฌํ•˜๊ณ  SpringApplication ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•ด์„œ run()์„ ํ˜ธ์ถœํ•œ๋‹ค.

SpringApplication ์ธ์Šคํ„ด์Šค ์ƒ์„ฑ๊ณผ run() ํ˜ธ์ถœ ์‚ฌ์ด์— ๋นˆ์„ ๋“ฑ๋กํ•˜๋Š” ์ฝ”๋“œ๋ฅผ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ž‘์„ฑํ•ด์ฃผ๋ฉด ๋œ๋‹ค.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContextInitializer;
import org.springframework.context.support.GenericApplicationContext;
import out.MyService;
 
@SpringBootApplication
public class Demospring52Application {
 
    @Autowired
    MyService myService;
 
    public static void main(String[] args) {
//        SpringApplication.run(Demospring52Application.class, args);
        var app = new SpringApplication(Demospring52Application.class);
 
        app.addInitializers(new ApplicationContextInitializer<GenericApplicationContext>() {    // GenericApplicationContext๋กœ ์„ค์ •
            @Override
            public void initialize(GenericApplicationContext ctx) {
                ctx.registerBean(MyService.class);
            }
        });
 
        app.run(args);
    }
}
cs

ctx.registerBean()์ด ๋นˆ์„ ๋“ฑ๋กํ•˜๋Š” ๋ถ€๋ถ„์ด๋‹ค.

@ComponentScan์„ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•๊ณผ ๋‹ฌ๋ฆฌ function์„ ์‚ฌ์šฉํ•œ ๋นˆ ๋“ฑ๋ก ๋ฐฉ๋ฒ•์€ ์Šค์บ” ๋ฒ”์œ„์— ๊ตฌ์• ๋ฐ›์ง€ ์•Š๋Š”๋‹ค.

 

MyService๋Š” Application ํด๋ž˜์Šค์™€ ๋‹ค๋ฅธ ํŒจํ‚ค์ง€์— ์žˆ์œผ๋ฉฐ @Component ์• ๋…ธํ…Œ์ด์…˜์ด ๋ถ™์–ด์žˆ์ง€ ์•Š์€ ํด๋ž˜์Šค์ด๋‹ค.

 

์ด ํด๋ž˜์Šค๋ฅผ ctx.register()๋ฅผ ์ด์šฉํ•ด ๋นˆ์œผ๋กœ ๋“ฑ๋กํ•˜๊ณ  ์ •์ƒ์ ์œผ๋กœ ๋“ฑ๋ก๋˜๋Š”์ง€ ํ™•์ธํ•ด๋ณด๊ธฐ ์œ„ํ•ด @Autowired๋กœ ํ•„๋“œ์— ์ฃผ์ž…๋ฐ›์•˜๋‹ค.

 

์‹คํ–‰ ๊ฒฐ๊ณผ

์œ„์™€ ๊ฐ™์ด ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ์ •์ƒ์ ์œผ๋กœ ์‹คํ–‰๋˜๋Š” ๊ฒƒ์œผ๋กœ ๋นˆ์ด ์ž˜ ๋“ฑ๋ก๋œ ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

 

์ด ์ฝ”๋“œ๋Š” ๋žŒ๋‹ค์‹์„ ์ด์šฉํ•ด์„œ ์งง๊ฒŒ ํ‘œํ˜„ํ•  ์ˆ˜ ์žˆ๋‹ค.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContextInitializer;
import org.springframework.context.support.GenericApplicationContext;
import out.MyService;
 
@SpringBootApplication
public class Demospring52Application {
 
    @Autowired
    MyService myService;
 
    public static void main(String[] args) {
        var app = new SpringApplication(Demospring52Application.class);
 
        /*app.addInitializers(new ApplicationContextInitializer<GenericApplicationContext>() {    // GenericApplicationContext๋กœ ์„ค์ •
            @Override
            public void initialize(GenericApplicationContext ctx) {
                ctx.registerBean(MyService.class);
            }
        });*/
 
        // Lambda ~
        app.addInitializers((ApplicationContextInitializer<GenericApplicationContext>) ctx -> ctx.registerBean(MyService.class));
 
        app.run(args);
    }
}
cs

 

์ฐธ๊ณ ๋กœ registerBean()์„ ์ด์šฉํ•ด์„œ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ApplicationRunner๋ฅผ ๋นˆ์œผ๋กœ ๋“ฑ๋กํ• ์ˆ˜๋„ ์žˆ๋‹ค.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContextInitializer;
import org.springframework.context.support.GenericApplicationContext;
import out.MyService;
 
import java.util.function.Supplier;
 
@SpringBootApplication
public class Demospring52Application {
 
    @Autowired
    MyService myService;
 
    public static void main(String[] args) {
        var app = new SpringApplication(Demospring52Application.class);
 
        app.addInitializers((ApplicationContextInitializer<GenericApplicationContext>) ctx -> {
            ctx.registerBean(MyService.class);
 
            // ๋ฉ”์‹œ์ง€๋ฅผ ์ถœ๋ ฅํ•˜๋Š” ApplicationRunner๋ฅผ ์ƒ์„ฑํ•ด์„œ ๋นˆ์œผ๋กœ ๋“ฑ๋ก
            ctx.registerBean(ApplicationRunner.classnew Supplier<ApplicationRunner>() {
                @Override
                public ApplicationRunner get() {
                    return new ApplicationRunner() {
                        @Override
                        public void run(ApplicationArguments args) throws Exception {
                            System.out.println("Hello World!!");
                        }
                    };
                }
            });
        });
 
        app.run(args);
    }
}
cs

registerBean()์˜ ์ฒซ ๋ฒˆ์งธ ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ApplicationRunner์˜ ํƒ€์ž…์„ ์ „๋‹ฌํ•˜๊ณ  ํ•จ์ˆ˜ํ˜• ์ธํ„ฐํŽ˜์ด์Šค Supplier๋ฅผ ์ด์šฉํ•ด์„œ ๋‘ ๋ฒˆ์งธ ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ApplicationRunner ํƒ€์ž…์˜ ์ธ์Šคํ„ด์Šค๋ฅผ ์ œ๊ณตํ•ด์ค€๋‹ค.

๊ฐ„๋‹จํ•˜๊ฒŒ "Hello World!!"๋ฅผ ์ถœ๋ ฅํ•˜๋Š” ApplicationRunner๋ฅผ ๋งŒ๋“ค์–ด์„œ ๋นˆ์œผ๋กœ ๋“ฑ๋กํ•˜๋Š” ์ฝ”๋“œ์ด๋‹ค.

 

์‹คํ–‰ ๊ฒฐ๊ณผ

 

๋งˆ์ฐฌ๊ฐ€์ง€๋กœ lambda์‹์œผ๋กœ ์งง๊ฒŒ ํ‘œํ˜„ํ•  ์ˆ˜ ์žˆ๋‹ค.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContextInitializer;
import org.springframework.context.support.GenericApplicationContext;
import out.MyService;
 
@SpringBootApplication
public class Demospring52Application {
 
    @Autowired
    MyService myService;
 
    public static void main(String[] args) {
        var app = new SpringApplication(Demospring52Application.class);
 
        app.addInitializers((ApplicationContextInitializer<GenericApplicationContext>) ctx -> {
            ctx.registerBean(MyService.class);
 
            // ๋ฉ”์‹œ์ง€๋ฅผ ์ถœ๋ ฅํ•˜๋Š” ApplicationRunner๋ฅผ ์ƒ์„ฑํ•ด์„œ ๋นˆ์œผ๋กœ ๋“ฑ๋ก
            ctx.registerBean(ApplicationRunner.class, () -> args1 -> System.out.println("Hello World!!"));
        });
 
        app.run(args);
    }
}
cs

3. Component Scanning VS Functional

@ComponentScan ๋ฐฉ์‹์€ ์‹ฑ๊ธ€ํ†ค scope์ธ ๋นˆ๋“ค์„ ๋ชจ๋‘ ์ดˆ๊ธฐ์— ์ƒ์„ฑํ•œ๋‹ค.

๋”ฐ๋ผ์„œ ๋“ฑ๋กํ•ด์•ผํ•  ๋นˆ์ด ๋งŽ์„ ๊ฒฝ์šฐ ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์ดˆ๊ธฐ ๊ตฌ๋™์‹œ๊ฐ„์ด ์˜ค๋ž˜ ๊ฑธ๋ฆด ์ˆ˜ ์žˆ๋‹ค๋Š” ๋‹จ์ ์ด ์žˆ๋‹ค.

 

Function์„ ์‚ฌ์šฉํ•œ ๋นˆ ๋“ฑ๋ก ๋ฐฉ๋ฒ•์€ @ComponentScan์„ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•๋ณด๋‹ค ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ดˆ๊ธฐ ๊ตฌ๋™ ์‹œ๊ฐ„์ด ๋” ์งง๋‹ค. 

๋˜ ๋‹ค๋ฅธ ์žฅ์ ์€ ์กฐ๊ฑด์— ๋”ฐ๋ผ ๋นˆ์„ ๋“ฑ๋กํ•œ๋‹ค๋˜์ง€ ํ•˜๋Š” ๋กœ์ง์„ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค.

์ฆ‰ ๋นˆ์„ ๋“ฑ๋กํ•˜๋Š”๋ฐ ์žˆ์–ด์„œ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์ ์ธ ์ปจํŠธ๋กค์ด ๊ฐ€๋Šฅํ•ด์ง„๋‹ค.

 

๋‘ ๋ฐฉ๋ฒ• ์ค‘ ํ•˜๋‚˜๋ฅผ ๋ฐ˜๋“œ์‹œ ํƒํ•ด์•ผ ํ•˜๋Š”๊ฑด ์•„๋‹ˆ๊ณ  ๋‘˜ ๋‹ค ๋™์‹œ์— ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

์ด ๊ฒฝ์šฐ @ComponentScan ๋ฐฉ์‹์˜ ๋นˆ์ด ๋จผ์ € ๋“ฑ๋ก๋œ๋‹ค.

@ComponentScan์€ BeanFactoryPostProcessor๋ฅผ ๊ตฌํ˜„ํ•œ ConfigurationPostProcessor์™€ ์—ฐ๊ด€์ด ๋ผ์žˆ๋‹ค.

BeanFactoryPostProcessor์˜ ๊ตฌํ˜„์ฒด๋“ค์€ ๋‹ค๋ฅธ ๋ชจ๋“  ๋นˆ๋“ค์„ ๋งŒ๋“ค๊ธฐ ์ด์ „์— ์ ์šฉ๋œ๋‹ค.

์ฆ‰ ๋‹ค๋ฅธ ๋นˆ๋“ค์„ ๋“ฑ๋กํ•˜๊ธฐ ์ „์— @ComponentScan์œผ๋กœ ๋นˆ์„ ๋จผ์ € ๋“ฑ๋กํ•œ๋‹ค.

์—ฌ๊ธฐ์„œ ๋‹ค๋ฅธ ๋นˆ๋“ค์ด๋ž€ @Bean ๋˜๋Š” function์„ ์‚ฌ์šฉํ•ด์„œ ์ง์ ‘ ๋“ฑ๋กํ•œ ๋นˆ์„ ๋งํ•œ๋‹ค.

 

Functionalํ•œ ๋นˆ ๋“ฑ๋ก์€ ๋ชจ๋“  ๋นˆ์„ ์ง์ ‘ ๋“ฑ๋กํ•ด์ค˜์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋ฒˆ๊ฑฐ๋กญ๊ณ  ์ฝ”๋“œ๊ฐ€ ๋ณต์žกํ•ด์ง„๋‹ค.

๋”ฐ๋ผ์„œ @ComponentScan ๋ฐฉ์‹์„ ์™„์ „ํžˆ ๋Œ€์ฒดํ•ด์„œ ์‚ฌ์šฉํ•˜๊ธฐ ๋ณด๋‹ค๋Š” @ComponentScan์œผ๋กœ ๋“ฑ๋กํ•˜๋Š” ๋นˆ ์™ธ์— @Bean์œผ๋กœ ์ง์ ‘ ๋“ฑ๋กํ•ด์•ผํ•˜๋Š” ๋นˆ์ด ์žˆ์„ ๊ฒฝ์šฐ functionalํ•œ ๋ฐฉ๋ฒ•์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์„ ๊ณ ๋ คํ•ด๋ณด๋Š”๊ฒŒ ์ข‹๋‹ค.

 

References

์ธํ”„๋Ÿฐ - ๋ฐฑ๊ธฐ์„ ๋‹˜์˜ ์Šคํ”„๋ง ํ”„๋ ˆ์ž„์›Œํฌ ํ•ต์‹ฌ ๊ธฐ์ˆ 

๋ฐ˜์‘ํ˜•

๋Œ“๊ธ€