WAS
WS
스프링 프레임워크는 자바 개발을 편리하게 해주는 오픈 소스 프레임워크
1. 경량 컨테이너로서 자바 객체를 직접 관리
--> 각각의 객체 생성, 소멸과 같은 라이프 사이클을 관리하며 스프링으로부터 필요한
객체를 얻어올 수 있다.
2. 제어의 역전(IoC) 기술을 통해 어플리케이션의 느슨한 결합을 도모
--> 컨트롤의 제어권이 사용자가 아닌 프레임워크에 있어 필요에 따라 스프링에서 사용자의 코드를 호출
3. 의존성 주입(DI)을 지원
--> 각각의 계층이나 서비스들 간에 의존성이 존재할 경우 프레임워크가 서로 연결시켜준다.
4. 관점 지향 프로그래밍(AOP)을 지원
--> 트랜잭션이나 로깅, 보안과 같이 여러 모듈에서 공통적으로 사용하는 기능의 경우 해당 기능을 분리하여 관리할 수 있다.
@RequestBody
클라이언트가 전송하는 JSON 형태의 HTTP Body 내용을 MessageConverter를 통해 Java Object로 변환시켜주는 역할
@RequestParam
1개의 http 요청 파라미터를 받기 위해 사용하며, 필수 여부가 true이기 때문에 기본적으로
반드시 해당 파라미터가 전송되어야 한다. 전송되지 않으면 400에러 발생
반드시 필요한 변수가 아니라면 required = false 설정
@ModelAttribute
http Body내용과 http 파라미터 값들을 생성자, getter, setter를 통해 주입하기 위해 사용
spring은 프로젝트 초기에 다양한 환경설정을 해야 하지만
spring Boot는 설정의 많은 부분을 자동화하여 사용자가 편하게 스프링을 사용할 수 있도록 해준다. spring Boot starter dependency만 추가해주면 설정은 끝나고 내장 톰캣이 있어 서버를 바로 실행할 수 있다.
쉽게 말하면 유저가 웹 사이트에 들어가면
컨트롤러가 유저의 요청에 따라 서비스를 제공하기 위해 모델을 호출
호출된 모델은 데이터 소스에 그 결과를 가져오고
컨트롤러가 모델이 그 결과를 뷰에 반영하여 최종적으로 뷰를 유저가 볼 수 있게 된다
mvc패턴은 1, 2로 나뉘어짐
mvc1패턴
컨트롤러와 뷰가 같이 있음
뷰가 유저의 요청도 처리함
장점 - 빠르고 쉬운 개발
단점 - 뷰가 비대해짐, 컨트롤러와 뷰가 조잡해짐
mvc2패턴
컨트롤러가 유저에게 바로 뷰를 보여줄건지 모델을 거쳐갈건지 결정
뷰는 말 그대로 뷰 역할
장점 - 유지보수, 확장이 편함 / 개발자간 분업, 협업이 좋아짐
단점 - 난이도가 높아져 설계 단계가 힘듦
DispatcherServlet : 클라이언트에게 요청을 받아 으답까지의 MVC 처리과정을 통제
HandlerMapping : 클라이언트의 요청 URL을 어떤 Controller가 처리할지 결정한다.
ViewResolver : Controller의 처리 결과(데이터)를 생성할 view를 결정한다.
제어의 역전이란 모든 객체에 대한 (생성, 라이프사이클 등) 제어권을 개발자가 아닌 IoC 컨테이너에게 넘긴 것을 말한다. 스프링에서는 IoC 컨테이너에 객체들을 생성하면 객체끼리 의존성을 주입하는 역할을 하고 컨테이너에 등록한 객체들을 빈이라고 한다.
2가지의 방법
1. @Component 어노테이션 사용
@Controller, @Service, @Repository 모두 @Conponent를 포함하고 있다.
필요한 객체를 직접 생성하는 것이 아닌 외부에서 생성한 후 주입시켜주는 방식
이를 통해 객체 간 결합도를 줄이고 코드의 재사용성을 높일 수 있다.
의존성 주입은 생성자 주입, 필드 주입, 세터 주입의 3가지 방법이 있다.
1. 생성자 주입 - @autowired 생략 가능
@Controller
public class CocoController {
//final을 붙일 수 있음
private final CocoService cocoService;
@Controller
public class CocoController {
@Autowired
private CocoService cocoService;
}
단점
@Controller
public class CocoController {
private CocoService cocoService;
@Autowired
public void setCocoService(CocoService cocoService) {
this.cocoService = cocoService;
}
}
단점
3가지 중 생성자 주입 방법을 가장 권장한다.
1. 순환 참조를 방지할 수 있다.
개발을 하다 보면 여러 컴포넌트 간 의존성이 생겨 a,b가 있다고 할 때
a가 b를 참조하고 b가 다시 a를 참조하는 순환 참조되는 것을 방지할 수 있다.
2. 불변성
변경의 가능성을 배제하고 불변성을 보장하는 것이 좋다.
3. 테스트에 용이하다.
생성자 주입을 통해 코드를 더 편리하게 작성할 수 있다.
그리고 생성자 주입은 객체의 생성과 의존관계 주입이 동시에 일어난다.
스프링 빈의 라이프사이클
스프링 IoC 컨테이너 생성 -> 스프링 빈 생성 -> 의존관계 주입 -> 초기화 콜백 메소드 호출 -> 소멸 전 콜백 메소드 호출 -> 스프링 종료
스프링은 크게 3가지 방법으로 빈 생명주기 콜백을 관리한다
1. 인터페이스
2. 설정 정보에 초기화 메소드, 종료 메소드 지정
3. @PostConstruct, @PreDestroy 어노테이션 지원
(참고 : https://dev-coco.tistory.com/170)
필터
말 그대로 요청과 응답을 거른 뒤 정체하는 역할
스프링 컨테이너가 아닌 톰캣과 같은 웹 컨테이너에 의해 관리가 되는 것이고 스프링 범위 밖에서 처리된다.
dispatcher Servlet에 요청이 전달되기 전/후에 URL 패턴에 맞는 모든 요청에 대해 부가 작업을 처리할 수 있는 기능 제공
사용 예시
인터셉터
요청에 대한 작업 전/후로 가로채 요청과 응답을 참조하거나 가공하는 역할
웹 컨테이너에서 동작하는 필터와 달리 인터셉터는 스프링 컨텍스트에서 동작
dispatcher Servlet이 Controller를 호출하기 전/후에 인터셉터가 끼어들어 요청과 응답을 참조하거나 가공할 수 있는 기능을 제공
사용 예시
AOP는 핵심 비즈니스 로직에 있는 공통 관심사항을 분리하여 각각의 모듈화 하는 것을 의미하며
공통 모듈인 인증, 로깅, 트랜잭션 처리에 용이하다.
핵심 비즈니스 로직에 부가기능을 하는 모듈이 중복되어 분포되어 있을 경우 사용할 수 있다.
AOP의 가장 큰 특징이자 장점은 중복 코드 제거, 재활용성의 극대화, 변화수용의 용이성이 좋다는 점이다.
lombok은 메소드를 컴파일 하는 과정에 개입해서 추가적인 코드를 만들어낸다.
이것을 어노테이션 프로세싱이라고 하는데
어노테이션 프로세싱은 자바 컴파일러가 컴파일 단계에서 어노테이션을 분석하고 처리하는 기법을 말한다.
클라이언트의 요청을 처리하고 그 결과를 반환하는 Servlet 클래스의 구현 규칙을 지킨 자바 웹 프로그래밍 기술이다.
spring MVC에서 Controller로 이용되며 사용자의 요청을 받아 처리한 후 결과를 반환한다
간단히 말하자면 자바를 사용해 웹을 만들기 위해 필요한 기술이다
서블릿 동작 방식
VO (Value Object) - 실제 데이터만을 저장하는 객체
BO (Business Object) - 여러 DAO를 활용해 비즈니스 로직을 처리하는 객체 (서비스에 해당)
DAO (Data Access Object) - DB의 데이터에 접근을 위한 객체 (Repository 또는 mapper에 해당)
DTO (Data Transfer Object) - 각 계층 간의 데이터 교환을 위한 객체 (Controller, View, Business Layer, Persistent Layer)
객체의 인스턴스를 단 하나만 생성하는 것을 말한다.
스프링에서 bean 생성 시 별다른 설정이 없으면 default로 싱글톤이 적용
스프링 컨테이너를 통해 직접 싱글톤 객체를 생성하고 관리하는데
요청이 들어올 때마다 객체를 생성하지 않고 이미 만들어진 객체를 공유하기 때문에
효율적인 사용이 가능하다.
프로토타입 빈은 싱글톤 빈과 달리 컨네이터에게 빈을 요청할 때마다 매번 새로운 객체를 생성하여 반환해준다.
빈의 scope 설정은 @Scope 어노테이션으로 설정하며 프로토타입 scope로 설정하려면 @Scope("prototype")와 같이 문자열로 지정해주면 된다.
@Transactional을 메소드 또는 클래스에 명시하면 AOP를 통해 Target이 상속하고 있는 인터페이스 또는 Target 객체를 상속한 Proxy 객체가 생성되며, Proxy 객체의 메소드를 호출하면 Target 메소드 전 후로 트랜잭션 처리를 수행한다.