<์ถ์ฒ ์ธํ๋ฐ>
๊ณผ์ฐ ์คํ๋ง์ ์ด๋ค ์ด์ ์ ๊ฐ์ง๊ณ ์์๊น? ์ค์ ๋ก ์น์ฌ์ดํธ๋ฅผ ์ด์ํ๊ฒ ๋๋ฉด ๊ณ ๊ฐ์ ๋์ ์์ฒญ์ ์ฒ๋ฆฌํ๊ฒ ๋๋ค. ๋งค๋ฒ ๊ณ ๊ฐ์ ์์ฒญ์ ์ฒ๋ฆฌํ ๋ ๋ง๋ค ์๋ก์ด ๊ฐ์ฒด๋ฅผ ์์ฑํ๊ฒ ๋๋ฉด ๋ฉ๋ชจ๋ฆฌ ๊ณผ๋ถํ๊ฐ ์ค๊ณ ๋นํจ์จ์ ์ผ๋ก ์ด์ํ๊ฒ ๋ ๊ฒ์ด๋ค. ์คํ๋ง์ ์ด๋ฐ ๊ฒฝ์ฐ ์ด๋
ธํ
์ด์
์ ์ด์ฉํ์ฌ ๊ฐ๋จํ ์ฝ๋๋ก ์ฑ๊ธํค ํจํด์ ์ ์ง์์ผ์ฃผ๋ฉฐ ๊ฐ๋ฐ์๊ฐ ํจ์จ์ ์ด๊ฒ ๊ด๋ฆฌํ ์ ์๋๋ก ๋์์ค๋ค. ์ฑ๊ธํค ํจํด์ด ๋ฌด์์ด๋ฉฐ ์คํ๋ง์ด ์ด๋ค ์์ผ๋ก ์ฑ๊ธํค์ ๊ด๋ฆฌํด์ฃผ๋์ง ์์๋ณด์.
๐งธ
๐งธ ๊ตฌ์กฐํ์
๐งธ
singleton ใด class : SingletonService, SingletonTest, StatefulService, StatefulServiceTest, ConfigurationSingletonTest
AppConfig
Q. ์คํ๋ง์ ์ฌ์ฉํ๋ ์ด์ ๋?
A. ์ฑ๊ธํค ์ด ๋ณด์ฅ๋๊ธฐ ๋๋ฌธ์ด๋ค.
โ๏ธ SingletonTest
โบ pureContainer
์์ ์๋ฐ์ฝ๋๋ก ์์ฑ์๋ฅผ ์ง์ ํธ์ถํ๋ค.
AppConfig appConfig = new AppConfig();
MemberService memberService1 = appConfig.memberService();
MemberService memberService2 = appConfig.memberService();
์คํ๋ง ์ปจํ
์ด๋๋ฅผ ์ด์ฉํ์ง ์๊ณ ์ง์ AppConfig์ ๊ฐ์ฒด๋ฅผ ์์ฑํ๋ค. appConfig์ ์๋ memberService ๋ฉ์๋๋ฅผ ์ด์ฉํ๋๋ฐ ํ์
์ MemberService์ด๋ฉฐ ๊ฐ ์ด๋ฆ์ memberService1๊ณผ memberService2๊ฐ ๋๋ค. ์์ ์ฝ๋๋ ์ฑ๊ธํค ํจํด์ ๊ฐ์ง ํด๋์ค๋ฅผ ์ด์ฉํ์ง๋, ์คํ๋ง์ ์ด์ฉํ์ง๋ ์์๊ธฐ ๋๋ฌธ์ memberService1๊ณผ memberService2๋ ์๋ก ๋ค๋ฅธ ๊ฐ์ฒด๋ฅผ ๊ฐ์ง ๊ฒ์ด๋ค. ์ค์ ํ๋ก๊ทธ๋จ์์๋ ๋ค์ ๊ณ ๊ฐ์ ๋์ ์์ฒญ์ด ๋ฐ์ํ๋ค. ๊ณ ๊ฐ์ด ์์ฒญํ ๋๋ง๋ค AppConfig๋ ๊ฐ์ฒด๋ฅผ ์๋ก ์์ฑํด์ผํ๋ค. ์ด ๋ง์ ์์ฒญ๋ง๋ค ์๋ก์ด ๊ฐ์ฒด๋ฅผ ๋ง๋๋ ๊ฒ์ ๋ฉ๋ชจ๋ฆฌ ๋ญ๋น๋ฅผ ์ ๋ฐํ๋ค.
โธ ๊ฒฐ๊ณผ
๊ฐ ๊ฐ์ด 6a472554์ 7ff2a664๋ก ๋ค๋ฅธ ๊ฒ์ ํ์ธํ ์ ์๋ค. ๊ฐ์ฒด๊ฐ ๋ค๋ฅด๊ฒ ์์ฑ๋์๋ค๋ ๊ฒ์ ์๋ฏธํ๋ค.
••• ์ด์ด์ ๋ค๋ฅธ ์ฝ๋ ๋ถ๋ถ •••
Assertions.assertThat(memberService1).isNotSameAs(memberService2);
assertThat(A).isNotSameAs(B)
: ๋์ A์ ๋์ B์ ์ฃผ์๊ฐ์ด ๋ค๋ฅธ์ง ํ์ธํ๋ ๋ฉ์๋
Q. assertThat(A).isEqualTo(B)์ assertThat(A).isSameAs(B)์ ์ฐจ์ด์ ์ ๋ฌด์์ธ๊ฐ? A. isEqualTo ๋ ๋์์ ๋ด์ฉ์ ๋น๊ต ํ๊ณ isSameAs ๋ ๋์์ ์ฃผ์๊ฐ์ ๋น๊ต ํ๋ค. ์์) isEqualTo
String A = "Hi";
String B = "Hi";
assertThat(A).isEqualTo(B);โ
์์) isSameAs (==)
String A = "Hi";
String B = A;
assertThat(A).isSameAs(B);
โ๏ธ SingletonService
์ฑ๊ธํค ๋์์ธ ํจํด์ ๊ตฌํํ๋ค.
private static final SingletonService instance = new SingletonService();
private
: ์ธ๋ถ์์ ์ ๊ทผํ ์ ์๊ฒ ํ๋ค.
static
: instance ๋ณ์๊ฐ ํด๋์ค ์์ค์์ ๊ด๋ฆฌ๋๊ฒ ํ๋ฉฐ, ํด๋์ค๊ฐ ๋ฉ๋ชจ๋ฆฌ์ ๋ก๋๋ ๋ ์ธ์คํด์ค๊ฐ ์์ฑ๋๊ณ ํ๋ก๊ทธ๋จ ์ข
๋ฃ๋ ๋๊น์ง ์ ์ง๋๋ค.
final
: ์ธ์คํด์ค๊ฐ ํ ๋ฒ ์์ฑ๋๋ฉด ๋ณ๊ฒฝํ ์ ์๋ค.
Q. ์ฑ๊ธํค ํจํด์ static์ ์ ์ฐ๋๊ฑธ๊น? A. static์ ์ธ์คํด์ค(๋ฉ๋ชจ๋ฆฌ ์์ ์ฌ๋ผ๊ฐ ๊ฐ์ฒด)๋ฅผ ์๋ก ์์ฑํ์ง ์์๋ ์ ๊ทผ ๊ฐ๋ฅํ๊ฒ ํ๋ค. ์ฑ๊ธํค ํจํด์ ๋จ์ํ ํ๋์ ์ธ์คํด์ค๋ง ์์ฑํ๋ ๊ฒ์ด ์๋๋ค. ํ๋์ ์ธ์คํฐ์ค๋ฅผ ์์ฑ ํ ๊ณต์ ํด ์ฌ์ฉํ๋๋ก ํ๋ค. ์ฌ๊ธฐ์ static์ ํ๋์ ์ธ์คํด์ค๋ฅผ ์์ฑ๋๋๋ก ํ๋ฉฐ, ์ ์ญ์ ์ผ๋ก ๊ณต์ (์ฌ์ฉ)ํ๋๋ก ํ๊ฒ ํด์ค๋ค. private์ final์ ์ญํ ์ ์ธ๋ถ์์ ๋ณ๊ฒฝํ ์ ์๋๋ก ํด์ค๋ค.
- ์ฑ๊ธํค ํจํด๊ณผ static์ ๊ด๋ จ ์ถ์ฒ
์ฑ๊ธํด ํจํด( Singleton Pattern ) ๊ณผ static - Java ๋์์ธ ํจํด
์ฑ๊ธํค ํจํด์ด๋? ์ฑ๊ธํด ํจํด์ ์ผ๋ถ ์ฌ๋๋ค์ด static์ ์ ์ญ ๋ณ์์ ๊ฐ์ ๋ณด์ด๊ณ ๊ฐ์ฒด ์งํฅ์ด ์๋๋ผ๋ ์ฃผ์ฅ์ ์ด๋ฌํ ๋นํ์ ํด๊ฒฐํ๊ณ ์ ๋์๋ค๊ณ ๋ณผ ์ ์๋ค. ์ ํ๋ฆฌ์ผ์ด์
์ด ์์๋ ๋, ์ด๋ค
100100e.tistory.com
Q. ๊ฐ์ฒด์ ์ธ์คํด์ค์ ์ฐจ์ด A. ๊ฐ์ฒด๋ ์ ์ธ, ์ธ์คํด์ค๋ ์ค์ฒดํ๋ฅผ ์๋ฏธํ๋ค. ๊ฐ์ฒด๋ ํด๋์ค์ ํ์
์ผ๋ก ์ ์ธ๋์์ ๋, ์ธ์คํด์ค๋ ๊ทธ ๊ฐ์ฒด๊ฐ ๋ฉ๋ชจ๋ฆฌ ์์ ์ฌ๋ ค์ก์ ๋๋ฅผ ๋งํ๋ค. ๊ทธ๋ฌ๋๊น ํน๋ณํ ๊ฐ์ฒด๋ฅผ ์ธ์คํด์ค ๋ผ๊ณ ํ๋ค. (์ฉ์ด์ ์๋ฏธ๊ฐ ์กฐ๊ธ ๋ค๋ฅผ ๋ฟ, ๊ฐ์ฒด์ ์ธ์คํด์ค๋ ๊ฐ๋ค๊ณ ๋ณด๋ฉด ๋๋ ๊ฒ ๊ฐ๋ค.)
Dog myDog = new Dog();
Dog anotherDog = new Dog();
์์ ๋ ์ฝ๋์์ myDog์ anotherDog๋ Dog ํด๋์ค์ ๊ฐ์ฒด์ด์ ์ธ์คํด์ค ์์ ๋ํ๋ธ๋ค. ์ฆ, ๊ฐ์ฒด์ง๋ง ์ธ์คํด์ค๊ฐ ์๋ ๊ฒฝ์ฐ๋ ์๋ค ๊ณ ํ๋ค.
- ๊ฐ์ฒด์ ์ธ์คํด์ค์ ์ฐจ์ด์ ์ถ์ฒ
instance๋?
์ธ์คํด์ค๋ ๊ฐ์ฒด ์งํฅ ํ๋ก๊ทธ๋๋ฐ(Object Oriented Programming)์์ class์ ์์๋ ๊ฐ๋ณ์ ์ธ ๊ฐ์ฒด๋ฅผ ๋งํ๋ค.์๋ฅผ ๋ค์ด, user๋ผ๋ ํด๋์ค๋ฅผ ์ ์ํ๊ณ hong์ด๋ผ๋ ๊ฐ์ฒด๋ฅผ ์์ฑํ ๊ฒฝ์ฐ, hong์ด๋ผ๋ ๊ฐ์ฒด๋ user
velog.io
•••๊ทธ ๋ค์ ์ฝ๋ •••
public static SingletonService getInstance() {
return instance;
}
SingletonService์ ์ธ์คํด์ค๋ฅผ ์๋ก ๋ง๋ค์ง ์๊ณ , getInstance( ) ๋ฉ์๋๋ฅผ ํตํด ์ธ์คํด์ค๋ฅผ ์ ๊ทผํ๋ค. ๊ทธ๋ฌ๋๊น static์ผ๋ก ์ ์ญ์ ์ผ๋ก ๊ณต์ ๋ ๊ฒ์ ์ฌ์ฉํ๊ฒ ํด์ฃผ๋ ๋ฉ์๋๊ฐ getInstance( )์ธ ๋ฏ ํ๋ค.
private SingletonService() {
}
์์ฑ์
: ์ธ์คํด์ค๋ฅผ ๋ง๋ค ๋ ํธ์ถ๋๋ ํน๋ณํ ๋ฉ์๋
Q. ์์ฑ์๊ฐ ์ ํํ๊ฒ ๋ฌด์์ธ๊ฐ? A. ๊ฐ์ฒด๊ฐ ์์ฑ๋ ๋ ์๋์ผ๋ก ํธ์ถ๋๋ ํน์ ๋ชฉ์ ์ ๋ฉค๋ฒํจ์(๋ฉ์๋)๋ก ๊ฐ์ฒด์ ์ด๊ธฐํ๋ฅผ ์ํด ์ฌ์ฉ ํ๋ค. ๋ฌด์กฐ๊ฑด ํด๋์ค๋น ํ๋๊ฐ ์์ด์ผํ๋ฉฐ, ๊ฐ์ฒด๊ฐ ์์ฑ๋๋๋ฐ ๊ทธ์ ๋ง๋ ์์ฑ์๊ฐ ์์ ๊ฒฝ์ฐ ์ปดํ์ผ๋ฌ๊ฐ ์๋์ผ๋ก ๊ธฐ๋ณธ์์ฑ์๋ฅผ ์์ฑ ํ๊ฑฐ๋ ์ค๋ฅ๊ฐ ๋ฐ์ํ ์ ์๋ค.
public Book() { } // ๊ธฐ๋ณธ์์ฑ์
public Book(String title, int price) { // ๋งค๊ฐ๋ณ์๋ฅผ ๊ฐ์ง ์์ฑ์
this.title = title;
this.price = price;
}
Book b1 = new Book(); // ๊ฐ์ฒด์์ฑ - ๊ธฐ๋ณธ์์ฑ์ ํธ์ถ๋จ
Book b2 = new Book("๊ตญ์ด์ฑ
", 3000); // ๊ฐ์ฒด์์ฑ - ๋งค๊ฐ๋ณ์๋ฅผ ๊ฐ์ง ์์ฑ์ ํธ์ถ๋จ
- ์์ฑ์์ ๋ํ ์ค๋ช
์ถ์ฒ
[Java] ์๋ฐ - ์์ฑ์์ ๋ชฉ์ , ํน์ง, ์ฌ์ฉ๋ฒ (Constructor)
์๋ฐ - ์์ฑ์์ ๋ชฉ์ , ํน์ง, ์ฌ์ฉ๋ฒ 1. ์์ฑ์์ ๋ชฉ์ ์์ฑ์(Constructor)๋ ๊ฐ์ฒด๊ฐ ์์ฑ๋ ๋ ์๋์ผ๋ก ํธ์ถ๋๋ ํน์ ๋ชฉ์ ์ ๋ฉค๋ฒํจ์(๋ฉ์๋)๋ก ๊ฐ์ฒด์ ์ด๊ธฐํ๋ฅผ ์ํด ์ฌ์ฉ๋ฉ๋๋ค. 2. ์์ฑ์์ ํน
kadosholy.tistory.com
Q. ๊ทธ๋ ๋ค๋ฉด ์์ ์์ฑ์๋ ๊ธฐ๋ณธ ์์ฑ์์ธ๊ฐ? ์ ์ฐ๋๊ฑธ๊น? A. ์์ ์์ฑ์๋ ๊ธฐ๋ณธ์์ฑ์์ ์ฐจ์ด๊ฐ ์๋ค. ์ผ๋จ ๊ธฐ๋ณธ ์์ฑ์๋ public์ ๊ธฐ๋ฐ์ผ๋ก ํ๋๋ฐ, ์์ ์ฝ๋๋ private๋ก ๊ฐ๋ฐ์๊ฐ ์ ์ํ ๋ช
์์ ์์ฑ์ (๋งค๊ฐ๋ณ์๊ฐ ์๋)๋ค. private๋ฅผ ์ฌ์ฉํ ์ด์ ๋ ์ฑ๊ธํค ํจํด์ ๋ง๋ค๊ธฐ ์ํด ์ธ๋ถ์์ ์ธ์คํด์ค๋ฅผ ๋ง๋ค ์ ์๋๋ก ํ๊ธฐ ์ํจ ์ด๋ค.
••• ์ฐ๊ฒฐ๋ ํ
์คํธ ์ฝ๋ ํ์ธํ๊ธฐ •••
โ๏ธ SingletonTest
โบ singletonServiceTest
SingletonService singletonService1 = SingletonService.getInstance();
SingletonService singletonService2 = SingletonService.getInstance();
SingletonService์ ์ฝ๋๋ฅผ ์๊ฐํด๋ณด๋ฉด ์ธ์คํด์ค๋ฅผ ์ธ๋ถ์์ ๋ง๋ค์ง ๋ชปํ๋๋ก private ์์ฑ์๋ฅผ ๋ง๋ค์๋ค. ๊ทธ๋ฆฌ๊ณ static, final, private๋ก ์ธ์คํด์ค ๋ณ๊ฒฝ์ ๋ถ๊ฐํ๊ฒ ๋ง๋ค์๋ค. ๊ทธ๋ฐ๋ฐ ์ ์ญ์ ์ผ๋ก ๊ณต์ ๋ฅผ ํ๊ธฐ ์ํด getInstance ๋ฉ์๋๋ฅผ ๋ง๋ค์๋ค. getInstance( )๋ฅผ ํตํด ์ ๊ทผ ํ์ฌ singletonService1๊ณผ singletonService2์ ์ธ์คํด์ค๋ฅผ ๋ฐํ๋ฐ๋ ๊ฒ ์ด๋ค. ์์ฑ์๋ฅผ ์ง์ ํธ์ถํ์ง ์๊ณ ํด๋์ค ๋ด์์ ๊ด๋ฆฌํ๋ ์ ์ผํ ์ธ์คํด์ค๋ฅผ ๋ฐํํ๋ ์ ์ ๋ฉ์๋๋ฅผ ์ฌ์ฉ ํ๋ ๊ฒ์ด๋ค.
โบ singleton ๋ฉ๋ชจ๋ฆฌ ๋์ ์ดํด๋ณด๊ธฐ
# SingletonService
private static final SingletonService instance = new SingletonService();
# SingletonTest
SingletonService singletonService1 = SingletonService.getInstance();
SingletonService singletonService2 = SingletonService.getInstance();
ํด๋์ค๊ฐ ๋ก๋ฉ๋๋ฉด instance ๋ณ์๊ฐ ๋ฉ์๋ ์์ญ์ ์ ์ฌ ๋๋ค. ๊ทธ๋ฐ๋ฐ ์ด๋ instance ์ค์ ๊ฐ์ด ๋ฉ์๋ ์์ญ์ ์๋ ๊ฒ์ด ์๋๋ผ, instance๋ผ๊ณ ์ด๋ฆ๋ง ๋ถ์ฌ์ง ๊ป๋ฐ๊ธฐ๋ง ๋ฉ์๋ ์์ญ์ ์์ผ๋ฉฐ ์ค์ ๊ฐ์ฒด๋ ํ ์์ญ์ ์ ์ฅ ๋์ด์๋ค. ๋ฉ์๋ ์์ญ์๋ ํ ์์ญ์ ์๋ ์ค์ ๊ฐ์ฒด๊ฐ์ ๊ฐ๋ฆฌํค๋ ์ฃผ์๊ฐ ์์น๊ฐ ์กด์ฌ ํ๋ค. singletonService1์ ์คํ ์์ญ์ ์์ฑ ๋๊ฒ ๋๋ค. ๊ทธ๋ฌ๋ฉด singletonService1์ ๋ฉ์๋ ์์ญ์ instance๊ฐ ๊ฐ๋ฆฌํค๋ ํ์ ์ฃผ์๋ฅผ ๋ณต์ฌํ์ฌ ์ ์ฅ ํ๋ค. ๊ทธ ํ singletonService2๊ฐ ์์ฑ๋์ด๋ singletonService1์ ๊ฐ์ด ๋ฉ์๋ ์์ญ์ด ๊ฐ๋ฆฌํค๊ณ ์๋ instance ํ์ ์ฃผ์๋ฅผ ๋ณต์ฌํ์ฌ ์ ์ฅํ๋ค. ๊ทธ๋์ ์ฌ๋ฌ๊ฐ๋ฅผ ์์ฑํด๋ ํ๋์ ๊ฐ์ฒด๋ง ๊ฐ๋ฆฌํค๊ฒ ๋๋ ๊ฒ ์ด๋ค. ๋ง์ฝ static์ ๋ถ์ด์ง ์๊ฒ ๋๋ฉด instance๋ ๋ฉ์๋์ ์ ์ฌ๋์ง ์๊ณ ํ์ ์ ์ฌ ๋๋ค. ์ด๋ ์คํ์๋ ๊ฐ์ฒด ์ฌ์ฉ์ ์๊ตฌํ๋ ๋ณ์๊ฐ ๋ค์ด์ค๊ฒ ๋๋ฉด ํ ์์ญ์ ์๋ instance๋ ๊ณ์ํด์ ๋ง๋ค ์ ์๋ ํน์ฑ ์ ๊ฐ์ง๊ฒ ๋๊ธฐ ๋๋ฌธ์ new SingletonService( )๋ฅผ ํธ์ถํ์ฌ ์ฌ๊ท์ ์ผ๋ก instance์ ์๋ก์ด ๊ฐ์ฒด๋ฅผ ๋ฐํ ํ๋ค.
โบ ๊ฒฐ๋ก
์ฑ๊ธํค ํจํด์ ์ฌ์ฉํ๋ฉด DIP,OCP๋ฅผ ์๋ฐํ ์ ์๋ค. ๋๊ตฌ๋ private ์ฌ์ฉ์ผ๋ก ์ธํด ์ ์ฐ์ฑ๋ ๋จ์ด์ง๋ค.
๊ทธ๋ ๊ธฐ์ ์คํ๋ง ์ปจํ
์ด๋๋ฅผ ์ฌ์ฉํ์ฌ ์ธ์คํด์ค๋ฅผ ์ฑ๊ธํค์ผ๋ก ์ ์งํ๋ ๋ฐฉ์์ ์ฌ์ฉํ ๊ฒ์ด๋ค.
โ๏ธ SingletonTest
โบ springContainer
// ์คํ๋ง์ ์ฌ์ฉํ๊ธฐ ์ํด ์๋ ์ฝ๋ ์ ์
ApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class);
MemberService memberService1 = ac.getBean("memberService", MemberService.class);
MemberService memberService2 = ac.getBean("memberService", MemberService.class);
AppConfig์ ์ ์๋์ด์๋ memberService๋ผ๋ ์ด๋ฆ์ ๊ฐ์ง ๋น์ MemberService ํ์
์ผ๋ก ๋ฐํํ๋ค. ์ด๋ ์คํ๋ง ์ปจํ
์ด๋์ ํน์ฑ์ ์ํด ๊ฐ์ ๋น ์ธ์คํด์ค๋ฅผ ํ ๋นํ๋ค.
๊ฐ์ ๊ฒฐ๊ณผ๊ฐ์ด ๋์จ ๊ฒ์ ํ์ธํ ์ ์๋ค.
โ๏ธ StatefulService
๊ฐ์ฒด ์ธ์คํด์ค๋ฅผ ํ๋๋ง ์์ฑํด์ ๊ณต์ ํ๋ ์ฑ๊ธํค ๋ฐฉ์์ ๋ฌด์ํ๋ก ์ค๊ณํด์ผํ๋ค .
โบ ์ํ๋ฅผ ์ ์งํ๋๋ก ์ค๊ณํ ๊ฒฝ์ฐ ๋ฐ์ํ๋ ๋ฌธ์ ์
# StatefulService
private int price;
public void order(String name, int price) {
...
this.price = price;
}
# StatefulServiceTest
statefulService1.order("userA", 20000);
statefulService2.order("userB", 10000);
int price = statefulService1.getPrice();
System.out.println("price = " + price);
์ฒ์์ order์ 20000์ด ๋ค์ด์๋ค. ๊ทธ๋ฌ๋ฉด this๋ฅผ ํตํด ๋ค์ด์จ ๊ฐ์ ํ๋์ ์๋ price๋ก ๋ค์ด๊ฐ๋ฉด์ ๊ฐ์ด ๊ณต์ ๋๋ค. ๊ทธ๋ฆฌ๊ณ ๋์ userB๊ฐ 10000์ ์ฃผ๋ฌธํ๋ค. ๊ทธ๋ฌ๋ฉด ๋ค์ ํ๋๋ 10000์ ๊ฐ์ ๊ฐ์ง๊ฒ ๋๋ค. ๊ฐ์ด ์ฆ๊ฐ์ ์ผ๋ก ๋๋ ค์ง๋ ๋ฐฉ์์ด ์๋ ์ด๋ ๊ฒ ์ํ๋ฅผ ์ ์งํ๋ ๋ฐฉ์์ผ๋ก ์ค๊ณํ๊ธฐ ๋๋ฌธ์ ์ต์ข
์ ์ผ๋ก price์ ๊ฐ์ 10000์ด ๋๊ณ ๊ทธ ํ์ statefulService1์ price๋ฅผ ์ถ๋ ฅํ๋ ๋ง์ง๋ง ์ํ์๋ 10000์ด ๋์ค๊ฒ ๋๋ค.
โบ ๋ฌด์ํ๋ก ์ค๊ณํ๊ธฐ
public int order(String name, int price) {
...
return price;
}
order ๋ฉ์๋๊ฐ ๊ฐ๊ฒฉ์ ๋ฐ๋ก ๋ฐํํ๋๋ก ์ค๊ณ ํ๋ฉด ๋๋ค. ์ด๋ ๊ฒํ๋ฉด ์ํ๋ฅผ ์ ์งํ์ง ์๊ณ , ๊ฐ ์์ฒญ์ด ๋
๋ฆฝ์ ์ผ๋ก ์ฒ๋ฆฌ๋ ์ ์๋ค.
โ๏ธ StatefulServiceTest
โบ TestConfig
@Bean
public StatefulService statefulService() {
return new StatefulService();
}
@Bean์ ์จ์ ๊ฐ๋จํ ์ค์ ํด๋์ค๋ฅผ ๋ง๋ค์๋ค.
•••๊ทธ ๋ค์ ์ฝ๋ •••
StatefulService statefulService1 = ac.getBean(StatefulService.class);
StatefulService statefulService2 = ac.getBean(StatefulService.class);
statefulService1๊ณผ statefulService2์ ์ธ์คํด์ค๋ฅผ ์๊ตฌํ๋ค. ๊ทธ๋ฌ๋ฉด TestConfig์ ์๋ StatefulService๋ก ๊ฐ์ ์ธ์คํด์ค๋ฅผ ์์ฑํ๊ณ ๋ฐํํ๋ค.
•••๊ทธ ๋ค์ ์ฝ๋ •••
int userAprice = statefulService1.order("A", 2000);
int userBprice = statefulService2.order("B", 1000);
StatefulService์ order ๋ฉ์๋๋ฅผ ํธ์ถํ๋ค. ์์๋๋ก ๋ด๋ถ์ํํ๋ price์ ๊ฐ ๊ฐ์ ์ ์ฅํ๊ณ ์ด ๊ฐ์ ๋ฐํํ๋ค.
์ ์์ ์ผ๋ก ๋ฐํํ๋ค
โ๏ธ ์๋ฐ ์ฝ๋์ ์ฑ๊ธํค ์ ์ง๋ฒ
โบ App Config
@Bean
public MemberService memberService() {
System.out.println("call AppConfig.memberService");
return new MemberServiceImpl(memberRepository());
}
@Bean
public MemberRepository memberRepository() {
System.out.println("call AppConfig.memberRepository");
return new MemoryMemberRepository();
}
@Bean
public OrderService orderService() {
System.out.println("call AppConfig.orderService");
return new OrderServiceImpl(memberRepository(), rateDiscountPolicy());
}
์ฝ๋๋ฅผ ์ดํด๋ณด๋ฉด memberService์์ memberRepository๊ฐ ํธ์ถ๋๊ณ memberRepository์ ์๋ MemoryMemberRepository๊ฐ ํธ์ถ๋๋ค. memberRepository์์ MemoryMemberRepository๊ฐ ํธ์ถ๋๋ค. orderService์์ memberRepository๊ฐ ํธ์ถ๋๊ณ memberRepositorysms MemoryMemberRepository๋ฅผ ํธ์ถํ๋ค. ๊ทธ๋ ๊ฒ ์ด 3๋ฒ์ MemoryMemberRepository๊ฐ ํธ์ถ๋๋ ๊ฒ์ผ๋ก ๋ณด์ด๋ฉด์ ์ฑ๊ธํค์ด ๊นจ์ ธ๋ณด์ธ๋ค. ๊ณผ์ฐ ์ง์ง๋ก ์ฑ๊ธํค์ด ๊นจ์ง๋์ง ํ์ธํด๋ณด์.
โบ MemberServiceImpl
public MemberRepository getMemberRepository() {
return memberRepository;
}
memberRepository๊ฐ private final๋ก ์ ์๋์ด์๊ธฐ์ ์ธ๋ถ ํ
์คํธ ํด๋์ค์์ memberRepository๋ฅผ ์ฌ์ฉํ๊ธฐ ์ํดgetMemberRepository๋ฅผ ์ด์ฉํ์ฌ ๊ฐ์ฒด๋ฅผ ๊ฐ์ ธ์จ๋ค. ์ด๋ memberRepository๋ ์ธํฐํ์ด์ค๋ก MemoryMemberRepository์ ์์๋์ด์๋ค.
โบ ConfigurationSingletonTest
MemberRepository memberRepository1 = memberService.getMemberRepository();
MemberRepository memberRepository2 = orderService.getMemberRepository();
System.out.println("memberService -> memberRepository1 = " + memberRepository1);
System.out.println("orderService -> memberRepository2 = " + memberRepository2);
System.out.println("memberRepository = " + memberRepository);
memberService์ orderService๋ getMemberRepository๋ฅผ ํตํด memberRepository์ ๊ฐ์ฒด๋ฅผ ์ถ๋ ฅํ๋ค. ์ถ๋ ฅ ๊ฒฐ๊ณผ memberRepository๋ ๊ฐ์ ์ธ์คํด์ค๊ฐ ๊ณต์ ๋์ด ์ฌ์ฉ ํ๊ณ ์์์ ์ ์ ์๋ค.
โบ ์ด์ ์ ๋ํ์ฌ
@Configuration
public class AppConfig {
@Configuration์ด ๋ถ๊ฒ๋๋ฉด AppConfig๋ ๋ด๊ฐ ๋ง๋ ํด๋์ค๊ฐ ์๋ ์คํ๋ง์ด CGLIB๋ผ๋ ๋ฐ์ดํธ์ฝ๋ ์กฐ์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํด์ AppConfig ํด๋์ค๋ฅผ ์์๋ฐ์ ์์์ ๋ค๋ฅธ ํด๋์ค๋ฅผ ๋ง๋ค๊ณ ๊ทธ ๋ค๋ฅธ ํด๋์ค๋ฅผ ์คํ๋ง ๋น์ผ๋ก ๋ฑ๋กํ ๊ฒ์ ์ ์ ์๋ค. ์ฆ AppConfig์ AppConfig@CGLIB๊ฐ ์ค๋ฒ๋ผ์ด๋ฉ ๋์ด์ ์ค์ ์คํ์ AppConfig@CGLIB๊ฐ ๋ ๊ฒ ์ด๋ค. ๋ง์ฝ @Configuration์ ๋ถ์ด์ง ์์ผ๋ฉด @Bean์ด ๋ถ์ ๋ฉ์๋๊ฐ ํธ์ถ๋ ๋๋ง๋ค ์๋ก์ด ์ธ์คํด์ค๋ฅผ ์์ฑํ๊ฒ ๋ ๊ฒ์ด๋ค.
๐ท
์ด๋ ๊ฒ ์ฑ๊ธํค์ ์ด๋ป๊ฒ ๋ง๋๋์ง, ์คํ๋ง์ด ์ฑ๊ธํค์ ์ด๋ค ๋ฐฉ์์ผ๋ก ๋ณด์ฅํด๋์ง์ ๋ํด ์์๋ณด์๋ค.
์คํ๋ง ์ปจํ
์ด๋ ์์ฒด์ ์ผ๋ก ๋น์ ํ ๋ฒ๋ง ์์ฑํ๊ณ ์ฌ์ฌ์ฉํ๋ ๊ฒ๋ ์๊ฒ๋์์ง๋ง,
@Configuration์ ํตํด ์๋ฐ ์ฝ๋๋ ๊ฐ์ ๋ฐฉ์์ผ๋ก ๋์ํ๊ฒ ํ๋ค๋ ๊ฑธ ์ ์ ์์๋ค.