Java, Spring/스프링 핵심 원리 기본

5-4. 싱글톤 방식의 주의점(아주 중요) ~ 5-6

app0a 2022. 8. 7. 11:29

여러 클라이언트가 같은 객체를 공유하여 쓰므로 싱글톤 객체는 stateless로 써야함. 특정 클라이언트가 값을 변경할 수 있는 필드가 있으면 안됨.

 

 

 

이렇게 해놓고..

 

당연히 20000원 출력 ( stateful 하므로. )

같은 객체 StatefullService 의 Price필드는 공유됨. (당연한 소리)

 

 

특정 클라이언트가 값을 변경할 수 있는 필드는 없어야한다.

 

 

 

# 그럼 어떻게 Stateless하게 바꾸나?

 

필드 넣지 말고 그냥 price를 반환해라. 그러면.,,,

 

이러면 각각 10000원, 20000원이 나온다.

 

 

 

---------------------------------------------- 5-5. @Configuration과 싱글톤

 

@Configuration의 비밀 -> 싱글톤을 위해서 존재.

 

 

위의 주석처럼 MemoryMemberRepostiory가 두번 new 되니까 싱글톤 깨지는거 아닌가요?

--> 테스트 해보자.

 

MemberSerivceImpl, OrderServiceImpl에 각각

///테스트 용도
    public MemberRepository getMemberRepository() {
        return memberRepository;
    }

 

을 넣어서 꺼내서 비교해보자.

 

 

미쳤다 똑같다.....

등록된 진짜 memberRepository도 꺼내보자.

세 놈다 같은 놈이다...미쳤다..

 

각각 빈에 확인을 위한 call을 출력해보자

( 스프링은 기를 쓰고 싱글톤을 유지한다. )

 

 

 

-------------------------------------------------------------- 5-6. @Configuration과 바이트코드 조작의 마법

 

 

 

 

스프링이 아무리 좋아도 자바코드를 어찌 할 수는 없다. ( 분명 3번 호출되었어야한다. )

 

 

AppConfig빈을 찍어보면 뒤에 $$ 이상한게 붙는다.

 

결론 : 내가 만든 AppConfig 클래스가 아니다.

ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ내가 예상한 대로다 너무쉽다. ( 컨테이너에 있으면 그걸 씀, 없으면 컨테이너에 생성. )

 

-------------------

이건 몰랐음

 

AppConfig를 상속하는 AppConfig@CGLIB의 메서드가 저 위의 메서드다. ( 오버라이딩 시켜서 조작코드를 실행하게끔한다. -> 스프링은 원래 자바코드를 어찌 할 수는 없으므로. )

부모타입을 bean 조회하면 자식타입의 빈들도 다 튀어나온다.

 

( @Configuration 이 붙어있어야 CGLIB으로 컨테이너에 올린다. )

 

 

 

# @Configuration이 없을 때

그냥 new된것이므로 스프링이 관리하지않는 객체이다. ( 그냥 자바객체 )

이 처럼 그냥 메서드 안에서 new한 것이므로. ( 물론 @Configuration이 없을 떄 )