[Spring] 6.์ปดํฌ๋ํธ ์ค์บ
1. ์ปดํฌ๋ํธ ์ค์บ๊ณผ ์์กด๊ด๊ณ ์๋ ์ฃผ์ ์์ํ๊ธฐ
์ปดํฌ๋ํธ ์ค์บ๊ณผ ์์กด๊ด๊ณ ์๋ ์ฃผ์ ์์ํ๊ธฐ
- ์คํ๋ง ์ค์ ์ ๋ณด๊ฐ ์์ด๋ ์๋์ผ๋ก ์คํ๋ง ๋น์ ๋ฑ๋กํ๋ ์ปดํฌ๋ํธ ์ค์บ์ด๋ผ๋ ๊ธฐ๋ฅ ์ ๊ณต
- ์์กด๊ด๊ณ๋ ์๋์ผ๋ก ์ฃผ์ ํ๋ @Autowired ๊ธฐ๋ฅ ์ ๊ณต
์ปดํฌ๋ํธ ์ค์บ๊ณผ ์์กด๊ด๊ณ ์๋ ์ฃผ์
AutoAppConfig
@Configuration
@ComponentScan (excludeFilters = @Filter(type = FilterType.ANNOTATION, classes =
Configuration.class))
public class AutoAppConfig {
}
- @ComponentScan : @Component ๋ถ์ ํด๋์ค ์๋์ผ๋ก ์ฐพ์์ ์คํ๋ง ๋น์ผ๋ก ๋ฑ๋ก
- exludeFilters -> ๋บ๊ฑฐ ์ง์ (Configuration ๊ธฐ์กด ์์ ๋๋ฌธ์)
@Component์ถ๊ฐ
- MMRepo, DiscountPolicy, ServiceImpl(Member, Order)
@Autowired์ถ๊ฐ (์๋ ์์กด๊ด๊ณ ์ฃผ์ )
- ServiceImpl (Member, Order)
ํ ์คํธ
public class AutoAppConfigTest {
@Test
void basicScan() {
ApplicationContext ac = new AnnotationConfigApplicationContext(AutoAppConfig.class);
MemberService memberService = ac.getBean(MemberService.class);
assertThat(memberService).isInstanceOf(MemberService.class);
}
}
1) ์ปดํฌ๋ํธ ์ค์บ ๋์๋ฐฉ๋ฒ
- @ComponentScan์ @Component๊ฐ ๋ถ์ ๋ชจ๋ ํด๋์ค๋ฅผ ์คํ๋ง ๋น์ผ๋ก ๋ฑ๋ก
- ์ด๋ ์คํ๋ง ๋น์ ๊ธฐ๋ณธ ์ด๋ฆ์ ํด๋์ค ๋ช ์ผ๋ก ๋ฑ๋กํ๋ ๋งจ ์๊ธ์ ์๋ฌธ์๋ก ์ฌ์ฉ
๋น ์ด๋ฆ ๊ธฐ๋ณธ ์ ๋ต: MemberServiceImpl ํด๋์ค memberServiceImpl
๋น ์ด๋ฆ ์ง์ ์ง์ : ๋ง์ฝ ์คํ๋ง ๋น์ ์ด๋ฆ์ ์ง์ ์ง์ ํ๊ณ ์ถ์ผ๋ฉด @Component("memberService2") ์ด๋ฐ์์ผ๋ก ์ด๋ฆ์ ๋ถ์ฌํ๋ฉด ๋๋ค.
2) @Autowired ์์กด๊ด๊ณ ์๋ ์ฃผ์
- ์์ฑ์์ @Autowired ์ง์ ํ๋ฉด ์คํ๋ง ์ปจํ ์ด๋๊ฐ ์๋์ผ๋ก ํด๋น ์คํ๋ง ๋น ์ฐพ์์ ์ฃผ์
- ๊ธฐ๋ณธ ์ ๋ต : ํ์ ์ด ๊ฐ์ ๋น ์ฐพ์์ ์ฃผ์
- getBean(MemberRepository.class) ์ ๋์ผํ๋ค๊ณ ์ดํดํ๋ฉด ๋จ
- ์์ฑ์ ๋ง์๋ ๋ค ์ฐพ์์ ์ฃผ์ ํด์ค
2. ํ์ ์์น์ ๊ธฐ๋ณธ ์ค์บ ๋์
ํ์ํ ํจํค์ง์ ์์ ์์น ์ง์
- ๊ผญ ํ์ํ ์์น๋ถํฐ ํ์ ์์ํ๋๋ก ์ค์ ๊ฐ๋ฅ
@Configuration
@ComponentScan(
basePackages = "hello.core",
}
- basePackages : ํ์ํ ํจํค์ง์ ์์ ์์น ์ง์ / ์ด ํจํค์ง๋ฅผ ํฌํจํด์ ํ์ ํจํค์ง๋ฅผ ๋ชจ๋ ํ์
- ์ฌ๋ฌ ์์น๋ ์ค์ ๊ฐ๋ฅ (basePackages = {"hello.core", "hello.service"})
- basePackageClasses : ์ง์ ํ ํด๋์ค์ ํจํค์ง๋ฅผ ํ์ ์์ ์๋ก ์ง์
๊ถ์ฅ๋ฒ -> ํจํค์ง ์์น ์ง์ X,์ค์ ์ ๋ณด ํด๋์ค ์์น๋ฅผ ํ๋ก์ ํธ ์ต์๋จ์ ๋๊ธฐ
* ์ฐธ๊ณ ) ์คํ๋ง๋ถํธ : @SpringBootApplication (์คํ๋ง๋ถํธ ๋ํ ์์ ์ ๋ณด)๋ฅผ ํ๋ก์ ํธ ์์ ๋ฃจํธ ์์น์ ๋๋ ๊ฒ์ด ๊ด๋ก
-> ์ด ์ค์ ์์ @CompentScan์ด ๋ค์ด์์
์ปดํฌ๋ํธ ์ค์บ ๊ธฐ๋ณธ ๋์
- @Component : ์ปดํฌ๋ํธ ์ค์บ์ ์ฌ์ฉ
- @Controller : ์คํ๋ง MVC ์ปจํธ๋กค๋ฌ์ ์ฌ์ฉ
- @Service : ์คํ๋ง ๋น์ฆ๋์ค ๋ก์ง์ ์ฌ์ฉ
- @Repository : ์คํ๋ง ๋ฐ์ดํฐ ์ ๊ทผ ๊ณ์ธต์์ ์ฌ์ฉ
- @Configuration : ์คํ๋ง ์ค์ ์ ๋ณด์์ ์ฌ์ฉ
* ์ฐธ๊ณ ) ์คํ๋ง์๋ ์์๊ด๊ณ ์์
๋ถ๊ฐ ๊ธฐ๋ฅ
- @Controller : ์คํ๋ง MVC ์ปจํธ๋กค๋ฌ๋ก ์ธ์
- @Repository : ์คํ๋ง ๋ฐ์ดํฐ ์ ๊ทผ ๊ณ์ธต์ผ๋ก ์ธ์ / ๋ฐ์ดํฐ ๊ณ์ธต ์์ธ๋ฅผ ์คํ๋ง ์์ธ๋ก ๋ณํ
- @Configuration : ์คํ๋ง ์ค์ ์ ๋ณด๋ก ์ธ์ / ์คํ๋ง ๋น์ด ์ฑ๊ธํค ์ ์งํ๋๋ก ์ถ๊ฐ ์ฒ๋ฆฌ
- @Service : ํน๋ณ ์ฒ๋ฆฌ ์์ / ๊ฐ๋ฐ์๋ค์ด ํต์ฌ ๋น์ฆ๋์ค ๋ก์ง ์ธ์ ์ฝ๊ฒ
* ์ฐธ๊ณ ) useDefaultFilters : ์ต์ ์ ๊ธฐ๋ณธ์ผ๋ก ์ผ์ ธ์๋๋ฐ, ์ด ์ต์ ์ ๋๋ฉด ๊ธฐ๋ณธ ์ค์บ ๋์๋ค์ด ์ ์ธ
3. ํํฐ
์ข ๋ฅ
- includeFilters : ์ปดํฌ๋ํธ ์ค์บ ๋์์ ์ถ๊ฐ๋ก ์ง์
- excludeFilters : ์ปดํฌ๋ํธ ์ค์บ์์ ์ ์ธํ ๋์์ ์ง์
์ปดํฌ๋ํธ ์ค์บ ๋์์ ์ถ๊ฐํ annotation
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface MyIncludeComponent {
}
์ปดํฌ๋ํธ ์ค์บ ๋์์ ์ ์ธํ annotation
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface MyExcludeComponent {
}
์ปดํฌ๋ํธ ์ค์บ ๋์์ ์ถ๊ฐํ class
@MyIncludeComponent
public class BeanA {
}
์ปดํฌ๋ํธ ์ค์บ ๋์์ ์ ์ธํ class
@MyExcludeComponent
public class BeanB {
}
์ค์ ์ ๋ณด์ ์ ์ฒด ํ ์คํธ ์ฝ๋
public class ComponentFilterAppConfigTest {
@Test
void filterScan() {
ApplicationContext ac = new AnnotationConfigApplicationContext(ComponentFilterAppConfig.class);
BeanA beanA = ac.getBean("beanA", BeanA.class);
assertThat(beanA).isNotNull();
Assertions.assertThrows(
NoSuchBeanDefinitionException.class,
() -> ac.getBean("beanB", BeanB.class));
}
@Configuration
@ComponentScan(
includeFilters = @Filter(type = FilterType.ANNOTATION, classes = MyIncludeComponent.class),
excludeFilters = @Filter(type = FilterType.ANNOTATION, classes = MyExcludeComponent.class)
)
static class ComponentFilterAppConfig {
}
}
FilterType ์ต์ (5๊ฐ์ง)
- ANNOTATION: ๊ธฐ๋ณธ๊ฐ, ์ ๋ ธํ ์ด์ ์ ์ธ์ํด์ ๋์ํ๋ค. (์๋ต๊ฐ๋ฅ)
ex) org.example.SomeAnnotation
- ASSIGNABLE_TYPE: ์ง์ ํ ํ์ ๊ณผ ์์ ํ์ ์ ์ธ์ํด์ ๋์ํ๋ค.
ex) org.example.SomeClass
- ASPECTJ: AspectJ ํจํด ์ฌ์ฉ
ex) org.example..*Service+
- REGEX: ์ ๊ท ํํ์
ex) org\.example\.Default.*
- CUSTOM: TypeFilter ์ด๋ผ๋ ์ธํฐํ์ด์ค๋ฅผ ๊ตฌํํด์ ์ฒ๋ฆฌ
ex) org.example.MyTypeFilter
ex) BeanA๋ฅผ ๋นผ๊ณ ์ถ์๋
@ComponentScan(
includeFilters = {
@Filter(type = FilterType.ANNOTATION, classes = MyIncludeComponent.class),
},
excludeFilters = {
@Filter(type = FilterType.ANNOTATION, classes = MyExcludeComponent.class),
@Filter(type = FilterType.ASSIGNABLE_TYPE, classes = BeanA.class)
}
)
์ฐธ๊ณ ) @Component ๋ฉด ์ถฉ๋ถํ๊ธฐ ๋๋ฌธ์, includeFilters ๋ฅผ ์ฌ์ฉํ ์ผ์ ๊ฑฐ์ ์๋ค. excludeFilters ๋ ์ฌ๋ฌ๊ฐ์ง ์ด์ ๋ก ๊ฐํน ์ฌ์ฉํ ๋๊ฐ ์์ง๋ง ๋ง์ง๋ ์๋ค.
> ํนํ ์ต๊ทผ ์คํ๋ง ๋ถํธ๋ ์ปดํฌ๋ํธ ์ค์บ์ ๊ธฐ๋ณธ์ผ๋ก ์ ๊ณตํ๋๋ฐ, ๊ฐ์ธ์ ์ผ๋ก๋ ์ต์ ์ ๋ณ๊ฒฝํ๋ฉด์ ์ฌ์ฉํ๊ธฐ ๋ณด๋ค๋ ์คํ๋ง์ ๊ธฐ๋ณธ ์ค์ ์ ์ต๋ํ ๋ง์ถ์ด ์ฌ์ฉํ๋ ๊ฒ์ ๊ถ์ฅํ๊ณ , ์ ํธํ๋ ํธ์ด๋ค.
4. ์ค๋ณต๋ฑ๋ก๊ณผ ์ถฉ๋
์ปดํฌ๋ํธ ์ค์บ์์ ๊ฐ์ ๋น ์ด๋ฆ์ ๋ฑ๋กํ๋ฉด ์ด๋ป๊ฒ ๋ ๊น?
1) ์๋ ๋น ๋ฑ๋ก vs ์๋ ๋น ๋ฑ๋ก
2) ์๋ ๋น ๋ฑ๋ก vs ์๋ ๋น ๋ฑ๋ก
1) ์๋ ๋น ๋ฑ๋ก vs ์๋ ๋น ๋ฑ๋ก
-> ๋ฉค๋ฒ์๋น์ค์ ์ค๋์๋น์ค ๋๋ค @Component("sevice") ์ค๋ณต
-> ConflictingBeanDefinitionException ์์ธ ๋ฐ์
2) ์๋ ๋น ๋ฑ๋ก vs ์๋ ๋น ๋ฑ๋ก
->
@Configuration
@ComponentScan(
excludeFilters = @Filter(type = FilterType.ANNOTATION, classes = Configuration.class)
)
public class AutoAppConfig {
@Bean(name = "memoryMemberRepository")
public MemberRepository memberRepository() {
return new MemoryMemberRepository();
}
}
์ด ๊ฒฝ์ฐ ์๋ ๋น ๋ฑ๋ก์ด ์ฐ์ ๊ถ์ ๊ฐ์ง๋ค. (์๋ ๋น์ด ์๋ ๋น์ ์ค๋ฒ๋ผ์ด๋ฉ ํด๋ฒ๋ฆฐ๋ค.)
* ์๋ ๋น ๋ฑ๋ก์ ๋จ๋ ๋ก๊ทธ
Overriding bean definition for bean 'memoryMemberRepository' with a different definition: replacing
|
* ์คํธ๋ง๋ถํธ์์ ์๋ ๋น vs ์๋ ๋น ์ถฉ๋๋๋ฉด ์ค๋ฅ๊ฐ ๋ฐ์ํ๋๋ก ๋ณ๊ฒฝ
Consider renaming one of the beans or enabling overriding by setting spring.main.allow-bean-definition-overriding=true |
์คํ๋ง ๋ถํธ์ธ CoreApplication ์ ์คํํด๋ณด๋ฉด ์ค๋ฅ๋ฅผ ๋ณผ ์ ์๋ค.
'๐จโ๐ป Web Development > Spring - ๊ธฐ๋ณธ' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[Spring] 8.๋น ์๋ช ์ฃผ๊ธฐ ์ฝ๋ฐฑ (0) | 2023.02.28 |
---|---|
[Spring] 7.๋ค์ํ ์์กด๊ด๊ณ ์ฃผ์ ๋ฐฉ๋ฒ (0) | 2023.02.28 |
[Spring] 5.์ฑ๊ธํค ์ปจํ ์ด๋ (0) | 2023.02.22 |
[Spring] 4.์คํ๋ง ์ปจํ ์ด๋์ ์คํ๋ง ๋น (0) | 2023.02.20 |
[Spring] 3.์คํ๋ง ํต์ฌ ์๋ฆฌ ์ดํด2 - ๊ฐ์ฒด ์งํฅ ์๋ฆฌ ์ ์ฉ (0) | 2023.02.18 |
์ต๊ทผ๋๊ธ