Singleton
Singleton ํจํด?

โ ์ธ์คํด์ค๊ฐ ํ๋๋ง ์กด์ฌํ๋ ๊ฒ์ ๋ณด์ฆํ๋ ํจํด
์ฅ์
- ์ธ์คํด์ค๊ฐ ํ๋๋ง ์กด์ฌํ๊ธฐ ๋๋ฌธ์ ๋ฉ๋ชจ๋ฆฌ ๋ญ๋น๋ฅผ ๋ฐฉ์งํ ์ ์์
- ์ ์ญ ์ธ์คํด์ค์ด๊ธฐ ๋๋ฌธ์ ๋ค๋ฅธ ํด๋์ค์ ์ธ์คํด์ค๋ค์ด ๋ฐ์ดํฐ๋ฅผ ๊ณต์ ํ๊ธฐ ์ฌ์, ๋ฐ์ดํฐ ์ผ๊ด์ฑ ๋ณด์ฅ
- ์ดํ๋ฆฌ์ผ์ด์ ์ ์ธํ ๊ฐ( ๋ฐฐ๊ฒฝ์ ), DBCP, ๋ก๊ทธ ๊ธฐ๋ก ๊ฐ์ฒด
- DBCP! ํ ๋ง์์!
- db์ ์๋ฒ๊ฐ ์ฐ๊ฒฐํ๋ connection ์์ ์ ๋น์ฉ์ด ํผ โ ๋ค์์ ์ฌ์ฉ์ ๋์๋ค๋ฐ์ ์ผ๋ก ์ฌ์ฉ์ ์๋ฒ ๋ค์ด์ฌ๋ฌ ์ปค๋ฅ์ ๋ค์ ๋ฏธ๋ฆฌ ๋ด์๋๊ณ ํด๋ผ์ด์ธํธ๊ฐ ์์ฒญํ ๋๋ง๋ค ํ๋์ฉ ๊บผ๋ด์ ๋น๋ ค์ค
- ์ปค๋ฅ์ ์ด ๋ค ๋จ์ด์ง๋ฉด ๋ค๋ฅธ ํด๋ผ์ด์ธํธ๊ฐ ๋ฐํํ ๋๊น์ง ๋๊ธฐ์ํ๋ก ์ ํ
๋ค์ด์ด๊ทธ๋จ

๊ธฐ๋ณธ ๊ณจ๊ฒฉ : Eager Initialization (์ด๋ฅธ ์ด๊ธฐํ)
public class Singleton{
private static Singleton singleton = new Singleton();
private Singleton() {
System.out.println("์ธ์คํด์ค๋ฅผ ์์ฑํ์ต๋๋ค.");
}
public static Singleton getInstance() {
return singleton;
}
}
- ๊ฐ์ฅ ๊ฐ๋จํ ํํ์ ๊ตฌํ ๋ฐฉ๋ฒ
- ํด๋์ค ์ธ์คํด์ค ํด๋์ค ๋ก๋ฉ ๋จ๊ณ์์ ์์ฑ
โ ํด๋น ์ธ์คํด์ค๋ฅผ ์ฌ์ฉํ์ง ์๋๋ผ๋ ์ธ์คํด์ค ์์ฑ โ ๋ฉ๋ชจ๋ฆฌ ๋ญ๋น ์ด๋
โ ์ฑ๊ธํค ํด๋์ค๊ฐ ๋งค์ฐ ์ ์ ๋ฆฌ์์ค๋ฅผ ๋ค๋ฃฐ ๋ ์ ์
1. Lazy Initialization : ๋์ค์ ์ด๊ธฐํ
public class Singleton{
private static Singleton instance;
private Singleton() {}
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return singleton;
}
}
๋ฉํฐ ์ค๋ ๋ฉ ํ๊ฒฝ์์ ๊ฐ์ฒด๊ฐ ํ๋์์ ๋ณด์ฆํ์ง ๋ชปํ๋ค.
like ์๋ฆฌ-์์ ๋ ์คํ ๋
2. Thread Safe Singleton
public class Singleton {
private static Singleton instance;
private Singleton(){}
public static synchronized Singleton getInstance(){
if(instance == null){
instance = new Singleton();
}
return instance;
}
}
getInstance()ํ ๋๋ง๋ค ์ฑ๋ฅ ์ ํ ์ด๋
3. Double Checked Locking
public class Singleton {
private static volatile Singleton instance;
private Singleton(){}
public static Singleton getInstance(){
if(instance == null){
synchronized (Singleton.class) {
if(instance == null){
instance = new Singleton();
}
}
}
return instance;
}
}
- volatile : ์๋ฐ์ ๋ณ์๋ฅผ ๋ฉ์ธ๋ฉ๋ชจ๋ฆฌ์ ์ ์ฅํ๊ฒ ๋ค!
- CPU์ ์บ์๋ฅผ ๊ฑฐ์น์ง ์๊ณ ๋ฉ์ธ ๋ฉ๋ชจ๋ฆฌ์ ์ง์ Read/Write ์ํ
- volatile์ ์ฌ์ฉํ์ง ์๋ ๋ฉํฐ ์ค๋ ๋ ํ๊ฒฝ์์๋ CPU ์บ์์ ๊ฐ์ ์ ์ฅํ๊ฒ ๋จ.
- ๊ฐ๊ฐ์ ์ค๋ ๋๊ฐ ๊ฐ๋ ๋ณ์์ ๊ฐ์ด ๋ถ์ผ์น
- ๊ฐ๊ฐ์ ์ค๋ ๋๊ฐ ๊ฐ๋ ๋ณ์์ ๊ฐ์ด ๋ถ์ผ์น
- volatile ๋ณ์์ ๋ํ ์ ๊ทผ์ synchronized๋ฅผ ์ฌ์ฉํ๋ ๊ฒ๊ณผ ๋์ผํ๊ฒ ๋์
- ๋ฉํฐ ์ค๋ ๋ ํ๊ฒฝ์์ ํ๋์ ์ฐ๋ ๋๋ R/W ํ๊ณ , ๋๋จธ์ง๋ Read Onlyํ ๋ ์ ์
๋ณ์์ ๋ถ์ผ์น ์ํฉ์ ์กฐ๊ธ์ด๋ผ๋ ์ค์ด๊ธฐ ์ํด volatile ํค์๋์ ๊ฐ์ด ์
JDK 1.5๋ถํฐ ์ฌ์ฉ๊ฐ๋ฅ, JVM ๋์๋ฐฉ์ ์ดํด ํ์ํ๋ฏ๋ก ์ฌ์ฉํ์ง ์๋ ๊ฒ์ด ๊ถ์ฅ๋จ
4. Bill Pugh Singleton Implementaion (๋นํจ?)
- inner static helper class ์ฌ์ฉ
public class Singleton {
private Singleton(){}
private static class SingletonHelper{
private static final Singleton INSTANCE = new Singleton();
}
public static Singleton getInstance(){
return SingletonHelper.INSTANCE;
}
}
- private inner static class๋ฅผ ์ฌ์ฉํ์ฌ ์ฑ๊ธํค ์ธ์คํด์ค๋ฅผ ์์ฑํ๋ค.
- Singleton ํด๋์ค๊ฐ ๋ก๋๋ ๋๋ ๋ก๋๋์ง ์๋ค๊ฐ, getInstance()๊ฐ ํธ์ถ๋ ๋, ๋ฉ๋ชจ๋ฆฌ์ ๋ก๋๋๊ณ , ์ธ์คํด์ค๋ฅผ ์์ฑํ๊ฒ ๋๋ค.
- synchronized๋ฅผ ์ฌ์นํ์ง์๊ธฐ ๋๋ฌธ์ ์ฑ๋ฅ์ ํ๊ฐ ๋ฐ์ํ์ง ์๋๋ค.
๊ถ์ฅ๋๋ ๋ฐฉ๋ฒ, ๊ฐ์ฅ ๋๋ฆฌ ์ฐ์ด๋ ๋ฐฉ๋ฒ
์๋ฐ ๋ฆฌํ๋ ์ ์ผ๋ก ํ๊ดด๋๋ค๋๋ฐ ์ด๋ฒ์๋ ๊ทธ๋ฅ ๋์ด๊ฐ๋๋ก ํ์
5. Enum Singleton
public enum Singleton {
INSTANCE;
}
- enum์ด ์์์ธ ์ ์ ํ์ฉํ ๊ตฌํ๋ฐฉ์
- ๋ก๋ฉํ๋ ์๊ฐ ๋ง๋ค์ด์ง๋ค๋ ๋จ์ , ์์ ๋ฐ์ ์ฌ์ฉ ๋ถ๊ฐ
- ์์ ๋ฐ์ ์ฌ์ฉํ ๊ฒฝ์ฐ ํด๋์ค ํ๋ ์ฌ์ฉํ๋ฉด ๋์ง๋ง ์ฌ์ ํ ํ์ฅ์ฑ์ ๋จ์ด์ง
๋จ์
- SOLID ์์น ์๋ฐฐ
- ๋จ์ผ ์ฑ ์ ์์น ์๋ฐ (SRP)์ฑ๊ธํค ํด๋์ค๊ฐ ์์ฑ, ๊ด๋ฆฌ, ์ ์ญ ์ํ ์ ์ง ๋ฑ์ ์ฌ๋ฌ๊ฐ์ง ์ฑ ์์ ๋ด๋นํ๊ฒ ๋๋ฉด ํด๋์ค์ ํฌ๊ธฐ๊ฐ ์ปค์ง๊ณ ๋น์ฐํ ์ ์ง๋ณด์๊ฐ ์ด๋ ค์ ์ง๋ค.
- ํ๋์ ์ธ์คํด์ค๋ฅผ ๋ณด์ฆํ๊ธฐ ๋๋ฌธ์, ์ฌ๋ฌ๊ฐ์ง ์ผ์ ์ฒ๋ฆฌํ ์๋ฐ์ ์๋ ๊ตฌ์กฐ๋ค.
- ๊ฐ๋ฐฉ-ํ์ ์์น ์๋ฐ(OCP)
- ์ฑ๊ธํค ํด๋์ค๊ฐ ์์ ์ด ์ผ์ด๋๋ฉด ์ฑ๊ธํค ํด๋์ค๋ฅผ ์ฌ์ฉํ๋ ํด๋์ค ์ชฝ์์์ ์์ ๋ ๋ถ๊ฐํผํ๋ค.
- ์์กด ์ญ์ ์์น ์๋ฐ (DIP)์ฑ๊ธํค ํด๋์ค์ ๋ค๋ฅธ ํด๋์ค ๊ฐ์ ๊ฒฐํฉ๋๊ฐ ๋์์ง ์ ๋ฐ์ ์๊ธฐ ๋๋ฌธ์, ๊ฐ์ฒด ๊ฐ์ ์์กด์ฑ์ ์ธ๋ถ์์ ์ฃผ์ ํ์ฌ ๊ฐ์ฒด ๊ฐ์ ๊ฒฐํฉ๋๋ฅผ ๋ฎ์ถ ์ ์๋ค.
- ๊ฐ์ฒด๋ ๊ตฌ์ฒด์ ์ธ ๊ฐ์ฒด๊ฐ ์๋ ์ถ์ํ์ ์์กดํด์ผ ํ๋ค๋ ๋ฒ์น ์๋ฐ!
- TDD ๋จ์ ํ ์คํธ ์ด๋ ค์๋ง์ฝ ์ฑ๊ธํค ์ธ์คํด์ค๊ฐ ์ํ๋ฅผ ๊ฐ์ง๋ ๊ฒฝ์ฐ
- ์ธ์คํด์ค ๋ด๋ถ์ ๋ฐ์ดํฐ ๊ฐ์ด ๋ณ๊ฒฝ๋๋ค๋ ๋ง์ธ๋ฐ, ํ ์คํธ ์ผ์ด์ค๋ง๋ค ์ํ๊ฐ ๋ณ๊ฒฝ๋๊ธฐ ๋๋ฌธ์ ๋ค์์ ์ด๋ค์ง ํ ์คํธ์ ์ํฅ์ ๋ผ์น ์๋ ์๊ณ , ํ ์คํธ ๋ฒ์ ์ค์ ๋ ์ ๋งคํด์ง๋ค.
- ์ฑ๊ธํค ์ธ์คํด์ค๋ ์ด๋์๋ ์ง ์ ๊ทผ ๊ฐ๋ฅ
- Thread Safe ๋ฌธ์
์คํ๋ง์์์ ์ฑ๊ธํค
IoC ์ปจํ ์ด๋ ( ์คํ๋ง ์ปจํ ์ด๋ )
์ปจํ ์ด๋? - ์ปจํ ์ด๋๋ ๋ณดํต ๊ฐ์ฒด์ ์๋ช ์ฃผ๊ธฐ๋ฅผ ๊ด๋ฆฌ, ์์ฑ๋ ์ธ์คํด์ค๋ค์๊ฒ ์ถ๊ฐ์ ์ธ ๊ธฐ๋ฅ์ ์ ๊ณตํ๋๋ก ํ๋ ๊ฒ
์คํ๋ง ํ๋ ์์ํฌ๋ ๊ฐ์ฒด๋ฅผ ์์ฑํ๊ณ ๊ด๋ฆฌํ๊ณ ์ฑ ์์ง๊ณ ์์กด์ฑ์ ๊ด๋ฆฌํด์ฃผ๋ ์ปจํ ์ด๋๊ฐ ์๋๋ฐ,
๊ทธ๊ฒ์ด ๋ฐ๋ก IoC ์ปจํ ์ด๋(=์คํ๋ง ์ปจํ ์ด๋) ์ด๋ค.

๊ฐ์ฒด ๊ฐ์ ์์กด์ฑ์ ๋ฎ์ถ์ด(๋์จํ ๊ฒฐํฉ) ๊ฒฐํฉ๋๋ ๋ฎ์ถ๊ณ , ๋์ ์บก์ํ๋ฅผ ์ํด ์คํ๋ง ์ปจํ ์ด๋๊ฐ ์ฌ์ฉ๋๋ค.
์คํ๋ง ์ปจํ ์ด๋์ ์ข ๋ฅ

์คํ๋ง ์ปจํ
์ด๋๊ฐ ๊ด๋ฆฌํ๋ ๊ฐ์ฒด๋ฅผ ๋น(Bean)์ด๋ผ๊ณ ํ๋ค.
BeanFactory
๋น ํฉํ ๋ฆฌ(BeanFactory)๋ ์คํ๋ง ์ปจํ ์ด๋์ ์ต์์ ์ธํฐํ์ด์ค์ด๋ค.
BeanFactory๋ ๋น์ ๋ฑ๋ก, ์์ฑ, ์กฐํ ๋ฑ์ ๋น์ ๊ด๋ฆฌํ๋ ์ญํ ์ ํ๋ฉฐ, getBean() ๋ฉ์๋๋ฅผ ํตํด ๋น์ ์ธ์คํด์คํ ํ ์ ์๋ค.
@Bean ์ด๋ ธํ ์ด์ ์ด ๋ถ์ ๋ฉ์๋์ ์ด๋ฆ์ ์คํ๋ง ๋น์ ์ด๋ฆ์ผ๋ก ์ฌ์ฉํ์ฌ ๋น ๋ฑ๋ก์ ํ๋ค.
- BeanFactory์ ์ฌ๋ฌ๊ฐ์ง ์ปจํ ์ด๋ ๊ธฐ๋ฅ์ ์ถ๊ฐํ ์ดํ๋ฆฌ์ผ์ด์ ์ปจํ ์คํธ(ApplicationContext) ๊ฐ ์๋ค.
์คํ๋ง ์ปจํ ์ด๋์ ์์ฑ๊ณผ ๋ฑ๋ก

๊ธฐ๋ณธ์ ์ผ๋ก ์คํ๋ง ์ปจํ ์ด๋๋ Configuration Metadata๋ฅผ ์ฌ์ฉํ๋ค.
๋ํ, ์คํ๋ง ์ปจํ ์ด๋๋ ํ๋ผ๋ฏธํฐ๋ก ๋์ด์จ ์ค์ ํด๋์ค ์ ๋ณด๋ฅผ ์ฌ์ฉํ์ฌ ์คํ๋ง ๋น์ ๋ฑ๋กํ๋ค.
์คํ๋ง ์ปจํ ์ด๋๋ฅผ ๋ง๋๋ ๋ค์ํ ๋ฐฉ๋ฒ์ ApplicationContext ์ธํฐํ์ด์ค์ ๊ตฌํ์ฒด์ด๋ค.
AppConfig.class ๋ฑ์ ๊ตฌ์ฑ ์ ๋ณด๋ฅผ ์ง์ ํ์ฌ ์คํ๋ง ์ปจํ ์ด๋๋ฅผ ์์ฑํ ์ ์๋ค.
์ ํ๋ฆฌ์ผ์ด์ ํด๋์ค๋ ๊ตฌ์ฑ ๋ฉํ๋ฐ์ดํฐ์ ๊ฒฐํฉ๋์ด ApplicationContext๋ฅผ ์์ฑํ๊ณ ์ด๊ธฐํ๋๋ค.
์ดํ ์คํ ๊ฐ๋ฅํ ์์คํ ๋๋ ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ฐ๊ฒ ๋๋ค.
๋ง์ฝ, ์คํ๋ง ๋น ์กฐํ์์ ์์๊ด๊ณ๊ฐ ์์ ์์๋ ๋ถ๋ชจ ํ์ ์ผ๋ก ์กฐํํ๋ฉด ์์ ํ์ ๋ ํจ๊ป ์กฐํ๋๋ค. ์ฆ, Object ํ์ ์ผ๋ก ์กฐํํ๊ฒ ๋๋ฉด ๋ชจ๋ ์คํ๋ง ๋น์ ์กฐํํ ์ ์๋ค.
@Configuration
public class AppConfig {
@Bean
public MemberService memberService() {
return new MemberServiceImpl(memberRepository());
}
@Bean
public MemberRepository memberRepository() {
return new MemoryMemberRepository();
}
}
@Configuration
์คํ๋ง ์ปจํ ์ด๋๊ฐ ํด๋น ์ด๋ ธํ ์ด์ ์ด ๋ถ์ ํด๋์ค๋ฅผ ์ค์ ์ ๋ณด๋ก ์ฌ์ฉํ๋ค.
ํด๋์ค ๋ด๋ถ์ @Bean ์ด๋ ธํ ์ด์ ์ด ์ ํ ๋ฉ์๋๋ฅผ ๋ชจ๋ ํธ์ถํ์ฌ ์ป์ ๊ฐ์ฒด๋ฅผ ์คํ๋ง ์ปจํ ์ด๋์ ๋ฑ๋กํ๊ฒ ๋๋ค.
์คํ๋ง ์ปจํ ์ด๋์ ๋ฑ๋ก๋ ๊ฐ์ฒด๋ฅผ ์คํ๋ง ๋น(Bean)์ด๋ผ ํ๋ค.
public class MemberApp {
public static void main(String[] args) {
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);
MemberService memberService = applicationContext.getBean("memberService", MemberService.class)
}
}
@ApplicationContext(AppConfig.class)
ApplicationContext๋ฅผ ์คํ๋ง ์ปจํ ์ด๋๋ผ๊ณ ํ๋ฉฐ, ์ธํฐํ์ด์ค๋ก ๊ตฌํ๋์ด ์๋ค.
applicationContext.getBean(โ์ด๋ฆโ, ํ์ );
์คํ๋ง ๋น์ getBean() ๋ฉ์๋๋ฅผ ์ด์ฉํ์ฌ ์ป์ ์ ์๋ค.
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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="..." class="...">
<!-- collaborators and configuration for this bean go here -->
</bean>
<bean id="..." class="...">
<!-- collaborators and configuration for this bean go here -->
</bean>
<!-- more bean definitions go here -->
</beans>
ํ๊ทธ๋ฅผ ํตํด ํ์ํ ๊ฐ๋ค์ ์ค์ ํ ์ ์๋ค.
ํ๊ทธ๋ ๋น ์ ์๋ฅผ ์๋ณํ๋ ๋ฐ ์ฌ์ฉํ๋ ๋ฌธ์์ด์ด๋ค.
<bean class=โโฆโ ํ๊ทธ๋ Bean์ ์ ํ์ ์ ์ํ๊ณ ํด๋์ค ์ด๋ฆ์ ์ฌ์ฉํ๋ค.
ApplicationContext context = new ClassPathXmlApplicationContext("services.xml", "daos.xml");
Singleton
Singleton ํจํด?

โ ์ธ์คํด์ค๊ฐ ํ๋๋ง ์กด์ฌํ๋ ๊ฒ์ ๋ณด์ฆํ๋ ํจํด
์ฅ์
- ์ธ์คํด์ค๊ฐ ํ๋๋ง ์กด์ฌํ๊ธฐ ๋๋ฌธ์ ๋ฉ๋ชจ๋ฆฌ ๋ญ๋น๋ฅผ ๋ฐฉ์งํ ์ ์์
- ์ ์ญ ์ธ์คํด์ค์ด๊ธฐ ๋๋ฌธ์ ๋ค๋ฅธ ํด๋์ค์ ์ธ์คํด์ค๋ค์ด ๋ฐ์ดํฐ๋ฅผ ๊ณต์ ํ๊ธฐ ์ฌ์, ๋ฐ์ดํฐ ์ผ๊ด์ฑ ๋ณด์ฅ
- ์ดํ๋ฆฌ์ผ์ด์ ์ ์ธํ ๊ฐ( ๋ฐฐ๊ฒฝ์ ), DBCP, ๋ก๊ทธ ๊ธฐ๋ก ๊ฐ์ฒด
- DBCP! ํ ๋ง์์!
- db์ ์๋ฒ๊ฐ ์ฐ๊ฒฐํ๋ connection ์์ ์ ๋น์ฉ์ด ํผ โ ๋ค์์ ์ฌ์ฉ์ ๋์๋ค๋ฐ์ ์ผ๋ก ์ฌ์ฉ์ ์๋ฒ ๋ค์ด์ฌ๋ฌ ์ปค๋ฅ์ ๋ค์ ๋ฏธ๋ฆฌ ๋ด์๋๊ณ ํด๋ผ์ด์ธํธ๊ฐ ์์ฒญํ ๋๋ง๋ค ํ๋์ฉ ๊บผ๋ด์ ๋น๋ ค์ค
- ์ปค๋ฅ์ ์ด ๋ค ๋จ์ด์ง๋ฉด ๋ค๋ฅธ ํด๋ผ์ด์ธํธ๊ฐ ๋ฐํํ ๋๊น์ง ๋๊ธฐ์ํ๋ก ์ ํ
๋ค์ด์ด๊ทธ๋จ

๊ธฐ๋ณธ ๊ณจ๊ฒฉ : Eager Initialization (์ด๋ฅธ ์ด๊ธฐํ)
public class Singleton{
private static Singleton singleton = new Singleton();
private Singleton() {
System.out.println("์ธ์คํด์ค๋ฅผ ์์ฑํ์ต๋๋ค.");
}
public static Singleton getInstance() {
return singleton;
}
}
- ๊ฐ์ฅ ๊ฐ๋จํ ํํ์ ๊ตฌํ ๋ฐฉ๋ฒ
- ํด๋์ค ์ธ์คํด์ค ํด๋์ค ๋ก๋ฉ ๋จ๊ณ์์ ์์ฑ
โ ํด๋น ์ธ์คํด์ค๋ฅผ ์ฌ์ฉํ์ง ์๋๋ผ๋ ์ธ์คํด์ค ์์ฑ โ ๋ฉ๋ชจ๋ฆฌ ๋ญ๋น ์ด๋
โ ์ฑ๊ธํค ํด๋์ค๊ฐ ๋งค์ฐ ์ ์ ๋ฆฌ์์ค๋ฅผ ๋ค๋ฃฐ ๋ ์ ์
1. Lazy Initialization : ๋์ค์ ์ด๊ธฐํ
public class Singleton{
private static Singleton instance;
private Singleton() {}
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return singleton;
}
}
๋ฉํฐ ์ค๋ ๋ฉ ํ๊ฒฝ์์ ๊ฐ์ฒด๊ฐ ํ๋์์ ๋ณด์ฆํ์ง ๋ชปํ๋ค.
like ์๋ฆฌ-์์ ๋ ์คํ ๋
2. Thread Safe Singleton
public class Singleton {
private static Singleton instance;
private Singleton(){}
public static synchronized Singleton getInstance(){
if(instance == null){
instance = new Singleton();
}
return instance;
}
}
getInstance()ํ ๋๋ง๋ค ์ฑ๋ฅ ์ ํ ์ด๋
3. Double Checked Locking
public class Singleton {
private static volatile Singleton instance;
private Singleton(){}
public static Singleton getInstance(){
if(instance == null){
synchronized (Singleton.class) {
if(instance == null){
instance = new Singleton();
}
}
}
return instance;
}
}
- volatile : ์๋ฐ์ ๋ณ์๋ฅผ ๋ฉ์ธ๋ฉ๋ชจ๋ฆฌ์ ์ ์ฅํ๊ฒ ๋ค!
- CPU์ ์บ์๋ฅผ ๊ฑฐ์น์ง ์๊ณ ๋ฉ์ธ ๋ฉ๋ชจ๋ฆฌ์ ์ง์ Read/Write ์ํ
- volatile์ ์ฌ์ฉํ์ง ์๋ ๋ฉํฐ ์ค๋ ๋ ํ๊ฒฝ์์๋ CPU ์บ์์ ๊ฐ์ ์ ์ฅํ๊ฒ ๋จ.
- ๊ฐ๊ฐ์ ์ค๋ ๋๊ฐ ๊ฐ๋ ๋ณ์์ ๊ฐ์ด ๋ถ์ผ์น
- ๊ฐ๊ฐ์ ์ค๋ ๋๊ฐ ๊ฐ๋ ๋ณ์์ ๊ฐ์ด ๋ถ์ผ์น
- volatile ๋ณ์์ ๋ํ ์ ๊ทผ์ synchronized๋ฅผ ์ฌ์ฉํ๋ ๊ฒ๊ณผ ๋์ผํ๊ฒ ๋์
- ๋ฉํฐ ์ค๋ ๋ ํ๊ฒฝ์์ ํ๋์ ์ฐ๋ ๋๋ R/W ํ๊ณ , ๋๋จธ์ง๋ Read Onlyํ ๋ ์ ์
๋ณ์์ ๋ถ์ผ์น ์ํฉ์ ์กฐ๊ธ์ด๋ผ๋ ์ค์ด๊ธฐ ์ํด volatile ํค์๋์ ๊ฐ์ด ์
JDK 1.5๋ถํฐ ์ฌ์ฉ๊ฐ๋ฅ, JVM ๋์๋ฐฉ์ ์ดํด ํ์ํ๋ฏ๋ก ์ฌ์ฉํ์ง ์๋ ๊ฒ์ด ๊ถ์ฅ๋จ
4. Bill Pugh Singleton Implementaion (๋นํจ?)
- inner static helper class ์ฌ์ฉ
public class Singleton {
private Singleton(){}
private static class SingletonHelper{
private static final Singleton INSTANCE = new Singleton();
}
public static Singleton getInstance(){
return SingletonHelper.INSTANCE;
}
}
- private inner static class๋ฅผ ์ฌ์ฉํ์ฌ ์ฑ๊ธํค ์ธ์คํด์ค๋ฅผ ์์ฑํ๋ค.
- Singleton ํด๋์ค๊ฐ ๋ก๋๋ ๋๋ ๋ก๋๋์ง ์๋ค๊ฐ, getInstance()๊ฐ ํธ์ถ๋ ๋, ๋ฉ๋ชจ๋ฆฌ์ ๋ก๋๋๊ณ , ์ธ์คํด์ค๋ฅผ ์์ฑํ๊ฒ ๋๋ค.
- synchronized๋ฅผ ์ฌ์นํ์ง์๊ธฐ ๋๋ฌธ์ ์ฑ๋ฅ์ ํ๊ฐ ๋ฐ์ํ์ง ์๋๋ค.
๊ถ์ฅ๋๋ ๋ฐฉ๋ฒ, ๊ฐ์ฅ ๋๋ฆฌ ์ฐ์ด๋ ๋ฐฉ๋ฒ
์๋ฐ ๋ฆฌํ๋ ์ ์ผ๋ก ํ๊ดด๋๋ค๋๋ฐ ์ด๋ฒ์๋ ๊ทธ๋ฅ ๋์ด๊ฐ๋๋ก ํ์
5. Enum Singleton
public enum Singleton {
INSTANCE;
}
- enum์ด ์์์ธ ์ ์ ํ์ฉํ ๊ตฌํ๋ฐฉ์
- ๋ก๋ฉํ๋ ์๊ฐ ๋ง๋ค์ด์ง๋ค๋ ๋จ์ , ์์ ๋ฐ์ ์ฌ์ฉ ๋ถ๊ฐ
- ์์ ๋ฐ์ ์ฌ์ฉํ ๊ฒฝ์ฐ ํด๋์ค ํ๋ ์ฌ์ฉํ๋ฉด ๋์ง๋ง ์ฌ์ ํ ํ์ฅ์ฑ์ ๋จ์ด์ง
๋จ์
- SOLID ์์น ์๋ฐฐ
- ๋จ์ผ ์ฑ ์ ์์น ์๋ฐ (SRP)์ฑ๊ธํค ํด๋์ค๊ฐ ์์ฑ, ๊ด๋ฆฌ, ์ ์ญ ์ํ ์ ์ง ๋ฑ์ ์ฌ๋ฌ๊ฐ์ง ์ฑ ์์ ๋ด๋นํ๊ฒ ๋๋ฉด ํด๋์ค์ ํฌ๊ธฐ๊ฐ ์ปค์ง๊ณ ๋น์ฐํ ์ ์ง๋ณด์๊ฐ ์ด๋ ค์ ์ง๋ค.
- ํ๋์ ์ธ์คํด์ค๋ฅผ ๋ณด์ฆํ๊ธฐ ๋๋ฌธ์, ์ฌ๋ฌ๊ฐ์ง ์ผ์ ์ฒ๋ฆฌํ ์๋ฐ์ ์๋ ๊ตฌ์กฐ๋ค.
- ๊ฐ๋ฐฉ-ํ์ ์์น ์๋ฐ(OCP)
- ์ฑ๊ธํค ํด๋์ค๊ฐ ์์ ์ด ์ผ์ด๋๋ฉด ์ฑ๊ธํค ํด๋์ค๋ฅผ ์ฌ์ฉํ๋ ํด๋์ค ์ชฝ์์์ ์์ ๋ ๋ถ๊ฐํผํ๋ค.
- ์์กด ์ญ์ ์์น ์๋ฐ (DIP)์ฑ๊ธํค ํด๋์ค์ ๋ค๋ฅธ ํด๋์ค ๊ฐ์ ๊ฒฐํฉ๋๊ฐ ๋์์ง ์ ๋ฐ์ ์๊ธฐ ๋๋ฌธ์, ๊ฐ์ฒด ๊ฐ์ ์์กด์ฑ์ ์ธ๋ถ์์ ์ฃผ์ ํ์ฌ ๊ฐ์ฒด ๊ฐ์ ๊ฒฐํฉ๋๋ฅผ ๋ฎ์ถ ์ ์๋ค.
- ๊ฐ์ฒด๋ ๊ตฌ์ฒด์ ์ธ ๊ฐ์ฒด๊ฐ ์๋ ์ถ์ํ์ ์์กดํด์ผ ํ๋ค๋ ๋ฒ์น ์๋ฐ!
- TDD ๋จ์ ํ ์คํธ ์ด๋ ค์๋ง์ฝ ์ฑ๊ธํค ์ธ์คํด์ค๊ฐ ์ํ๋ฅผ ๊ฐ์ง๋ ๊ฒฝ์ฐ
- ์ธ์คํด์ค ๋ด๋ถ์ ๋ฐ์ดํฐ ๊ฐ์ด ๋ณ๊ฒฝ๋๋ค๋ ๋ง์ธ๋ฐ, ํ ์คํธ ์ผ์ด์ค๋ง๋ค ์ํ๊ฐ ๋ณ๊ฒฝ๋๊ธฐ ๋๋ฌธ์ ๋ค์์ ์ด๋ค์ง ํ ์คํธ์ ์ํฅ์ ๋ผ์น ์๋ ์๊ณ , ํ ์คํธ ๋ฒ์ ์ค์ ๋ ์ ๋งคํด์ง๋ค.
- ์ฑ๊ธํค ์ธ์คํด์ค๋ ์ด๋์๋ ์ง ์ ๊ทผ ๊ฐ๋ฅ
- Thread Safe ๋ฌธ์
์คํ๋ง์์์ ์ฑ๊ธํค
IoC ์ปจํ ์ด๋ ( ์คํ๋ง ์ปจํ ์ด๋ )
์ปจํ ์ด๋? - ์ปจํ ์ด๋๋ ๋ณดํต ๊ฐ์ฒด์ ์๋ช ์ฃผ๊ธฐ๋ฅผ ๊ด๋ฆฌ, ์์ฑ๋ ์ธ์คํด์ค๋ค์๊ฒ ์ถ๊ฐ์ ์ธ ๊ธฐ๋ฅ์ ์ ๊ณตํ๋๋ก ํ๋ ๊ฒ
์คํ๋ง ํ๋ ์์ํฌ๋ ๊ฐ์ฒด๋ฅผ ์์ฑํ๊ณ ๊ด๋ฆฌํ๊ณ ์ฑ ์์ง๊ณ ์์กด์ฑ์ ๊ด๋ฆฌํด์ฃผ๋ ์ปจํ ์ด๋๊ฐ ์๋๋ฐ,
๊ทธ๊ฒ์ด ๋ฐ๋ก IoC ์ปจํ ์ด๋(=์คํ๋ง ์ปจํ ์ด๋) ์ด๋ค.

๊ฐ์ฒด ๊ฐ์ ์์กด์ฑ์ ๋ฎ์ถ์ด(๋์จํ ๊ฒฐํฉ) ๊ฒฐํฉ๋๋ ๋ฎ์ถ๊ณ , ๋์ ์บก์ํ๋ฅผ ์ํด ์คํ๋ง ์ปจํ ์ด๋๊ฐ ์ฌ์ฉ๋๋ค.
์คํ๋ง ์ปจํ ์ด๋์ ์ข ๋ฅ

์คํ๋ง ์ปจํ
์ด๋๊ฐ ๊ด๋ฆฌํ๋ ๊ฐ์ฒด๋ฅผ ๋น(Bean)์ด๋ผ๊ณ ํ๋ค.
BeanFactory
๋น ํฉํ ๋ฆฌ(BeanFactory)๋ ์คํ๋ง ์ปจํ ์ด๋์ ์ต์์ ์ธํฐํ์ด์ค์ด๋ค.
BeanFactory๋ ๋น์ ๋ฑ๋ก, ์์ฑ, ์กฐํ ๋ฑ์ ๋น์ ๊ด๋ฆฌํ๋ ์ญํ ์ ํ๋ฉฐ, getBean() ๋ฉ์๋๋ฅผ ํตํด ๋น์ ์ธ์คํด์คํ ํ ์ ์๋ค.
@Bean ์ด๋ ธํ ์ด์ ์ด ๋ถ์ ๋ฉ์๋์ ์ด๋ฆ์ ์คํ๋ง ๋น์ ์ด๋ฆ์ผ๋ก ์ฌ์ฉํ์ฌ ๋น ๋ฑ๋ก์ ํ๋ค.
- BeanFactory์ ์ฌ๋ฌ๊ฐ์ง ์ปจํ ์ด๋ ๊ธฐ๋ฅ์ ์ถ๊ฐํ ์ดํ๋ฆฌ์ผ์ด์ ์ปจํ ์คํธ(ApplicationContext) ๊ฐ ์๋ค.
์คํ๋ง ์ปจํ ์ด๋์ ์์ฑ๊ณผ ๋ฑ๋ก

๊ธฐ๋ณธ์ ์ผ๋ก ์คํ๋ง ์ปจํ ์ด๋๋ Configuration Metadata๋ฅผ ์ฌ์ฉํ๋ค.
๋ํ, ์คํ๋ง ์ปจํ ์ด๋๋ ํ๋ผ๋ฏธํฐ๋ก ๋์ด์จ ์ค์ ํด๋์ค ์ ๋ณด๋ฅผ ์ฌ์ฉํ์ฌ ์คํ๋ง ๋น์ ๋ฑ๋กํ๋ค.
์คํ๋ง ์ปจํ ์ด๋๋ฅผ ๋ง๋๋ ๋ค์ํ ๋ฐฉ๋ฒ์ ApplicationContext ์ธํฐํ์ด์ค์ ๊ตฌํ์ฒด์ด๋ค.
AppConfig.class ๋ฑ์ ๊ตฌ์ฑ ์ ๋ณด๋ฅผ ์ง์ ํ์ฌ ์คํ๋ง ์ปจํ ์ด๋๋ฅผ ์์ฑํ ์ ์๋ค.
์ ํ๋ฆฌ์ผ์ด์ ํด๋์ค๋ ๊ตฌ์ฑ ๋ฉํ๋ฐ์ดํฐ์ ๊ฒฐํฉ๋์ด ApplicationContext๋ฅผ ์์ฑํ๊ณ ์ด๊ธฐํ๋๋ค.
์ดํ ์คํ ๊ฐ๋ฅํ ์์คํ ๋๋ ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ฐ๊ฒ ๋๋ค.
๋ง์ฝ, ์คํ๋ง ๋น ์กฐํ์์ ์์๊ด๊ณ๊ฐ ์์ ์์๋ ๋ถ๋ชจ ํ์ ์ผ๋ก ์กฐํํ๋ฉด ์์ ํ์ ๋ ํจ๊ป ์กฐํ๋๋ค. ์ฆ, Object ํ์ ์ผ๋ก ์กฐํํ๊ฒ ๋๋ฉด ๋ชจ๋ ์คํ๋ง ๋น์ ์กฐํํ ์ ์๋ค.
@Configuration
public class AppConfig {
@Bean
public MemberService memberService() {
return new MemberServiceImpl(memberRepository());
}
@Bean
public MemberRepository memberRepository() {
return new MemoryMemberRepository();
}
}
@Configuration
์คํ๋ง ์ปจํ ์ด๋๊ฐ ํด๋น ์ด๋ ธํ ์ด์ ์ด ๋ถ์ ํด๋์ค๋ฅผ ์ค์ ์ ๋ณด๋ก ์ฌ์ฉํ๋ค.
ํด๋์ค ๋ด๋ถ์ @Bean ์ด๋ ธํ ์ด์ ์ด ์ ํ ๋ฉ์๋๋ฅผ ๋ชจ๋ ํธ์ถํ์ฌ ์ป์ ๊ฐ์ฒด๋ฅผ ์คํ๋ง ์ปจํ ์ด๋์ ๋ฑ๋กํ๊ฒ ๋๋ค.
์คํ๋ง ์ปจํ ์ด๋์ ๋ฑ๋ก๋ ๊ฐ์ฒด๋ฅผ ์คํ๋ง ๋น(Bean)์ด๋ผ ํ๋ค.
public class MemberApp {
public static void main(String[] args) {
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);
MemberService memberService = applicationContext.getBean("memberService", MemberService.class)
}
}
@ApplicationContext(AppConfig.class)
ApplicationContext๋ฅผ ์คํ๋ง ์ปจํ ์ด๋๋ผ๊ณ ํ๋ฉฐ, ์ธํฐํ์ด์ค๋ก ๊ตฌํ๋์ด ์๋ค.
applicationContext.getBean(โ์ด๋ฆโ, ํ์ );
์คํ๋ง ๋น์ getBean() ๋ฉ์๋๋ฅผ ์ด์ฉํ์ฌ ์ป์ ์ ์๋ค.
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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="..." class="...">
<!-- collaborators and configuration for this bean go here -->
</bean>
<bean id="..." class="...">
<!-- collaborators and configuration for this bean go here -->
</bean>
<!-- more bean definitions go here -->
</beans>
ํ๊ทธ๋ฅผ ํตํด ํ์ํ ๊ฐ๋ค์ ์ค์ ํ ์ ์๋ค.
ํ๊ทธ๋ ๋น ์ ์๋ฅผ ์๋ณํ๋ ๋ฐ ์ฌ์ฉํ๋ ๋ฌธ์์ด์ด๋ค.
<bean class=โโฆโ ํ๊ทธ๋ Bean์ ์ ํ์ ์ ์ํ๊ณ ํด๋์ค ์ด๋ฆ์ ์ฌ์ฉํ๋ค.
ApplicationContext context = new ClassPathXmlApplicationContext("services.xml", "daos.xml");