[Spring] @Component ์ ๋ ธํ ์ด์ ๋ฐ ํจ๊ป ์ฌ์ฉํ๋ ์ ๋ ธํ ์ด์ ์ ๋ฆฌ
์คํ๋ง ๋น ์ค์ XML ํ์ผ์ <bean id="..." class="..."/>๋ ์๋ฐ @Configuration ํด๋์ค์์ @Bean์ ๋ถ์ฌ ๋น์ ๋ฑ๋กํ๋ ๊ฒ์ฒ๋ผ ๋น ํด๋์ค์ @Component ์ ๋ ธํ ์ด์ ์ ๋ถ์ฌ ๋น์ ๋ฑ๋กํ ์ ์๋ค.
์ฆ @Component๋ฅผ ์ฌ์ฉํด์ ๋น ์ค์ ํ์ผ์ด ์๋๋ผ ๋น ํด๋์ค์์ ๋น์ ์ง์ ๋ฑ๋กํ ์ ์๋ค.
Component Scan ์ค์
@Component๋ฅผ ๋ถ์ธ ํด๋์ค๋ฅผ ์ค์บํ ์ ์๋๋ก ์ค์ ํด ์ฃผ์ด์ผ ํ๋ค.
1) XML ์ค์ ์ ์ฌ์ฉํ ๊ฒฝ์ฐ
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!-- ์ง์ ๋ ํจํค์ง ์์ ์๋ Bean ํด๋์ค๋ค์ ์ด๋
ธํ
์ด์
์ ๋ถ์ํ๋๋ก ์ง์ ํ๋ค -->
<context:component-scan base-package="com.atoz_develop.beans1"/>
<context:component-scan base-package="com.atoz_develop.beans2"/>
</beans>
<context:component-scan> ํ๊ทธ์ base-package์ ์ค์บํ ํจํค์ง๋ฅผ ์ค์ ํ๋ค.
ํจํค์ง๊ฐ ์ฌ๋ฌ๊ฐ์ธ ๊ฒฝ์ฐ <context:component-scan>๋ฅผ ์ฌ๋ฌ๊ฐ ์์ฑํ ์ ์๋ค.
2) @Configuration ์ค์ ์ ์ฌ์ฉํ ๊ฒฝ์ฐ
@Configuration
// ์ง์ ๋ ํจํค์ง์ Bean ํด๋์ค๋ค์ ์ด๋
ธํ
์ด์
์ ๋ถ์ํ์ฌ Bean์ ๋ฑ๋กํ๋ผ๊ณ ์ง์ ํ๋ค.
@ComponentScan(basePackages = {"com.atoz_develop.beans", "com.atoz_develop.bean1"})
@ComponentScan(basePackages = "com.atoz_develop.beans2")
@ComponentScan(basePackages = "com.atoz_develop.beans3")
public class BeanConfigClass { }
@Configuration ํด๋์ค๋ฅผ ์ฌ์ฉํ ๊ฒฝ์ฐ @ComponentScan ์ ๋ ธํ ์ด์ ์ basePackages๋ฅผ ์ฌ์ฉํด์ ํจํค์ง๋ฅผ ์ค์ ํ๋ค.
ํจํค์ง๊ฐ ์ฌ๋ฌ๊ฐ์ผ ๊ฒฝ์ฐ ๋ฐฐ์ด๋ก ์ง์ ํ๋์ง, @ComponentScan์ ์ฌ๋ฌ๊ฐ ๋ถ์ด๋ ๋ฐฉ๋ฒ์ ์ฌ์ฉํ ์ ์๋ค.
@Component
@Component
public class TestBean { }
์ด๋ <Bean class=“…”/>์ ๋์ผํ ํํ์ด๋ค.
1) @Component๋ก ๋ฑ๋กํ ๋น ๊ฐ์ ธ์ค๊ธฐ
ApplicationContext ctx = new AnnotationConfigApplicationContext(BeanConfigClass.class);
TestBean1 t1 = ctx.getBean(TestBean1.class);
TestBean1 t1 = (TestBean1) ctx.getBean("testBean1");
TestBean1 t1 = ctx.getBean("testBean1", TestBean1.class);
@Component๋ฅผ ๋ถ์ฌ ๋น์ ๋ฑ๋กํ๋ฉด ํด๋์ค ์ด๋ฆ์ ์ฒซ ๋ฌธ์๋ฅผ ์๋ฌธ์๋ก ๋ฐ๊พผ ๊ฒ์ด ๋น์ ์ด๋ฆ(id)์ด ๋๋ค.
๋น ๊ฐ์ฒด๊ฐ ์์ฑ๋๋ ์์ ์ ApplicationContext ๊ฐ์ฒด๊ฐ ์์ฑ๋๋ ์์ ์ด๋ฉฐ ๊ธฐ๋ณธ์ ์ผ๋ก singleton scope์ด๋ค.
2) @Component("์ด๋ฆ")
@Component("tb")
public class TestBean { }
@Component("์ด๋ฆ")๊ณผ ๊ฐ์ด ๋น ์ด๋ฆ(id)๋ฅผ ์ง์ ํ ์ ์๋ค.
@Lazy
@Component
@Lazy
public class TestBean { }
@Component๋ฅผ ๋ถ์ฌ์ ๋ฑ๋กํ ๋น์ ๊ธฐ๋ณธ์ ์ผ๋ก ApplicationContext ๊ฐ์ฒด๊ฐ ์์ฑ๋ ๋ ๋น ๊ฐ์ฒด๊ฐ ์์ฑ๋๋๋ฐ @Lazy๋ฅผ ๊ฐ์ด ๋ถ์ด๋ฉด getBean()๊ณผ ๊ฐ์ด ํด๋น ๋น์ด ์ฌ์ฉ๋ ๋ ๋น ๊ฐ์ฒด๊ฐ ์์ฑ๋๋ค.
<Bean lazy-init="true"/>์ ๋์ผํ ํํ์ด๋ค.
@Scope
@Component
@Scope("prototype")
public class TestBean { }
@Component๋ฅผ ๋ถ์ฌ์ ๋ฑ๋กํ ๋น์ ๊ธฐ๋ณธ์ ์ผ๋ก singleton scope์ด ๋๋๋ฐ @Scope๋ฅผ ๋ถ์ฌ์ ๋น์ scope๋ฅผ ์ค์ ํ ์ ์๋ค.
<Bean>์ scope ์์ฑ๊ณผ ๋์ผํ ์ค์ ์ ํ ์ ์๋ค.
@PostConstruct, @PreDestroy
@Component
public class TestBean {
@PostConstruct
public void init() {
System.out.println("init ๋ฉ์๋ ํธ์ถ");
}
@PreDestroy
public void destroy() {
System.out.println("destroy ๋ฉ์๋ ํธ์ถ");
}
}
@PostConstruct๋ก ๋น ์์ฑ์ ํธ์ถ ์ดํ ์๋์ผ๋ก ํธ์ถ๋ ๋ฉ์๋์ @PreDestroy๋ก ๋น ๊ฐ์ฒด๊ฐ ์๋ฉธ๋ ๋ ์๋์ผ๋ก ํธ์ถ๋๋ ๋ฉ์๋๋ฅผ ๋ฑ๋กํ๋ค.
์๋ฐ์์ ์ ๊ณตํ๋ JSR-250 ์ ๋ ธํ ์ด์ ์ด๋ฉฐ ์ฌ์ฉํ๋ ค๋ฉด ๋ค์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ถ๊ฐํด์ผํ๋ค.
<!-- https://mvnrepository.com/artifact/javax.annotation/javax.annotation-api -->
<dependency>
<groupId>javax.annotation</groupId>
<artifactId>javax.annotation-api</artifactId>
<version>1.3.2</version>
</dependency>
์๋ ์ฃผ์
@Component๋ก ๋ฑ๋กํ ๋น์ ์๋ ์ฃผ์ ๋ฐฉ๋ฒ์ @Bean์ผ๋ก ๋ฑ๋กํ ๋น์ ์๋ ์ฃผ์ ๋ฐฉ๋ฒ๊ณผ ๋์ผํ๋ค.
@Autowired, @Qualifier, @Resource๋ฅผ ์ฌ์ฉํ ์ ์๋ค.
1) @Autowired
@Component
public class TestBean1 {
@Autowired
private DataBean1 data1;
}
@Component
public class DataBean1 { }
@Autowired๋ ๊ฐ์ ํ์ ์ ๋น์ ์๋ ์ฃผ์ ํ๋ฉฐ ํ๋์ ๋ถ์ด๋ฉด ํด๋น ํ๋์ setter๊ฐ ์๋์ผ๋ก ์์ฑ๋๋ค.
2) @Qualifier
@Component
public class TestBean1 {
@Autowired
@Qualifier("obj2")
private DataBean2 data2;
}
@Component("obj2")
public class DataBean2 { }
@Autowired์ @Qualifier๋ฅผ ํจ๊ป ์ฌ์ฉํ๋ฉด @Qualifier์ ์ง์ ๋ ์ด๋ฆ๊ณผ ๊ฐ์ ์ด๋ฆ์ ๋น์ ์ฐพ์ ์๋ ์ฃผ์ ๋๋ค.
3) @Resource
@Component
public class TestBean1 {
@Resource(name = "obj3")
private DataBean3 data3;
@Resource(name = "obj4")
private DataBean3 data4;
@Resource(name = "obj5")
private DataBean3 data5;
}
@Component("obj2")
public class DataBean2 { }
@Configuration
@ComponentScan(basePackages = "com.atoz_develop.beans")
public class BeanConfigClass {
@Bean
public DataBean3 obj4() {
return new DataBean3();
}
@Bean
public DataBean3 obj5() {
return new DataBean3();
}
}
JSR-250 ์ ๋ ธํ ์ด์ @Resource๋ ํ๋๋ช ๊ณผ ์ด๋ฆ์ด ๊ฐ์ ๋น์ ์ฐพ์ ์๋ ์ฃผ์ ํ๋ค.
@Resource(name = ์ด๋ฆ)๊ณผ ๊ฐ์ด ํน์ ์ด๋ฆ์ ์ง์ ํ๋ฉด ํ๋๋ช ์ด ์๋ ์ง์ ํ ์ด๋ฆ์ ๋น์ ์ฐพ์ ์๋ ์ฃผ์ ํ๋ค.
์ฌ์ฉํ๋ ค๋ฉด JSR-250 ์ ๋ ธํ ์ด์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ถ๊ฐํด์ผ ํ๋ค.
4) ์์ฑ์ ์๋ ์ฃผ์
@Component
public class TestBean3 {
private DataBean4 data3;
private DataBean5 data4;
public TestBean3(DataBean4 data3, DataBean5 data4) {
this.data3 = data3;
this.data4 = data4;
}
}
@Component
public class DataBean4 { }
@Component
public class DataBean4 { }
@Component๋ฅผ ๋ถ์ฌ ๋ฑ๋กํ ๋น์ ์์ฑ์ ์๊ท๋จผํธ์ ํ์ ์ด ๊ฐ์ ๋น์ด ์๋์ผ๋ก ์ฃผ์ ๋๋ค.
์ด๋ฌํ ์์ฑ์ ์๋ ์ฃผ์ ๋ฐฉ๋ฒ์ ์คํ๋ง 5.1๋ถํฐ deprecated๋ @Required์ ๊ฐ์ ๋ ๋์ฒด ๋ฐฉ๋ฒ์ด๋ค.
์ฆ ๋น์์ ๋ฐ๋์ ์ฃผ์ ํด์ผํ๋ ํ๋๋ ์์ฑ์ ์ฃผ์ ๋ฐฉ๋ฒ์ ์ฌ์ฉํ๋ค.
5) @Value
@Component
public class TestBean3 {
private int data1;
private String data2;
private DataBean4 data3;
private DataBean5 data4;
public TestBean3(@Value("100") int data1, @Value("๋ฌธ์์ด") String data2, DataBean4 data3, DataBean5 data4) {
this.data1 = data1;
this.data2 = data2;
this.data3 = data3;
this.data4 = data4;
}
}
์์ฑ์ ์๊ท๋จผํธ ์ค ๊ธฐ๋ณธ ํ์ ๊ณผ ๋ฌธ์์ด ํ์ ์ @Value๋ฅผ ์ฌ์ฉํด ์ฃผ์ ํ ๊ฐ์ ์ง์ ์ง์ ํ๋ค.
๋๊ธ