bean이란?
- 스프링은 이전에 프레임워크와 의존성이 매우 높았던 EJB대신 POJO객체를 쓰는 것을 강조한다.
- POJO란 프레임워크에 독립적인 객체를 의미한다.
- IOC컨테이너, 즉 application context에서 beanFactory 인터페이스들을 확장해 bean들의 라이프사이클을 관리한다.
bean의 메타정보
- 빈 아이디: 빈 오브젝트를 구분할 수 있는 식별자
- 클래스 or 클래스 이름: 빈으로 만들 POJO클래스 또는 서비스 클래스 정보
- 스코프: 빈의 생성 방식과 존재 범위
- 프로퍼티 값 또는 참조: DI에 사용할 프로퍼티 이름과 값 또는 참조하는 빈의 이름
- 생성자 파라미터 값 또는 참조: DI에 사용할 생성자 파라미터 이름과 값 또는 참조할 빈의 이름
- 지연된 로딩 여부, 우선 빈 여부, autowiring여부, 부모 빈 정보, 빈팩토리 이름 등
bean scope란?
- singleton: 한번만 생성해서 캐시해두고 계속해서 사용(디폴트)
- 상태가 없을 때
- 이뮤터블 할 때
- 상태가 있어도 생성하는 비용이 매우 클 때
- prototype: 사용할때마다 계속 생성
- 뮤터블해서 동기화 비용을 생각할 바에는 객체를 새로 만들 때
- request: 한 http request안에는 하나의 객체만 존재
- session: 한 http session안에는 하나의 객체만 존재
- global session: 한 global session안에는 하나의 객체만 존재
singleton vs prototype
- 싱글톤
- ioc컨테이너가 빈의 초기화 및 라이프사이클 관리
- prototype
- ioc컨테이너는 빈을 초기화하고 di를 해주지만, 거기서부터는 di받은 빈이 담당한다. 즉, di받은 빈이 제거되면 그때 해당 빈도 제거됨
- 사용자의 요청별로 필요한 오브젝트(ex DTO)를 new로 안만들고 ioc에서 DL받을 필요가 있을 때 사용
ex) DTO 내부에서 DB에 접근할 필요가 있어서 DAO를 주입받아야 할 때
- 왜 DI를 안하고 DL을?: DI를 할 경우에는 컨트롤러에서 DTO를 di받을텐데, 이렇게 하면 컨트롤러의 빈스코프가 싱글톤이기 때문에 해당 DTO의 빈스코프가 프로토타입이어도 요청마다 제거되지 않음. 따라서 컨트롤러에 들어와서 지역변수에다가 DL을 하면 요청이 끝나면 제거됨.
다른 요청 스코프, 세션 스코프들은 왜 DL?
- DI로 할 경우에는 맨처음에 객체를 초기화할 때, 에러가 발생할 것<- 요청 스코프는 요청이 들어오면 객체를 생성하기 때문. 따라서 나중에 주입할 수 있는 DL로 찾아오는게 옳다.
요청 스코프와 프로토타입의 차이
- 그러면 매 요청마다 새로 생성되니 같은 것 아닌가?
- ㄴㄴ 보통 평범하게 사용하면 매 요청마다 새로 생성하겠지만, getBean을 여러번 하면 요청 스코프는 요청 안에서는 매번 똑같은 객체를 얻을 수 있지만, 프로토타입의 경우에는 매번 다른 객체를 얻음
수정자 주입, 생성자 주입
application Context 두개
DL방식
- ServiceLocatorFactoryBean, 메소드 주입 등등..
- @Inject Provider< T >사용하는 방식이 제일 많이 쓰임
세션 스코프 동작방식
스코프 프록시 오브젝트 사용 - 어떤 오브젝트를 가져올지는 알아서 추상화가 됨
bean을 가져오는 순서
- 빈의 메타 정보를 기록해 둔 beanDefinition을 등록 applicaionContext에 등록
- applicaionContext내부에서 빈을 생성
- applicationContext에서 빈을 가져와서 사용
WebApplicaionContext
- ApplicationContext구현체중 WebApplicationContext가 웹 서비스에서 가장 편하게 사용 가능
- main메소드 역할을 하는 서블릿을 만들어두고, 어플리케이션 컨텍스트를 생성한 뒤, 요청이 서블릿으로 들어올 때마다 getBean으로 빈을 가져와 정해진 메소드를 실행하는 방식이었는데(스프링의 덜 추상화된 api를 사용하니 프레임워크에 종속적으로 됨), webApplicationContext를 사용하면 DispatcherServlet이 중간 역할을 대신해준다. 요청이 들어오면 기존에 생성한 어플리케이션 컨텍스트에서 빈을 찾아와 이를 실행시켜주는 역할
- 이 DispatcherServlet가 들어온 모든 요청에 대해 filter를 처리하고 알맞은 핸들러에 요청을 전달하기 때문에 프론트 컨트롤러라고도 함
bean 스캔 방식
- 스테레오타입 어노테이션이 붙어 있을 경우 빈으로 인식: 클래스에 붙어서 해당 클래스가 컴포넌트 스캐닝의 대상이고 스프링을 통해 관리될 것이라고 명시하는 어노테이션
bean등록 방법
- configuration + bean: bean이 싱글톤일 경우 싱글톤으로 동작
- bean: 매 요청마다 새로운 객체를 리턴
- component: 클래스에 붙이는 스테리오타입 어노테이션
autowired
방식
- 생성자:
- 장
- 수정자 메소드가 많아질 일이 없다
- 순환 참조를 미리 알 수 있다.
- 단
- 일부 프로퍼티는 쪽 DI하지 않고 선택적으로 DI할 수 있도록 하지 못한다(아니 할 수 있잖아????)
- 수정자
- 필드
관련 anotation
- resource: 빈의 이름과 타입으로 찾음
- autowired: 빈의 이름과 타입으로 찾음
- resource와의 차이: 생성자에도 부여 가능
- qualifier: 빈에게 한정자 값을 주고 이 한정자를 가진 빈을 autowired할 수 있게 한다.
- value: 해당되는 값을 넣어줌
컨테이너 위치
WebApplication 레벨에 컨테이너 존재
- 프론트 컨트롤러 서블릿의 어플리케이션 컨텍스트를 자식으로, 웹 어플리케이션에 어플리케이션 컨텍스트를 부모로 두는 구조
- 하나로 합쳐도 되지만, 스프링을 사용하지 않는 기술들은 서블릿을 거쳐갈 필요가 없기에 곧바로 루트 어플리케이션 컨텍스트에 접근하라고 둠
주입 방식
생성자 주입
- 어플리케이션을 실행하면 객체를 생성하기 위해 DI를 받는데, 여기서 순환참조를 확인할 수 있음.
필드 주입, 새터 주입
- 객체를 메모리에 올린 다음에 DI를 하므로, 어플리케이션을 실행해도 에러를 발견할 수 없음
- 필드를 final로 지정할 수 없음
https://coding-start.tistory.com/250
MVC패턴이란?
모델, 뷰 컨트롤러로 이뤄진 패턴으로, 두가지 구현 방식이 존재
spring mvc vs spring boot