SpringのSingleton
Singleton
モノトーンとは?
Javaを使用して単一トーンモードを実装し、ビューstatic finalを使用してjavaサーバ上で1つのインスタンスしか存在しないように設計し、getInstance()メソッドを使用すると、インスタンスが他のサービスロジックで1つのインスタンスを共有できます.
public class SingletonService {
//1. static 영역에 객체를 딱 1개만 생성해둔다.
private static final SingletonService instance = new SingletonService();
//2. public으로 열어서 객체 인스터스가 필요하면 이 static 메서드를 통해서만 조회하도록 허용한다.
public static SingletonService getInstance() { return instance; }
//3. 생성자를 private으로 선언해서 외부에서 new 키워드를 사용한 객체 생성을 못하게 막는다.
private SingletonService() { } public void logic() {
System.out.println("싱글톤 객체 로직 호출");
}
}
実施したモノトーンモードテスト
@Test
@DisplayName("싱글톤 패턴을 적용한 객체 사용")
public void singletonServiceTest() {
//private으로 생성자를 막아두었다. 컴파일 오류가 발생한다.
//new SingletonService();
//1. 조회: 호출할 때 마다 같은 객체를 반환
SingletonService singletonService1 = SingletonService.getInstance();
//2. 조회: 호출할 때 마다 같은 객체를 반환
SingletonService singletonService2 = SingletonService.getInstance();
//참조값이 같은 것을 확인
System.out.println("singletonService1 = " + singletonService1);
System.out.println("singletonService2 = " + singletonService2);
}
モノトーンパターンの設計をうまく実現したようだが,この設計には問題がある.
Singleton Container
モノクロコンテナは、モノクロモードの問題を解決し、モノクロモードのターゲットに従って実行できます.今まで私たちが学んだSpring Binはモノトーン管理のBindsです
Singleton Containerとは?
@Test
@DisplayName("스프링 컨테이너와 싱글톤")
void springContainer(){
//AppConfig appConfig = new AppConfig();
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);
Assertions.assertThat(memberService1).isSameAs(memberService2);
}
上記のテストコードを実行して、アドレス値が結果値と同じであることを確認します.ただし、アイテムをモノトーンで作成する場合は、注意が必要です.
モノトーンの注意点
モノトーンの注意点
アテンションポイントが認識されないときに発生する障害例コード
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;
}
}
@Test
void statefulServiceSingleton(){
AnnotationConfigApplicationContext ac = new annotationConfigApplicationContext(TestConfig.class);
StatefulService statefulService1 = ac.getBean(StatefulService.class);
StatefulService statefulService2 = ac.getBean(StatefulService.class);
//ThreadA : A 사용자 10000원 주문
statefulService1.order("userA", 10000);
//ThreadB : B 사용자 20000원 주문
statefulService2.order("userB", 20000);
//ThreadA : 사용자A 주문 금액 조회
int price = statefulService1.getPrice();
System.out.println("price = " + price);
Assertions.assertThat(statefulService1.getPrice()).isEqualTo(20000);
}
上記のテストを行い、Aのユーザーは10000ウォンの商品を注文し、Bのユーザーは20000ウォンの商品を注文した.ただし、javaサーバは単一トーンモードであるため、インスタンスが共有され、インスタンスのpriceフィールドの値が変更されます.だから.前述したように、Aという10000ウォンの価格は20000ウォンに変更できない.
@構成とモノトーン
ここには好奇心のある場所があるかもしれませんそれではAppConfigファイルで確認してみましょう@Configuration
public class AppConfig {
//@Bean memberService -> new MemoryMemberRepository()
//@Bean orderService -> new MemoryMemberRepository()
@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());
}
@Bean
public DiscountPolicy discountPolicy(){
return new RateDiscountPolicy();
}
}
上記のコードでは、memberServiceとorderServiceが2回MemoryMemerRepository()を呼び出し、memberRepository自体が1回呼び出され、合計3回MemoryMemerRepositoryが呼び出されます.では、このインスタンスをスプリングコンテナでどのように管理しますか?3回の呼び出しのすべてのインスタンスを作成する必要がありますか?インスタンスを共有しますか?モノトーンモードでは、1つに共有する必要があります.Springがこれを実現したのは,@Configurationでバイトコードを処理するライブラリCGIB技術を用いたためである.
@構成のバイトコード操作 @Bean
public MemberRepository memberRepository() {
if (memoryMemberRepository가 이미 스프링 컨테이너에 등록되어 있으면?) {
return 스프링 컨테이너에서 찾아서 반환;
} else { //스프링 컨테이너에 없으면
기존 로직을 호출해서 MemoryMemberRepository를 생성하고 스프링 컨테이너에 등록
return 반환
}
}
上記のコードのような操作により、コンテナインスタンスを登録するかどうかを決定し、インスタンスを管理し、単一の色調であることを保証する.출처
https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-%ED%95%B5%EC%8B%AC-%EC%9B%90%EB%A6%AC-%EA%B8%B0%EB%B3%B8%ED%8E%B8
Reference
この問題について(SpringのSingleton), 我々は、より多くの情報をここで見つけました
https://velog.io/@ililil9482/Spring의-Singleton
テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol
@Configuration
public class AppConfig {
//@Bean memberService -> new MemoryMemberRepository()
//@Bean orderService -> new MemoryMemberRepository()
@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());
}
@Bean
public DiscountPolicy discountPolicy(){
return new RateDiscountPolicy();
}
}
@Bean
public MemberRepository memberRepository() {
if (memoryMemberRepository가 이미 스프링 컨테이너에 등록되어 있으면?) {
return 스프링 컨테이너에서 찾아서 반환;
} else { //스프링 컨테이너에 없으면
기존 로직을 호출해서 MemoryMemberRepository를 생성하고 스프링 컨테이너에 등록
return 반환
}
}
上記のコードのような操作により、コンテナインスタンスを登録するかどうかを決定し、インスタンスを管理し、単一の色調であることを保証する.출처
https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-%ED%95%B5%EC%8B%AC-%EC%9B%90%EB%A6%AC-%EA%B8%B0%EB%B3%B8%ED%8E%B8Reference
この問題について(SpringのSingleton), 我々は、より多くの情報をここで見つけました https://velog.io/@ililil9482/Spring의-Singletonテキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol