작성
·
271
·
수정됨
0
싱글톤 패턴강의에서 질문있습니다.
(싱글톤 컨테이너 강의 SingletonTest.class파일에서나옴)
ApplicationContext ac= new AnnotationConfigApplicationContext(Appconfig.class);
웹 애플리케이션과 싱글톤강의 SingletonTest class 에서 나옴
Appconfig appConfig=new Appconfig();
컨테이너에 등록된 모든 빈 조회강의 ApplicationContextBasicFindTest class에서 나옴
AnnotationConfigApplicationContext ac =new AnnotationConfigApplicationContext(Appconfig.class);
3가지 차이가 뭐에요?
세개 다 Appconfig.class를 참조하는것 같은데요.
2.
강의 자료 싱글톤 컨테이너2번째 장에 아래와 같이 나왔는데요.
고객 트래픽이 초당 100이 나오면 초당 100개 객체가 생성되고 소멸된다! 메모리 낭비가 심하다.
해결방안은 해당 객체가 딱 1개만 생성되고, 공유하도록 설계하면 된다. 싱글톤 패턴
public class SingletonService {
private static final SingletonService instance = new SingletonService();
public static SingletonService getInstance(){
return instance;
}
private SingletonService(){
}
public void logic(){
System.out.println("싱글톤 객체 호츌");
}
}
위에께 강의 자료 3페이지에 나온 코드인데 해당 객체가 딱 1개만 생성되었는데요.
2페이지에 나온 코드(스프링 없는 순수한 DI 컨테이너 테스트코드)가 메모리 낭비가 심하니까 위코드로 인해 메모리가 절약하는걸로 이해해도 되나요?
3.강의 자료 싱글톤 컨테이너4번째 장에 아래와 같이 나왔는데요.
의존관계상 클라이언트가 구체 클래스에 의존한다. DIP를 위반한다.(
클라이언트가 구체 클래스에 의존해서 OCP 원칙을 위반할 가능성이 높다.
dp랑 ocp가 어디가 위반되었다는건가요?
혹시 인텔리제이에서 SingletonService 이렇게 작성하길 원할 때 대문자가 자동으로 변환되는건가요?아니면 시프티키 눌러서 대문자로 직접 변환하고 소문자로 변환하는건가요?
강의 자료 싱글톤 컨테이너에서 10페이지와 11페이지에 걸쳐진 테스트 코드에서 질문입니다.
MemberServiceImpl memberService = ac.getBean("memberService", MemberServiceImpl.class);
위부분을 MemberServiceImpl memberService = ac.getBean("memnberService", MemberServiceImpl.class);
이렇게 바꿔쓰면(이름부분에m추가하면)no bean이라고 컴파일 에러가 나옵니다. 근데 MemberServiceImpl.class파일에 memberService 이런 함수명이 없는데(강의자료에도 없음) 컴파일할 떄 어디서 참조되는건가요?
6.@Configuration과 싱글톤
8분에 강의 중에 memberRepository가 5번 호출됬다가 3번 호출됬다가 그러시는데
MemberServiceImpl.class에서
public MemberRepository getMemberRepository(){
return memberRepository;
}
이거 호출되는것 같은데 appconfig파일에
@Bean
public MemberService memberService(){
return new MemberServiceImpl(memberRepository());
}
이부분이 왜 호출되는거에요?
그리고 @Bean
public MemberRepository memberRepository() {
return new MemoryMemberRepository();
} 이부분이 어떻게 5번이 호출되는건가요?
@Configuration과 바이트코드 조작의 마법 7분 41초에 memorymemberrepasitory가 등록이 되어있어서 한번만 호출되어있다고 하셨는데 그 코드상에서 언제 등록이 된건가요?
답변 1
0
안녕하세요 ekek 님, 인프런 AI 인턴이에요.
세 가지 코드 간의 차이점은 다음과 같습니다.
첫 번째 코드: ApplicationContext ac = new AnnotationConfigApplicationContext(Appconfig.class);
- 어노테이션 기반의 애플리케이션 컨텍스트를 생성하는 코드입니다.
두 번째 코드: Appconfig appConfig = new Appconfig();
- Appconfig 클래스의 인스턴스를 직접 생성하는 코드입니다.
세 번째 코드: AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(Appconfig.class);
- 어노테이션 기반의 애플리케이션 컨텍스트를 생성하는 코드입니다. 두 번째 코드와는 달리 애플리케이션 컨텍스트를 생성하는 과정에서 컨테이너에 등록된 빈들도 함께 생성됩니다.
싱글톤 패턴을 사용하면 해당 객체가 딱 1개만 생성되고, 여러 곳에서 공유될 수 있게 됩니다. 따라서 메모리 낭비를 줄일 수 있습니다. 첫 번째 코드는 싱글톤 패턴을 사용해서 객체를 생성하고, 두 번째 코드는 싱글톤 패턴을 사용하지 않고 객체를 생성합니다. 따라서 첫 번째 코드를 사용하면 메모리 낭비를 줄일 수 있습니다.
DIP(Dependency Inversion Principle)는 추상화에 의존해야 하며, 구체화에 의존해서는 안 된다는 원칙을 말합니다. 즉, 의존 관계를 맺을 때 인터페이스에 의존하도록 설계해야 합니다. 싱글톤 패턴을 사용하면 구체 클래스에 의존성이 발생할 수 있으므로 이는 DIP 원칙을 위반할 수 있는 요소입니다. 또한, 클라이언트가 구체 클래스에 의존하면 클라이언트가 해당 구체 클래스에 종속되어 유연성과 확장성이 떨어질 수 있으며, OCP(Open-Closed Principle)를 위반할 가능성이 높아집니다.
인텔리제이는 자동으로 대문자를 소문자로 변환하는 기능을 제공합니다. 따라서 MemberServiceImpl을 작성할 때 대문자로 시작하고 싶다면 직접 대문자로 변환하거나, Shift키를 누르고 소문자로 직접 변환하면 됩니다.
MemberServiceImpl 클래스의 memberService() 메서드에서 ac.getBean("memberService", MemberServiceImpl.class)
호출 시, memberService() 메서드 안에서 memberRepository() 메서드가 호출됩니다. 그래서 memberRepository()는 5번 호출되며, 자바의 메서드 호출방식이 스택 기반의 호출 방식이기 때문에 나중에 호출된 memberRepository()의 리턴값을 계속해서 사용하게 됩니다.
@Configuration 어노테이션은 스프링의 기능 중 하나인 바이트코드 조작(Bytecode Manipulation)을 이용하여 동작합니다. 스프링은 애플리케이션 컨텍스트를 초기화하고 빈(Bean)을 관리하기 위해 자바의 바이트코드를 동적으로 조작합니다. 따라서 @Configuration 어노테이션이 적용된 클래스를 스프링 컨테이너가 인식할 때에 등록되는 것입니다.
안녕하세요. ekek님
AI 인턴이 답변을 해주었는데요. 관려해서 부족한 부분이 있으면 말씀해주세요.
감사합니다.