spring core : singleton container
This commit is contained in:
@@ -17,16 +17,19 @@ public class AppConfig {
|
||||
|
||||
@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(), discountPolicy());
|
||||
}
|
||||
|
||||
|
||||
@@ -17,4 +17,9 @@ public class MemberServiceImpl implements MemberService {
|
||||
public Member findMember(Long memberId) {
|
||||
return memberRepository.findById(memberId);
|
||||
}
|
||||
|
||||
// 테스트 용
|
||||
public MemberRepository getMemberRepository() {
|
||||
return memberRepository;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,4 +20,9 @@ public class OrderServiceImpl implements OrderService {
|
||||
int discountPrice = discountPolicy.discount(member, itemPrice);
|
||||
return new Order(memberId, itemName, itemPrice, discountPrice);
|
||||
}
|
||||
|
||||
// 테스트 용
|
||||
public MemberRepository getMemberRepository() {
|
||||
return memberRepository;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
package com.example.basic.singleton;
|
||||
|
||||
import com.example.basic.AppConfig;
|
||||
import com.example.basic.member.MemberRepository;
|
||||
import com.example.basic.member.MemberServiceImpl;
|
||||
import com.example.basic.order.OrderServiceImpl;
|
||||
import org.assertj.core.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
|
||||
class ConfigurationSingletonTest {
|
||||
|
||||
@Test
|
||||
void configurationTest() {
|
||||
ApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class);
|
||||
|
||||
MemberServiceImpl memberService = ac.getBean("memberService", MemberServiceImpl.class);
|
||||
OrderServiceImpl orderService = ac.getBean("orderService", OrderServiceImpl.class);
|
||||
MemberRepository memberRepository = ac.getBean("memberRepository", MemberRepository.class);
|
||||
|
||||
MemberRepository memberRepository1 = memberService.getMemberRepository();
|
||||
MemberRepository memberRepository2 = orderService.getMemberRepository();
|
||||
System.out.println("memberRepository1 = " + memberRepository1);
|
||||
System.out.println("memberRepository2 = " + memberRepository2);
|
||||
System.out.println("memberRepository = " + memberRepository);
|
||||
|
||||
Assertions.assertThat(memberService.getMemberRepository()).isSameAs(memberRepository);
|
||||
Assertions.assertThat(orderService.getMemberRepository()).isSameAs(memberRepository);
|
||||
}
|
||||
|
||||
@Test
|
||||
void configurationDeep() {
|
||||
ApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class);
|
||||
AppConfig bean = ac.getBean(AppConfig.class);
|
||||
|
||||
System.out.println("bean = " + bean.getClass());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.example.basic.singleton;
|
||||
|
||||
public class SingletonService {
|
||||
|
||||
private static final SingletonService instance = new SingletonService();
|
||||
|
||||
private SingletonService() {}
|
||||
|
||||
public static SingletonService getInstance() {
|
||||
return instance;
|
||||
}
|
||||
|
||||
public void logic() {
|
||||
System.out.println("싱클톤 객체 호출");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
package com.example.basic.singleton;
|
||||
|
||||
import com.example.basic.AppConfig;
|
||||
import com.example.basic.member.MemberService;
|
||||
import org.assertj.core.api.Assertions;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
|
||||
import static org.assertj.core.api.Assertions.*;
|
||||
|
||||
public class SingletonTest {
|
||||
|
||||
@Test
|
||||
@DisplayName("스프링 없는 DI 컨테이너")
|
||||
void pureContainer() {
|
||||
AppConfig appConfig = new AppConfig();
|
||||
|
||||
// 호출 할 때마다 객체를 생성
|
||||
MemberService memberService1 = appConfig.memberService();
|
||||
MemberService memberService2 = appConfig.memberService();
|
||||
|
||||
// 참조 값이 다른 것을 확인
|
||||
System.out.println("memberService1 = " + memberService1);
|
||||
System.out.println("memberService2 = " + memberService2);
|
||||
|
||||
// memberService1 != memberService2
|
||||
assertThat(memberService1).isNotSameAs(memberService2);
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("싱글톤 패턴 적용한 객체 사용")
|
||||
void singletonServiceTest() {
|
||||
SingletonService singletonService1 = SingletonService.getInstance();
|
||||
SingletonService singletonService2 = SingletonService.getInstance();
|
||||
|
||||
System.out.println("singletonService1 = " + singletonService1);
|
||||
System.out.println("singletonService2 = " + singletonService2);
|
||||
|
||||
// memberService1 != memberService2
|
||||
assertThat(singletonService1).isSameAs(singletonService2);
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("스프링 컨테이너와 싱글톤")
|
||||
void springContainer() {
|
||||
|
||||
AnnotationConfigApplicationContext 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);
|
||||
|
||||
// memberService1 != memberService2
|
||||
assertThat(memberService1).isSameAs(memberService2);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package com.example.basic.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;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package com.example.basic.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;
|
||||
|
||||
class StatefulServiceTest {
|
||||
|
||||
@Test
|
||||
void statefulServiceSingleton() {
|
||||
ApplicationContext ac = new AnnotationConfigApplicationContext(TestConfig.class);
|
||||
StatefulService statefulService1 = ac.getBean(StatefulService.class);
|
||||
StatefulService statefulService2 = ac.getBean(StatefulService.class);
|
||||
|
||||
// A 사용자 10000원 주문
|
||||
statefulService1.order("userA", 10000);
|
||||
// B 사용자 20000원 주문
|
||||
statefulService2.order("userB", 20000);
|
||||
|
||||
// 사용자 A 주문 금액 조회
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user