본문 바로가기

개발일기/Spring

[Spring]싱클톤 사용시 주의사항.

728x90
반응형

Bean을 통한 싱글톤이던, 순수 자바를 사용하여 만든 싱클톤 방식이던 주의 사항이 있다.

상태를 유지하면서 변경까지 되는 필드가 존재해서는 안된다.

그 이유를 간략한 예로 표현하겠다.

 

public class testService {
    private String userName;

    public void addUserName(String userName){
        this.userName = userName;
    }

    public String getUserName(){
        return userName;
    }
}

#위의 코드를 보면 usreName이라는 필드가 선언되었고 이 userName의 값을 addUserName을 통하여 값을 넣어주고,

getUserName을 통하여 return 하는 아주 간단한 코드이다. 

 

    @Test
    void 싱클톤주의사항(){
        ApplicationContext ac = new AnnotationConfigApplicationContext(testConfig.class);
        testService testService1 = ac.getBean("testservice" , testService.class);
        testService testService2 = ac.getBean("testservice" , testService.class);

        testService1.addUserName("홍길동");
        testService2.addUserName("김아무개");

        String getUserName1 = testService1.getUserName();

        System.out.println("testService1의 name = " + getUserName1);
    }

#위에 testService를 testConfig에 Bean으로 등록후 불러온다음 각각 testService1과 testServcie2를 생성하였다.

#그후 각각의 testService의 홍길동 , 김아무개라는 userName을 add 한후 testService1에서만 해당 userName을 get 하였다.

#이경우 예상하는 결과값은 당연히 홍길동이라는 이름이 나와야하지만 실제로 결과값은

#김아무개라는 이름이 출력이 되었다. 이는, 처음 testService에서 선언한 private String userName 에 처음 쓰레드로 홍길동이 입력이 되었지만 그 다음 쓰레드로 김아무개라는 이름이 새로 변경이되면서 이러한 현상이 이러나게 된것이다.

#이러한 오류는 실제 현업도중에 발생된다면 큰 이슈가 될일이다. 예를 들면 금액와 같은 예민한 것들이 있다.

#이를 방지하기 위해서는 해당 필드를 무상태로 유지해야한다.

 

public class testService {

    public String addAndGetuserName(String userName){
        return userName;
    }
}

#단순한 예이다. 필드를 선언하지 않고 그 값 그대로 다시 return 하는 코드이다.

#이경우 결과 값은,

 

#원하던대로 홍길동이라는 이름이 출력이 된걸 볼 수 있다.

#정말 예민한 사항이기 때문에 항상 이 점을 유의하며 개발을 해야한다.

728x90
반응형