Today I Learned_220710
Spring Framework
BeanDefinition
스프링은 BeanDefinition이라는 메타 정보로 스프링의 설정 메타 정보를 추상화 한다.
AnnotationConfigApplicationContext로 생성
beanDefinitionName = memberService beanDefinition = Root bean: class [null]; scope=; abstract=false; lazyInit=null; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=appConfig; factoryMethodName=memberService; initMethodName=null; destroyMethodName=(inferred); defined in hello.core.AppConfig
GenericXmlApplicationContext로 생성
beanDefinitionName = memberRepository beanDefinition = Generic bean: class [hello.core.member.MemoryMemberRepository]; scope=; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; defined in class path resource [appConfig.xml]
scope가 비어 있는 것 : singleton으로 생성
lazyInit : 보통 스프링 빈들이 스프링 컨테이너가 뜰 때 등록이 된다. 그게 아니라 실제 사용하는 시점에 스프링을 초기화하라는 정보
factoryBeanName, factoryMethodName을 통해 빈이 어디에서 생성되었는지 확인 가능
스프링에 빈을 등록하는 방법
- 직접 스프링 빈을 등록 (일반적으로 XML config를 이용해 등록하는 방법)
- factory method를 사용하는 방법 (일반적으로 Java config를 이용해 등록하는 방법). 외부에서 메소드를 호출해서 생성이 되는 방식
annotation이 도입되면서 factory method를 사용하는게 더 용이해졌다.
Singleton
웹 어플리케이션의 특징 : 고객의 요청이 많다.
스프링 없는 순수한 DI 컨테이너는 요청을 할 때마다 객체를 새로 생성함 -> 트래픽이 많이 나오면 많은 객체가 생성되고 소멸되며 메모리 낭비가 심하다.
싱글턴 패턴을 사용하여 해당 객체가 딱 1개만 생성되고 공유하도록 설계하면 된다.
스프링 컨테이너를 사용하면 스프링 컨테이너가 객체를 기본적으로 싱글톤으로 관리해 준다.
싱글톤 패턴은 객체가 1개만 생성되는 것을 보장하지만, 많은 단점을 가지고 있음
- 싱글톤 패턴을 구현하는 코드가 많이 들어감
- 클라이언트가 구체 클래스에 의존해여 DIP, OCP 위반
- 테스트하기 어렵다
- 자식 클래스 만들기 어려움
- 유연성이 떨어져 안티패턴이라 불리움
스프링 컨테이너는 싱글톤이 가진 위의 단점들을 제거하면서 객체를 싱글톤으로 관리해 준다.
IntelliJ
command + B : 정의로 이동
JUnit
assertThat의 method
same : 객체 인스턴스가 같은지
equal : Java의 equals에 해당