BeanFactory나 ApplicationContext를 스프링 컨테이너라 한다.
ApplicationContext는 BeanFactory 외에도 여러가지 편리한 기능을 상속받은 컨테이너이다. 그리고 이 컨테이너 설정 정보는 다양한 형식으로 설정할 수 있다. ex) 자바 코드, XML, Groovy 등
<bean id="orderService" class="hello.respringstart.order.OrderServiceImpl">
<constructor-arg name="discountPolicy" ref="discountPolicy"></constructor-arg>
<constructor-arg name="memberRepository" ref="memberRepository"></constructor-arg>
</bean>
xml로 설정하면 이렇게 bean 이름과 return 하는 클래스를 지정해주고
constructor를 통해 생성자에 들어가는 객체를 지정해준다.
인스턴스가 딱 1개만 생성되도록 디자인하는 패턴이다.
자바코드 private를 이용해 수작업으로 만들 수 있지만, 이렇게 했을 때는 private로 인한 변경, 상속 제한/ DIP, OCP 위반이 발생한다.
이 단점을 보완하고 장점을 가져가기 위해 spring container를 사용한다.
@Configuration 어노테이션이 붙은 클래스에 @Bean 을 이용해 등록한다.
주의할 점은 싱글톤은 말 그대로 하나의 인스턴스가 반복해서 사용되기 때문에 무상태를 유지해야한다. 상태를 유지하는 필드가 값이 변경된다면, 위험한 문제가 될 수 있다.
- 스프링 핵심 : 컴포넌트 스캔 ~ 의존관계 자동 주입
- 애노테이션을 이용한 컴포넌트 스캔 자동 빈 등록, 탐색위치 지정 및 필터 기능에 대해 배웠다.
탐색위치 디폴트값이 자신이 위치한 패키지부터이므로 보통 패키지 최상위에 설정파일을 위치시킨다.
필터를 이용해 등록하지 않을 클래스를 지정할 수도 있다.
@AutoWired
- 의존관계 주입도 @AutoWired 애노테이션을 이용한다.
생성자, 수정자, 일반매서드, 필드 주입 이렇게 4가지 방법이 있지만, 생성자 사용을 권장하고, 필요에 따라 수정자를 이용한다.
private final MemberService memberService;
@AutoWired
public MemberService(MemberRepository memberRepository){
this.memberRepository = memberRepository
}
- 생성자를 이용하면, final 을 사용할 수 있고, 이를 통해 값이 딱 한번만 설정되고 변하지 않음을 보장할 수 있다. 이렇게 필요에 따른 제한은 프로그래밍을 할 때 굉장히 좋은 요소라고 한다.
@Primary
public class DiscountPolicy rateDiscountPolicy{...}
@Qualifier("fixDiscountPolicy)
public class DiscountPolicy fixDiscountPolicy{...}
- 조회할 빈의 타입에 해당하는 것이 여러개일 때 우선순위나 구분을 위해 @Primary, @Qualifier 애노테이션을 이용하고 @Qualifier의 경우에는 애노테이션을 직접 커스텀해서 사용하기도 한다. 하지만 무분별한 애노테이션 생성은 유지보수를 어렵게 하니 주의해야 한다. 보통은 여러개인 경우 메인 객체를 Primary로 지정하고 다른 객체를 사용해야할 경우에 Qualifier를 이용한다.
@RequiredArgsConstructor
static class DiscountService{
private final Map<String, DiscountPolicy> policyMap;
private final List<DiscountPolicy> policies;
}
- Map이나 List에 해당 타입을 주입받아 다형성을 활용할 수 있다.
- 자동과 수동 등록을 이용하는 기준
기본적으로 자동을 활용, 직접 등록하는 기술 지원 객체, 다형성을 적극 활용하는 비즈니스 로직은 수동 등록을 고민
- 스프링 빈의 이벤트 라이프사이클
스프링 컨테이너 생성 -> 스프링 빈 생성 의존관계 주입 -> 초기화 콜백 -> 사용 -> 소멸전 콜백 -> 스프링 종료
의존관계 주입이 끝난 시점, 스프링 종료 직전에 수행해야하는 작업이 있을 때 해당 시점에 작동하도록 함수를 설정할 수 있다.
방법은 인터페이스 상속, @Bean 옵션추가, 자바표준 지원 애노테이션 사용이 있는데, 애노테이션을 사용하는 것이 권장된다.
어떻게 쓰는지는 알겠지만, 실제로 어떤 상황에서 사용되는지는 잘 상상이 안 된다. 하지만 객체의 생성과 초기화를 분리하는 것이 유지보수측면에서 더 좋다고 한다. 여기서 초기화는 외부커넥션을 연결하는 것과 같은 무거운 작업이다. 객체 생성자는 객체 자체를 생성하는 것에만 집중하는 편이 좋다.
- 빈 스코프
스프링 컨테이너에서 빈을 관리하는 범위를 빈 스코프라고 한다.
private ObjectProvider<PrototypeBean> prototypeBeanProvider; //provider 선언
public int logic() {
PrototypeBean prototypeBean = prototypeBeanProvider.getObject();
prototypeBean.addCount();
int count = prototypeBean.getCount();
return count;
}
ApplicationContext를 선언해서 getBean을 할 수도 있지만, 그렇게 되면 스프링에 너무 종속적인 코드가 된다.
사실 프로토타입은 거의 사용 x, 초기가 아닌 필요할 때 생성된다는 특징이 있다.
@Component
@Scope(value = "request", proxyMode = ScopedProxyMode.TARGET_CLASS)
public class MyLogger {
}
프록시는 가짜 객체를 만들고 실제 필요한 시점에 진짜 객체와 연결해주는 스프링의 기능중 하나이다.
사실 Provider를 사용하든, 프록시를 사용하든 핵심 아이디어는 진짜 객체 조회를 꼭 필요한 시점까지
지연처리 한다는 점이다.
단지 애노테이션 설정 변경만으로 원본 객체를 프록시 객체로 대체할 수 있다. 이것이 바로 다형성과 DI
컨테이너가 가진 큰 강점이다.
꼭 웹 스코프가 아니어도 프록시는 사용할 수 있다.
HTTP 기본지식 강의를 듣기 시작했다.
이런식으로 전송 데이터를 TCP로 감싸고, IP로 다시 감싸서 전송한다.
UDP는 TCP보다 좀 더 간결한? 형식이라고 이해했는데, 최근에는 UDP를 사용하는 추세라고 한다.
전체 문법
• scheme://[userinfo@]host[:port][/path][?query][#fragment]
• https://www.google.com:443/search?q=hello&hl=ko
• 프로토콜(https)
• 호스트명(www.google.com)
• 포트 번호(443)
• 패스(/search)
• 쿼리 파라미터(q=hello&hl=ko)
HTTP
거의 모든 데이터를 주고받는 형식이 HTTP이다.
되도록 무상태, 비연결성으로 구성하는 게 좋다. 무상태로 했을 때 장점은, 서버 확장에 유리하고 더 효율적으로 요청을 처리할 수 있다. 하지만 주고받는 데이터의 양이 늘어나고, 연결을 끊었다 맺는데 비용이 발생한다.
HTTP 메서드
HTTP 요청을 보낼 때 path를 설정하는데, 이 path 를 리소스로 구성하는 게 좋다고 한다.
예를 들면 멤버를 찾는 거면 /member-find 가 아닌 그냥 /member 처럼 리소스로만 구성한다. 이때 동작을 구분하기 위해 HTTP 메서드를 이용한다.
- GET : 조회
- POST : 데이터를 처리 ( 대부분의 경우 사용 가능 )
- PUT : 데이터 자체를 교체, 바꿀 데이터의 위치가 정해져있고 클라이언트가 알고있다는 점에서 POST와 차이가 있고 데이터 자체를 바꿔버린다는 특징이 있다.
- PATCH : 데이터 수정, 일부분만 수정하는 점에서 PUT과 차이가 있다.
- DELTE : 삭제
이외에도 몇가지가 있지만 주로 사용되는 것의 위의 다섯가지이다.
메서드별로 안전, 멱등(Idempotent), 캐시와 같은 속성이 있다.
안전 : 리소스가 변하지 않는 것 ex) GET
멱등 : 여러번 호출해도 결과에 변화가 없는 것 ex) GET,PUT, DELETE
캐시는 뒤에서 자세히 다룰 예정
이야 빈씨 오랜만에 포스팅 !!