Classpath Scanning and Managed Components
Spring ํ๋ ์์ํฌ์์ Classpath Scanning๊ณผ Managed Components๋ฅผ ์ฌ์ฉํ๋ฉด XML ์์ด๋ ์ ํ๋ฆฌ์ผ์ด์ ์ปดํฌ๋ํธ๋ฅผ ์๋์ผ๋ก ๊ฐ์งํ๊ณ ์ปจํ ์ด๋์ ๋ฑ๋กํ ์ ์์ต๋๋ค.
์ด๋ฅผ ํตํด ๊ฐ๋ฐ์๋ ์ ๋ ธํ ์ด์ ์ ์ฌ์ฉํ์ฌ ์๋์ผ๋ก Bean์ ๋ฑ๋กํ๊ฑฐ๋ ์์กด์ฑ์ ์ฃผ์ ํ ์ ์์ต๋๋ค. ์ด๋ฌํ ๋ฐฉ์์ ์ฝ๋์ ๊ฐ๊ฒฐ์ฑ์ ๋์ด๊ณ ์ค์ ์ ๊ฐ์ํํ๋ ๋ฐ ๊ธฐ์ฌํฉ๋๋ค.
Component ๋ฐ ๊ด๋ จ ์ ๋
ธํ
์ด์
Spring์ ์ฌ๋ฌ ๊ณ์ธต์์ ์ฌ์ฉ๋๋ ํด๋์ค๋ค์ ์ ์ ํ๊ฒ ์๋ณํ ์ ์๋ ๋ช ๊ฐ์ง Stereotype ์ ๋ ธํ ์ด์ ์ ์ ๊ณตํฉ๋๋ค
@Component: ๋ชจ๋ Spring ๊ด๋ฆฌ ์ปดํฌ๋ํธ์ ์ฌ์ฉํ ์ ์๋ ์ผ๋ฐ์ ์ธ ์คํ ๋ ์คํ์ ์ ๋ ธํ ์ด์ ์ ๋๋ค.
@Repository: ์์์ฑ ๊ณ์ธต์์ DAO(Data Access Object)๋ฅผ ๋ํ๋ด๋ฉฐ, ์์ธ ๋ฒ์ญ ๋ฑ์ ์ถ๊ฐ ๊ธฐ๋ฅ์ด ์ ๊ณต๋ฉ๋๋ค.
@Service: ๋น์ฆ๋์ค ๋ก์ง์ ์ฒ๋ฆฌํ๋ ์๋น์ค ๊ณ์ธต์ ๋ํ๋ด๋ ์คํ ๋ ์คํ์ ์ ๋๋ค.
@Controller: ํ๋ ์ ํ ์ด์ ๊ณ์ธต์์ MVC ํจํด์ ์ปจํธ๋กค๋ฌ ์ญํ ์ ์ํํ๋ ํด๋์ค์ ์ฌ์ฉ๋ฉ๋๋ค.
์ด๋ฌํ ์คํ ๋ ์คํ์ ์ ๋ ธํ ์ด์ ๋ค์ @Component์ ํน์ํ๋ก, ๊ฐ ๊ณ์ธต์ ์ ํฉํ ์ถ๊ฐ์ ์ธ ์๋ฏธ๋ ๋๊ตฌ์ ์ํ ์ฒ๋ฆฌ ๊ฐ๋ฅ์ฑ์ ์ ๊ณตํฉ๋๋ค.
Meta-Annotations ๋ฐ Composed Annotations
Spring์ ์ ๋ ธํ ์ด์ ๋ค์ ๋ค๋ฅธ ์ ๋ ธํ ์ด์ ์ ๋ฉํ ์ ๋ ธํ ์ด์ ์ผ๋ก ์ฌ์ฉ๋ ์ ์์ต๋๋ค. ๋ํ, ์ฌ๋ฌ ๋ฉํ ์ ๋ ธํ ์ด์ ์ ๊ฒฐํฉํ์ฌ Composed Annotation์ ๋ง๋ค ์ ์์ต๋๋ค.
์๋ฅผ ๋ค์ด, @RestController๋ @Controller์ @ResponseBody๋ฅผ ๊ฒฐํฉํ ์ ๋ ธํ ์ด์ ์ ๋๋ค. Composed Annotation์ ๋ฉํ ์ ๋ ธํ ์ด์ ์ ์์ฑ์ ์ฌ์ ์ํ์ฌ ์ปค์คํฐ๋ง์ด์ฆํ ์๋ ์์ต๋๋ค.
Classpath์์ Bean์ ์๋์ผ๋ก ๊ฐ์งํ๊ณ ๋ฑ๋กํ๊ธฐ
Spring์ ํด๋์ค ๊ฒฝ๋ก๋ฅผ ์ค์บํ์ฌ ํน์ ์กฐ๊ฑด์ ๋ง๋ ํด๋์ค๋ค์ ์๋์ผ๋ก ๊ฐ์งํ๊ณ , ํด๋น ํด๋์ค๋ฅผ BeanDefinition์ผ๋ก ๋ฑ๋กํ ์ ์์ต๋๋ค. ์ด ๋ฐฉ์์ XML๋ก Bean์ ๋ฑ๋กํ๋ ๋์ , ์ปดํฌ๋ํธ ์ ๋ ธํ ์ด์ ์ ์ฌ์ฉํด ์๋์ผ๋ก Bean์ ๊ฐ์งํฉ๋๋ค.
์๋น์ค ํด๋์ค์ ๋ ํฌ์งํ ๋ฆฌ ํด๋์ค
@Service
public class SimpleMovieLister {
private MovieFinder movieFinder;
public SimpleMovieLister(MovieFinder movieFinder) {
this.movieFinder = movieFinder;
}
}
@Repository
public class JpaMovieFinder implements MovieFinder {
// ๊ตฌํ ์๋ต
}Configuration ํด๋์ค์์ Component ์ค์บ ์ฌ์ฉ
@Configuration
@ComponentScan(basePackages = "org.example")
public class AppConfig {
// ์ค์ ๋ฉ์๋ ์๋ต
}๋๋ XML์ ์ฌ์ฉํ์ฌ ๊ฐ์ ์ค์ ์ ํ ์ ์์ต๋๋ค:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="...">
<context:component-scan base-package="org.example"/>
</beans>์ด ๊ตฌ์ฑ์์๋ context:component-scan์ด context:annotation-config ๊ธฐ๋ฅ์ ์๋์ผ๋ก ํ์ฑํํ๋ฏ๋ก, ๋ ์์๋ฅผ ํจ๊ป ์ฌ์ฉํ ํ์๊ฐ ์์ต๋๋ค.
์ค์บ ์ปค์คํฐ๋ง์ด์ง: ํํฐ ์ฌ์ฉ
๊ธฐ๋ณธ์ ์ผ๋ก Spring์ @Component, @Repository, @Service, @Controller, @Configuration ์ ๋ ธํ ์ด์ ์ด ๋ถ์ ํด๋์ค๋ง์ ๊ฐ์งํ์ฌ Bean์ผ๋ก ๋ฑ๋กํฉ๋๋ค.
๊ทธ๋ฌ๋ ํํฐ๋ฅผ ์ฌ์ฉํ๋ฉด ์ด ๋์์ ์ปค์คํฐ๋ง์ด์งํ ์ ์์ต๋๋ค. includeFilters ๋๋ excludeFilters ์์ฑ์ ์ฌ์ฉํ์ฌ ํํฐ๋ฅผ ์ถ๊ฐํ๊ฑฐ๋ XML ์ค์ ์์ context:include-filter ๋๋ context:exclude-filter ์์๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค.
์๋ฅผ ๋ค์ด, @Repository ์ ๋ ธํ ์ด์ ์ด ์๋ ํด๋์ค๋ฅผ ์ ์ธํ๊ณ Stub ๋ ํฌ์งํ ๋ฆฌ๋ง ํฌํจํ๋ ์ค์ ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค:
@Configuration
@ComponentScan(basePackages = "org.example",
includeFilters = @Filter(type = FilterType.REGEX, pattern = ".*Stub.*Repository"),
excludeFilters = @Filter(Repository.class))
public class AppConfig {
// ์ค์ ์๋ต
}XML๋ก๋ ๋ค์๊ณผ ๊ฐ์ด ํํํ ์ ์์ต๋๋ค:
<context:component-scan base-package="org.example">
<context:include-filter type="regex" expression=".*Stub.*Repository"/>
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Repository"/>
</context:component-scan>Bean ๋ฉํ๋ฐ์ดํฐ ์ ์
Spring ์ปดํฌ๋ํธ์์ @Bean ์ ๋ ธํ ์ด์ ์ ์ฌ์ฉํ์ฌ ์ถ๊ฐ์ ์ธ Bean ๋ฉํ๋ฐ์ดํฐ๋ฅผ ์ ์ํ ์ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด, @Component ํด๋์ค์์ ๋ฉ์๋๋ฅผ ์ฌ์ฉํ์ฌ Bean์ ์ ์ํ๋ ๋ฐฉ๋ฒ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค:
@Component
public class FactoryMethodComponent {
@Bean
@Qualifier("public")
public TestBean publicInstance() {
return new TestBean("publicInstance");
}
@Bean
protected TestBean protectedInstance(@Qualifier("public") TestBean spouse) {
return new TestBean("protectedInstance");
}
}Autowired ๋ฐ Lazy ์์กด์ฑ ์ฃผ์
@Autowired ํ๋์ ๋ฉ์๋์ ๋ํ ์ง์์ด ์์ผ๋ฉฐ, @Lazy ์ ๋ ธํ ์ด์ ์ ์ฌ์ฉํ์ฌ ์ง์ฐ ๋ก๋ํ ์๋ ์์ต๋๋ค. ์ง์ฐ ๋ก๋๋ Bean์ ํ์ํ ๋๊น์ง ์์ฑ๋์ง ์๊ณ , ๋ ๋์๊ฐ ObjectProvider์ ๊ฐ์ ๋๊ตฌ๋ฅผ ์ฌ์ฉํ์ฌ ๋ ๋ณต์กํ ์ํธ์์ฉ์ ์ฒ๋ฆฌํ ์ ์์ต๋๋ค.
์ด๋ฆ ์๋ ๊ฐ์ง
ํด๋์ค๊ฐ ์ค์บ๋ ๋ BeanNameGenerator ์ ๋ต์ ์ํด ์ด๋ฆ์ด ์๋ ์์ฑ๋ฉ๋๋ค.
๊ธฐ๋ณธ์ ์ผ๋ก AnnotationBeanNameGenerator๊ฐ ์ฌ์ฉ๋ฉ๋๋ค. ์คํ ๋ ์คํ์ ์ ๋ ธํ ์ด์ ์์ value ์์ฑ์ ์ด๋ฆ์ ์ง์ ํ๋ฉด ๊ทธ ์ด๋ฆ์ด Bean ์ด๋ฆ์ผ๋ก ์ฌ์ฉ๋ฉ๋๋ค.
์๋ฅผ ๋ค์ด, ๋ค์๊ณผ ๊ฐ์ ํด๋์ค๋ ๊ฐ๊ฐ myMovieLister์ movieFinderImpl๋ผ๋ ์ด๋ฆ์ Bean์ผ๋ก ๋ฑ๋ก๋ฉ๋๋ค:
@Service("myMovieLister")
public class SimpleMovieLister {
// ...
}
@Repository
public class MovieFinderImpl implements MovieFinder {
// ...
}Bean ์ด๋ฆ์ด ์ถฉ๋ํ ์ ์๋ ๊ฒฝ์ฐ, BeanNameGenerator๋ฅผ ์ปค์คํฐ๋ง์ด์ฆํ์ฌ ์ฒ๋ฆฌํ ์ ์์ต๋๋ค. FullyQualifiedAnnotationBeanNameGenerator์ ๊ฐ์ ์ ๋ต์ ์ฌ์ฉํ ์๋ ์์ต๋๋ค.
Autodetected ์ปดํฌ๋ํธ์ ๋ฒ์ ์ง์
๊ธฐ๋ณธ์ ์ผ๋ก ์๋ ๊ฐ์ง๋ ์ปดํฌ๋ํธ๋ singleton ๋ฒ์๋ฅผ ๊ฐ์ง๋๋ค. ๊ทธ๋ฌ๋ @Scope ์ ๋ ธํ ์ด์ ์ ์ฌ์ฉํ์ฌ ๋ค๋ฅธ ๋ฒ์๋ฅผ ์ง์ ํ ์ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด, prototype ๋ฒ์๋ก ์ค์ ๋ Bean์ ๋งค๋ฒ ์๋ก์ด ์ธ์คํด์ค๋ฅผ ๋ฐํํฉ๋๋ค:
@Scope("prototype")
@Repository
public class MovieFinderImpl implements MovieFinder {
// ...
}Qualifier ๋ฉํ๋ฐ์ดํฐ ์ ๊ณต
์๋ ๊ฐ์ง๋ ์ปดํฌ๋ํธ์์ @Qualifier ์ ๋ ธํ ์ด์ ์ ์ฌ์ฉํ์ฌ ์ธ๋ฐํ ์ฃผ์ ์ ์ด๋ฅผ ํ ์ ์์ต๋๋ค. ์ด๋ ํน์ Bean์ด ์ฌ๋ฌ ๊ฐ ์์ ๋, ์ด๋ค Bean์ ์ฃผ์ ํ ์ง ์ง์ ํ๋ ๋ฐ ์ ์ฉํฉ๋๋ค:
@Component
@Qualifier("Action")
public class ActionMovieCatalog implements MovieCatalog {
// ...
}๋ํ ์ปค์คํ ์ ๋ ธํ ์ด์ ์ ํตํด ๋ ๊ตฌ์ฒด์ ์ธ ์ ์ด๋ ๊ฐ๋ฅํฉ๋๋ค.
Last updated