[spring]モノトーン注意点(spring基本編by金英漢)


モノトーンの注意点
単一トーンでオブジェクトを作成して共有するため、ステータスを維持するように設計されています.🔥ぜったい🔥 いけません!
そうであれば、複数のユーザが同時に要求を発行すると、問題が発生する可能性があります.したがって、特定のユーザに依存して立ってはいけません.たとえば、グローバル変数を作成してステータスを保存したり、特定のユーザーに基づいて値を変更したりすることは避けてください.この問題は、領域変数またはパラメータを一時的に存在させることで解決できます.
ステータスのあるクラス
たとえば、価格を保存し、ユーザーの注文に応じて変更させるには、ステータス設計があります.
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;
    }
}
勘定科目のテスト・コード
以下のクラスにTestConfigを作成し,スプリングコンテナを作成してテストした.もちろん、現在はマルチスレッドではありませんが、マルチスレッドと仮定すると、ユーザー1の注文とクエリー金額の間に、ユーザー2が注文しました.これにより価格が変わり、ユーザー1の価格は20000になります.
class StatefulServiceTest {

    @Test
    void statefulServiceTest() {
        ApplicationContext 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);

    }

    static class TestConfig {

        @Bean
        public StatefulService statefulService() {
            return new StatefulService();
        }
    }

}
ステータス変更なし
StatefulServiceを次のように変更します.orderの戻り値をpriceとして終了します.orderの後に戻り値を保存すると、ユーザー間で混同は発生しません.
public class StatefulService {

    public int order(String name, int price){
        System.out.println("name = " + name + "price = " + price);
        return price
    }

}