스프링 전체흐름
1.서버 시작 시:
- 스프링 부트 애플리케이션을 실행하거나 Tomcat 같은 서블릿 컨테이너에 배포하면 서버가 초기화 과정을 시작합니다.
2. 스프링 부트 애플리케이션 초기화
- Spring Boot의 가장 중요한 특징은 애플리케이션이 실행 시 자동으로 필요한 Bean과 설정을 구성해주는 것
- SpringApplication.run(): main() 메서드에서 호출되며, 스프링 애플리케이션의 전체 구동을 시작합니다.
- 스프링 부트 자동 구성(Auto-Configuration) :
- SpringApplication.run()이 호출되면 스프링 부트는 애플리케이션의 설정값을 로드합니다. 이때 application.yml이 읽혀지며, 설정값이 자동 구성(Auto-Configuration) 과정에 활용됩니다.
- 클래스패스 설정, 등록된 빈(bean), 그리고 다양한 프로퍼티 설정에 따라 애플리케이션 컨텍스트(ApplicationContext)가 자동으로 설정됩니다.
- (1) 데이터 소스(DataSource) : Spring Boot는 클래스패스에 JDBC 또는 JPA 라이브러리가 있을 경우, 자동으로 데이터베이스 연결을 구성합니다.
- (2) 서버(Server) : Spring Boot는 내장형 Tomcat, Jetty, Undertow를 통해 애플리케이션 서버를 구성합니다.
- (3) JPA 및 Hibernate 설정 : JPA(Hibernate)와 관련된 설정은 데이터베이스 초기화, SQL 출력, 쿼리 캐싱 등과 관련 있습니다.
- (4) 로깅(Logging) : Spring Boot는 기본적으로 Logback을 사용하며, application.yml로 로깅 수준과 출력 포맷을 제어합니다.
3. WebApplicationContext 초기화
- WebApplicationContext 생성: 웹 애플리케이션에 특화된 ApplicationContext인 WebApplicationContext가 생성됩니다. 보안, MVC, 데이터 처리 등과 관련된 모든 설정이 이 WebApplicationContext에 등록됩니다.
- 빈 정의 로드: 스프링이 애플리케이션을 스캔하여 빈 정의(예: @Component, @Service, @Repository, @Controller, @Configuration)를 로드합니다.
- 보안 설정 처리 : @EnableWebSecurity 또는 @Configuration으로 정의된 보안 설정도 이 단계에서 로드되고 처리됩니다.
- 필터 체인 설정: 보안 설정의 일부로, 요청을 처리하기 위한 필터 체인(filter chain)이 구성됩니다.
4.DispatcherServlet 초기화
- DispatcherServlet 빈 생성: DispatcherServlet은 스프링의 특별한 서블릿으로, 모든 HTTP 요청을 처리하는 프론트 컨트롤러 역할을 합니다.
- URL 패턴 매핑 : 일반적으로 DispatcherServlet은 "/" URL 패턴에 매핑되어, 애플리케이션으로 들어오는 모든 요청을 처리합니다.
- 핸들러 매핑 및 기타 빈 로드 : DispatcherServlet은 WebApplicationContext에서 핸들러 매핑, 뷰 리졸버(view resolver), 기타 필요한 구성 요소를 로드합니다.
5. 요청 처리
- 서버가 HTTP 요청 수신: 클라이언트가 HTTP 요청을 보내면 서버가 이를 수신하고 DispatcherServlet으로 전달합니다.
- 필터 체인 실행 : 요청이 DispatcherServlet에 도달하기 전에, 보안 설정 단계에서 구성된 필터 체인을 통과합니다. Filter는 서블릿 컨테이너 레벨에서 작동하며, 보안, 인증, 로깅 등을 처리할 수 있습니다.
- DispatcherServlet 전달 : 필터를 통과한 후 요청은 DispatcherServlet으로 전달되어 애플리케이션의 로직을 처리합니다.
6. DispatcherServlet 내부동작
- 핸들러 매핑: @RequestMapping, @GetMapping 등의 애너테이션을 기준으로 핸들러를 검색합니다. 요청 URI에 매칭되는 핸들러 검색.
- 핸들러 어댑터 실행: 적합한 HandlerAdapter 선택 및 핸들러 실행 준비.
- 메서드 인수 처리: 핸들러 메서드의 매개변수(예: @RequestBody, @PathVariable)를 준비합니다. RequestResponseBodyMethodProcessor 같은 ArgumentResolver가 작동하여 데이터 변환을 수행합니다.
- 인터셉터 처리: 컨트롤러 호출 전에 등록된 Interceptor가 전처리 작업(preHandle)을 수행합니다.
- 컨트롤러 호출:적절히 처리된 요청 데이터가 컨트롤러 메서드로 전달됩니다.
- @RequestBody 매핑 : JSON/XML 요청 본문이 HttpMessageConverter를 사용하여 Java 객체로 변환됩니다. 변환된 객체는 Bean Validation을 거친 후 컨트롤러로 전달됩니다. 조건을 만족하지 못하면 스프링은 MethodArgumentNotValidException을 발생시킵니다.
스프링 MVC : @RequestBody 매핑 과정과정
- JSON/XML 요청 본문이 HttpMessageConverter를 사용하여 Java 객체로 변환됩니다.
- 기본적으로 Jackson 라이브러리가 사용됩니다:
- Jackson은 JSON 필드 이름과 Java 객체의 필드 이름을 매핑합니다.
- 적절한 생성자 또는 기본 생성자와 setter를 사용해 값을 설정합니다.
- 리스트(files)와 같은 컬렉션 필드는 JSON 배열을 Java의 List로 변환합니다.
- Jackson 라이브러리의 동작에 의해서 @Noargs, @Setter은 필수적이며, value에 접근하기 위해서 Getter까지 필수적임.
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.IOException;
public class Main {
public static void main(String[] args) {
ObjectMapper objectMapper = new ObjectMapper();
String jsonString = "{\"continent\":\"Asia\",\"country\":\"Korea\",\"region\":\"Seoul\",\"title\":\"Welcome\",\"content\":\"Welcome to Seoul\"}";
try {
// Deserialize JSON into an object
RequestCreateCommunity community = objectMapper.readValue(jsonString, RequestCreateCommunity.class);
System.out.println("Deserialization successful:");
System.out.println("Continent: " + community.getContinent());
System.out.println("Country: " + community.getCountry());
System.out.println("Region: " + community.getRegion());
System.out.println("Title: " + community.getTitle());
System.out.println("Content: " + community.getContent());
System.out.println("Files: " + community.getFiles()); // This will print null since 'files' is not in the JSON
} catch (IOException e) {
e.printStackTrace();
}
}
}
object.readValue() 안의 동작 ; field.set() method를 사용하기때문에 @setter은 필수적이다.
public <T> T readValue(JsonParser parser, Class<T> valueType) throws IOException {
// Create an instance of the class
T instance = instantiateClass(valueType);
// Iterate over JSON tokens
while (parser.nextToken() != JsonToken.END_OBJECT) {
String fieldName = parser.getCurrentName();
parser.nextToken(); // Move to value
// Find matching field or setter
Field field = findField(valueType, fieldName);
if (field != null) {
Object value = parseValue(parser, field.getType());
// Inject value directly if accessible
if (isAccessible(field)) {
field.set(instance, value);
} else {
// Use setter if available
Method setter = findSetter(valueType, fieldName);
if (setter != null) {
setter.invoke(instance, value);
}
}
}
}
return instance;
}
스프링 MVC - 필터, 인터셉트
개념설명
웹상에서 흐르는 데이터에 공통적인 처리를 할때 필요한 것이 필터와 인터셉트이다.
필터
- 스프링 외부의 서블릿에서 제공하는 공통처리기능, dispatcher로 가기전의 client의 불필요한 request(해킹 등)를 걸러주는 역할
- 스프링 내 요청이 들어오기 전과 스프링 요청이 나갈때 처리가능
- 조금더 low-level 처리가 가능
인터셉터
- 스프링에서 제공하는 공통처리 기능
- dispatcher에서 handler mapping이 완료된 후 controller로 향하는 데이터와 controller로부터 나오는 데이터가 특정조건에 만족한다면, 특정처리가 가능하다. 하여, 실제 매핑된 Handler 정보 확인가능(어떤 것이 실제 내 요청을 처리하는지도 확인 가능)
- 조금 더 상세한 조건식과 세부적인 스펙(pre, post, after)를 통해서 구체적인 시점에 구체적인 동작가능
- AOP와 비교한다면 AOP는 좀더 java code( 패키지, annotation, method명 등)에 대한 처리를, 인터셉터와 필터는 web관련 조건에 따라(url주소 protocol 등)처리를 한다는 점에서 차이가 있다.
- AOP는 인터셉터보다 더 구체적인 조건 (애노테이션, 파라미터, 주소 등)과 동작위치 (afterThrowing 등)을 갖음
사용설명
필터사용 - filter은 서블릿 기능으로 스프링과 무관하게 동작할 수도 있지만 스프링 빈으로 등록할시 여러가지 이점이 있음. 그러므로 component로 등록한다. filter라는 인터페이스를 구현하여 자체적으로 클래스를 만들고 dofilter를 정의하여 필터링 기능을 생성한다.
필터셋등록 - 그리고 filter는 보통 복수의 필터가 있기에 , configuration이라는 별도의 class를 만들고 registerfilter라는 메소드를 생성 하고 반환타입으로 filterregisterationbean이라는 set형식으로 filter들을 set에 등록하게 끔 한다. filterregisterationbean으로 필터가 동작할 url이나 필터의 순서를 지정가능함.
인터셉트는 handlerintercept라는 인터페이스를 구현하여 만들고 prehandle(handler처리전) posthandle(hadler응답성공후) aftercompletion( handler응답성공무관,항상). 각 메소드 들은 parameter로 request, response, handler, modelandview 등을 갖는다. 각각 return true를 해주면 method들이 순서대로 실행된다. 인터셉터는 조금더 다양한 정보로, 구체적인 정보로 동작은 해줄 수 있음. filter은 요즘 잘 안쓰면서 인터셉트가 더 잘쓰이는 추세인것같음.
인터셉트를 등록하기 위해서는 WebMvcConfigurer라는 인터페이스를 구현하면 편리하게 등록할 수 있다. filter를 담고있는 configuration클래스를 구현체로 사용해서 addinterceptors 메소드를 구현하여 인터셉터의 순서, 포함할 url, 제외할 url등을 설정하면된다. WebMvcConfigurer의 메소드들은 자동적으로 bean으로 등록되도록 구현되어있다. ( 필터의 경우 spring mvc가아닌 서블릿의 개체이기때문에 별도로 서블릿으로부터 filterregisterationbean을 끌어와서 구현한 것임. )
'개발기술 > Spring' 카테고리의 다른 글
MSA도입을 위한 Spring Cloud (0) | 2024.11.04 |
---|---|
Spring 동시성이슈 해결 (0) | 2024.07.30 |
Java 프로젝트 초기 환경설정 (스프링 부트, Package, Configuration) (0) | 2024.07.23 |
스프링 MVC, 예외처리 (0) | 2024.07.18 |
스프링 부가기능 (Resource, AOP, 유효성검증, 데이터바인딩,spel) (0) | 2024.07.17 |