์คํ๋ง์ ์น ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ตฌํํ๋ ๋ชฉ์ ์ผ๋ก ์ฃผ๋ก ์ฌ์ฉํ๋ค. ๋ฐ๋ผ์ ์ฌ๋ฌ ๊ณ ๊ฐ์ด ๋์์ ์์ฒญ์ ํ๋ค!!
๋ค์๊ณผ ๊ฐ์ ๊ณ ๊ฐ์๊ฒ ๋์์ ์์ฒญ์ด ๋ค์ด์ฌ ๋ ๊ฐ์ฒด๊ฐ ๊ณ์ ์์ฑ๋์ด ๋ฉ๋ชจ๋ฆฌ ๋ญ๋น๊ฐ ๋งค์ฐ ์ฌํ ์ ์๋ค.
๋ํ ๊ฐ์ฒด์ ์์ฑ๋ ๋น์ฉ์ด๊ธฐ ๋๋ฌธ์ ๊ธฐ์
์
์ฅ์์๋ ์์ฒญ๋ ๋น์ฉ์ด ๋๊ฐ๊ฒ์ด๋ค.
์์ ์ํฉ์ ์ฝ๋๋ก ๋ํ๋ด์๋ค!
@Test
@DisplayName("์คํ๋ง ์๋ ์์ํ DI ์ปจํ
์ด๋")
void pureContainer(){
AppConfig appConfig = new AppConfig();
//1. ์กฐํ: ํธ์ถํ ๋ ๋ง๋ค ๊ฐ์ฒด๋ฅผ ์์ฑ
MemberService memberService1 = appConfig.memberService();
//2. ์กฐํ: ํธ์ถํ ๋ ๋ง๋ค ๊ฐ์ฒด๋ฅผ ์์ฑ (๋ฉ๋ชจ๋ฆฌ ๋ญ๋น) -> ์ฑ๊ธํค ํจํด์ ํตํด ํด๊ฒฐ
MemberService memberService2 = appConfig.memberService();
System.out.println("memberService1 = " + memberService1);
System.out.println("memberService2 = " + memberService2);
//memberService 1 != memberService2
assertThat(memberService1).isNotSameAs(memberService2);
}
์๋น์ค๋ฅผ ์์ฒญํ ๋๋ง๋ค ์๋ก์ด ๊ฐ์ฒด๊ฐ ์์ฑ๋๋ ๊ฒ์ ๋ณผ์ ์๋ค...๐ฎโ๐จ
์์ ๊ฐ์ ์ํฉ์์ ํด๊ฒฐํ ์ ์๋ ๋ฐฉ๋ฒ์ ์ฑ๊ธํค ํจํด์ด๋ค. ๋์์ธ ํจํด์ ๋์ค์ ๋ฐ๋ก ํฌ์คํ ํ ์์ ์ด๋ค.
์ฑ๊ธํค ํจํด์ ๋ํด ๊ฐ๋ตํ ์ด์ผ๊ธฐํ์๋ฉด ํด๋์ค์ ์ธ์คํด์ค๋ฅผ 1๊ฐ๋ง ์์ฑํ๋๋ก ํ๋ ๋์์ธ ํจํด์ด๋ค.
์คํ๋ง ์ปจํ
์ด๋๋ ์ฑ๊ธํค ํจํด ์ฝ๋๋ฅผ ์ฌ์ฉํ์ง ์์๋ ๊ฐ์ฒด ์ธ์คํด์ค๋ฅผ ์ง์ ์ฑ๊ธํค ํจํด์ผ๋ก ๊ด๋ฆฌํ๊ณ , ๋์์ ์ฑ๊ธํค ํจํด ์ฌ์ฉ์ ๋ฐ์ํ๋ DIP(์์กด๊ด๊ณ ์ญ์ ์์น), OCP(๊ฐ๋ฐฉ-ํ์ ์์น) ์๋ฐ์ ๋ฐ์์ ๋ง์์ค๋ค.
๋ค์์ ์คํ๋ง ์ปจํ ์ด๋๋ฅผ ์ฌ์ฉํ ํ ์คํธ ์ฝ๋์ด๋ค!
@Test
@DisplayName("์คํ๋ง ์ปจํ
์ด๋์ ์ฑ๊ธํค")
void springContainer(){
//AppConfig appConfig = new AppConfig();
//์คํ๋ง์ ์ฑ๊ธํค ๋ฐฉ์์ผ๋ก ๋์ํ๋ค.
ApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class);
MemberService memberService1 = ac.getBean("memberService", MemberService.class);
MemberService memberService2 = ac.getBean("memberService", MemberService.class);
//์ฐธ์กฐ๊ฐ ํ์ธ
System.out.println("memberService1 = " + memberService1);
System.out.println("memberService2 = " + memberService2);
assertThat(memberService1).isSameAs(memberService2);
}
๊ฒฐ๊ณผ๋ฅผ ๋ณด๋ฉด ๊ฒ์ ์ ์ฌ๊ฐํ์ผ๋ก ํ์ํ ๋ถ๋ถ์ด ์๋น์ค๋ฅผ ์์ฒญํ์ ๋ ์ฐธ์กฐ๊ฐ์ด๋ค. ์ฐธ์กฐ๊ฐ์ด ๊ฐ์ ๊ฒ์ ๋ณผ ์ ์๋ค.
์ ์ฝ๋์ ๊ฒฐ๊ณผ์ด๋ค. ์๋ก์ด ์ธ์คํด์ค ์์ฑ์ด ์๋ ์ด๋ฏธ ๋ง๋ค์ด์ง ๊ฐ์ฒด๋ฅผ ๊ณต์ ํ์ฌ ๋ฉ๋ชจ๋ฆฌ์ ๋ญ๋น์ ๋น์ฉ์ ์ค์ผ ์ ์๋ ๊ฒ์ด๋ค.๐๐ป๐๐ป๐๐ป
์ฑ๊ธํค ํจํด์ด๋ , ์คํ๋ง ๊ฐ์ ์ฑ๊ธํค ์ปจํ ์ด๋๋ฅผ ์ฌ์ฉํ๋ , ๊ฐ์ฒด ์ธ์คํด์ค๋ฅผ ํ๋๋ง ์์ฑํด์ ๊ณต์ ํ๋ ์ฑ๊ธํค ๋ฐฉ์์ ์ฌ๋ฌ ํด๋ผ์ด์ธํธ๊ฐ ํ๋์ ๊ฐ์ฒด ์ธ์คํด์ค๋ฅผ ๊ณต์ ํ๊ธฐ ๋๋ฌธ์ ์ฑ๊ธํค ๊ฐ์ฒด๋ ์ํ๋ฅผ ์ ์งํ๊ฒ ์ค๊ณํ๋ฉด ์๋๋ค.
์ฆโ๏ธ ํน์ ํด๋ผ์ด์ธํธ์ ์์กด์ ์ธ ํ๋๊ฐ ์์ผ๋ฉด ์๋๋ค.
๋ค์ ์ฝ๋๋ฅผ ๋ณด์!
package hello.core.singleton;
public class StatefulService {
private int price; //์ํ๋ฅผ ์ ์งํ๋ ํ๋
public void order(String name, int price){
System.out.println("name = " + name + " price = " + price);
this.price = price; //๋ฌธ์ !!
}
public int getPrice(){
return price;
}
}
package hello.core.singleton;
import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import static org.junit.jupiter.api.Assertions.*;
class StatefulServiceTest {
@Test
void statefulServiceSingleton(){
ApplicationContext ac = new AnnotationConfigApplicationContext(TestConfig.class);
StatefulService statefulService1 = ac.getBean("statefulService", StatefulService.class);
StatefulService statefulService2 = ac.getBean("statefulService", StatefulService.class);
statefulService1.order("userA", 10000);
statefulService2.order("userB", 20000);
//ThreadA: ์ฌ์ฉ์ A ์ฃผ๋ฌธ ๊ธ์ก ์กฐํ ๊ธฐ๋์ ๋ฌ๋ฆฌ 20000์์ด ๋์ด...
int price = statefulService1.getPrice();
System.out.println("price = " + price);
Assertions.assertThat(statefulService1.getPrice()).isEqualTo(20000);
}
static class TestConfig{
@Bean
public StatefulService statefulService(){
return new StatefulService();
}
}
}
์ฌ์ฉ์A์ ์ฃผ๋ฌธ๊ธ์ก์ 10000์์ธ๋ฐ price ํ๋๋ฅผ ๊ณต์ ํ์ฌ 20000์์ด๋ผ๋ ์ด์ํ ๊ฒฐ๊ณผ๊ฐ์ด ๋์๋ค.
๐๋ฐ๋ผ์ ์คํ๋ง ๋น์ ํญ์ ๋ฌด์ํ(staeteless)๋ก ์์กด์ ์ธ ํ๋ ์์ด ์ค๊ณํด์ผ ํ๋คโ๏ธโ๏ธ