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

[Spring] @Component ์• ๋…ธํ…Œ์ด์…˜ ๋ฐ ํ•จ๊ป˜ ์‚ฌ์šฉํ•˜๋Š” ์• ๋…ธํ…Œ์ด์…˜ ์ •๋ฆฌ

by Leica 2020. 4. 25.
๋ฐ˜์‘ํ˜•

[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๋ฅผ ์‚ฌ์šฉํ•ด ์ฃผ์ž…ํ•  ๊ฐ’์„ ์ง์ ‘ ์ง€์ •ํ•œ๋‹ค.

๋ฐ˜์‘ํ˜•

๋Œ“๊ธ€