-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathComponentScan
More file actions
178 lines (129 loc) · 4.98 KB
/
ComponentScan
File metadata and controls
178 lines (129 loc) · 4.98 KB
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
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
package hello.core;
import hello.core.member.MemberRepository;
import hello.core.member.MemoryMemberRepository;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
@Configuration
//@Component가 붙은 모든 클래스를 자동으로 스프링 빈으로 듣록해줌.
@ComponentScan(
//hello.core 패키지부터 하위로 컴포넌트 스캔을 하는 것.
basePackages = "hello.core",
//AutoAppConfig.class가 있는 패키지부터 스캔을 하는 것.
basePackageClasses = AutoAppConfig.class,
//기존의 AppConfig.java와 충돌이 날까봐 스캔을 제외하는 코드
excludeFilters = @ComponentScan.Filter(
type = FilterType.ANNOTATION, classes = Configuration.class))
public class AutoAppConfig {
}
// AutoAppConfig.java
@Component
public class MemberServiceImpl implements MemberService {
private final MemberRepository memberRepository;
@Autowired
public MemberServiceImpl(MemberRepository memberRepository) {
this.memberRepository = memberRepository;
}
}
@Component
public class MemoryMemberRepository implements MemberRepository{
@Component
public class OrderServiceImpl implements OrderService{
private final MemberRepository memberRepository;
private final DiscountPolicy discountPolicy;
@Autowired
public OrderServiceImpl(MemberRepository memberRepository, DiscountPolicy discountPolicy) {
this.memberRepository = memberRepository;
this.discountPolicy = discountPolicy;
}
}
@Component
public class RateDiscountPolicy implements DiscountPolicy{
package hello.core.scan;
import hello.core.AutoAppConfig;
import hello.core.member.MemberService;
import org.junit.jupiter.api.Test;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import static org.assertj.core.api.Assertions.*;
public class AutoAppConfigTest {
@Test
void basicScan(){
AnnotationConfigApplicationContext ac
= new AnnotationConfigApplicationContext(AutoAppConfig.class);
MemberService memberService = ac.getBean(MemberService.class);
assertThat(memberService).isInstanceOf(MemberService.class);
}
}
//AutoAppConfigTest.java
package hello.core.scan.filter;
import java.lang.annotation.*;
//@Component에 들어가서 있는 애노테이션 복사해오기
//Target이 가장 중요. Type은 클래스 레벨에 붙는 것.
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
//이 애노테이션 붙은건 컴포넌트 스캔에 추가
public @interface MyIncludeComponent {
}
//MyIncludeComponent.java
package hello.core.scan.filter;
import java.lang.annotation.*;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
//이 애노테이션이 붙은건 컴포넌트 스캔에서 제외
public @interface MyExcludeComponent {
}
//MyExcludeComponent.java
package hello.core.scan.filter;
@MyIncludeComponent
public class BeanA {
}
//BeanA.java
package hello.core.scan.filter;
@MyExcludeComponent
public class BeanB {
}
//BeanB.java
package hello.core.scan.filter;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
import static org.assertj.core.api.Assertions.*;
import static org.junit.jupiter.api.Assertions.*;
public class ComponentFilterAppConfigTest {
@Configuration
@ComponentScan(
//타입이 ANNOTATION이 디폴트여서 생략도 가능.
includeFilters = @ComponentScan.Filter(classes = MyIncludeComponent.class),
excludeFilters = @ComponentScan.Filter(
type = FilterType.ANNOTATION, classes = MyExcludeComponent.class)
)
static class ComponentAppConfig{
}
@Test
void filterScan(){
AnnotationConfigApplicationContext ac
= new AnnotationConfigApplicationContext(ComponentAppConfig.class);
//beanA는 Null이면 안되고 조회가 되어야 함.
BeanA beanA = ac.getBean("beanA", BeanA.class);
assertThat(beanA).isNotNull();
//beanB는 조회가 되면 안되고 exception이 터져야함.
//BeanB beanB = ac.getBean("beanB", BeanB.class);
assertThrows(NoSuchBeanDefinitionException.class,
() -> ac.getBean("beanB", BeanB.class));
}
}
//ComponentFilterAppConfigTest.java
public class AutoAppConfig {
//수동/자동 중복 등록 충돌을 확인하기 위한 코드
@Bean(name="memoryMemberRepository")
MemberRepository memberRepository(){
return new MemoryMemberRepository();
}
}
//AutoAppConfig.java