spring core : singleton container

This commit is contained in:
haerong22
2021-10-05 22:46:52 +09:00
parent d71e0fec8f
commit 9b13cf0f88
8 changed files with 180 additions and 0 deletions

View File

@@ -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());
}

View File

@@ -17,4 +17,9 @@ public class MemberServiceImpl implements MemberService {
public Member findMember(Long memberId) {
return memberRepository.findById(memberId);
}
// 테스트 용
public MemberRepository getMemberRepository() {
return memberRepository;
}
}

View File

@@ -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;
}
}

View File

@@ -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());
}
}

View File

@@ -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("싱클톤 객체 호출");
}
}

View File

@@ -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);
}
}

View File

@@ -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;
}
}

View File

@@ -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();
}
}
}