스프링 컨테이너: BeanFactory를 기반으로 Bean 클래스들을 제어할 수 있는 기능을 지원한다.
스프링의 동작 구조 :
Request -> Servlet 컨테이너 -> Spring 컨테이너(new XmlWebApplicationContext()-> servlet-context.xml불러옴 )
*servlet-context.xml : spring 컨테이너가 실행해야 하는 내용을 설정하는 파일
(트랜잭션 관리, DI, AOP 등 관리)
즉,
1. 요청
2. 서블릿 컨테이너 - DispatcherServlet이 받음 (Web.xml 포함됨)
3. HandlerMapping ( 해당 요청을 매핑한 컨트롤러가 있는지 검색 -- @RequestMapping() 제공)
4. 처리 요청 +Bean등록
5. 결과를 출력할 View 리턴
6. DispatcherServlet에서 ViewResolver를 통해 view 검색 처리
[읽어들이는 순서]
-서버 구동시 web.xml 제일먼저 읽음
-그 안의 context-param 가장 먼저 읽음
-그 안에 root-context(자원관련 , DB ) / spring-security xml을 써놨고 제일 먼저 작동됨
-bean (스프링에서 생성하고 관리하는 객체) 으로 정의해놓음
-클라이언트가 요청시 dispatcher servlet 읽음 == 서블릿 컨테이너가 먼저 받음 ==> 스프링 컨테이너로 넘겨줌
-스프링 컨테이너의 servlet-context.xml의 설정대로 요청 받게됨 -> Handler Mapping ->
요청받은 주소를 처리할 클래스나 메서드에 지정하는 역할 (어노테이션 형식 사용) ==> @Controller, @RequestMapping 이 쓰임
-component-scan이 작동됨 -> 처리진행 -> 문자열 반환
-반환받은 문자열에 앞뒤 경로 붙여서 View Resolver 에서 응답 경로 내보냄
Bean?
-스프링이 IoC 방식으로 관리하는 객체 / 스프링이 직접 생성과 제어를 담당
<스프링 컨테이너와 스프링 빈> 작동 단계
1. 스프링컨테이너 생성
2. 스프링 빈 등록
3. 스프링 빈 의존관계 설정 준비
4. 스프링 빈 의존간계 설정 완료
<스프링 빈 조회 - 상속관계>
-> 부모타입으로 조회하면 자식타입도 모두 조회됨
<IoC컨테이너>
Bean 생성 객체 : BeanFactory <- ApplicationContext <- AnnotaionConfig ApllicationContext (상속)
BeanFactory :스프링 컨테이너 최상위 인터페이스 / 스프링의 IoC 담당하는 핵심
ApplicationContext : 팩토리 상속받아 빈 관리 + 부가기능위해 (실질적 사용)
* 스프링 컨테이너는 다양한 형식의 설정 정보를 받아들일수 있게 설계됨
(애너테이션, XML)
HOW? BeanDefinition이라는 추상화 덕분에 여기서 메타정보만 가져오면 스프링 빈을 생성할 수 있다.
<싱글톤 패턴>
대부분의 스프링 애플리케이션은 웹 -> 여러 고객이 동시에 요청을 한다
==> 문제점 : 요청시마다 계속 객체 생성해줘야함 ==>메모리 낭비가 극심
--> 1개의 객체를 공유하도록 설계 == 싱글톤 패턴
싱글톤 패턴 : 클래스의 인스턴스가 딱 1개만 생성되는 것을 보장하는 디자인 패턴
--> 2개 이상 생성을 막는다 == private으로 외부 new 막는다
==>스프링에선 자동으로 싱글톤 지원해줌
문제 :
1. 코드가 길어짐
2. 구체클래스에 의존한다 DIP 위반
3. == OCP 위반
4. 테스트 어려움
5. 유연성 떨어짐, 자식클래스 만들기 어려움
==> 스프링에서는 싱글톤 패턴 문제-> 싱글톤 컨테이너에서 해결함
싱글톤 컨테이너 : 싱글턴 패턴 적용 없이 싱글톤으로 관리
-> 스프링 컨테이너에서 관리.
-> 이미만들어진 객체를 공유해서 재사용
<싱글톤 방식의 주의점!!>
-> 상태를 유지하게 설계하면 안된다
== 만약 유저1일 100의 값을 넣은 상태에서 유저 2가 200의 값을 넣고 유저1이 값을 조회한다면?
==> 문제발생
<@Configuration> : 스프링의 싱글톤을 위해 존재한다
만약 두개의 bean에서 동일한 객체를 new로 생성한다면?각각 new 해야 맞지만 스프링이 싱글톤을 관리해줌 ==모두 같은 인스턴스가 공유되어 사용됨
HOW?
bean을 출력해보면 클래스 경로 + CGLIB를 붙혀버림 (상속 클래스를 하나 더 추가해서 조작함) => 이것이 유지해줌
1. 이미 스프링컨테이너에서 있으면? 스프링 컨테이너에서 반환
2. 아니면? 기존 로직을 호출해서 스프링 컨테이너에 등록하고 반환
-> @Configuration이 해주는 일이므로 @bean만 쓰면 싱글톤이 유지되지 않는다!