Ⅰ. @Slf4j
Slf4j는 인터페이스이고 그 구현체로 Logback같은 라이브러리를 선택한다. 실제 개발에서는 Spring Boot가 기본으로 제공하는 Logback을 대부분 사용한다.

System.out.println();을 사용하여 Console에 정보를 출력하지 않고, 별도의 로깅 라이브러리를 사용하여 로그를 출력한다.package com.example.springbasicannotation.controller;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
@Slf4j
@RestController
public class Slf4jController {
@RequestMapping("/logging")
public String logging() {
String sparta = "Sparta";
// TRACE -> DEBUG -> INFO -> WARN -> ERROR
log.trace("문자 trace={}", sparta);
log.debug("문자 debug={}", sparta);
// default
log.info("문자 info={}", sparta);// 문자 연산을 진행하지 않는다.
log.warn("문자 warn={}", sparta);
log.error("문자 error={}", sparta);
log.info("문자 info " + sparta); // 문자 연산을 먼저 해버린다.
return "success";
}
}
# com.example.springbasicannotation 하위 경로들의 로그 레벨을 설정한다.
logging.level.com.example.springbasicannotation=TRACE

- 출력결과

- level=TRACE

Ⅱ. @Controller VS @RestController
Annotation 기반의 Spring에서 Controller(Handler)를 만들 때 사용하는 어노테이션

@Target(ElementType.Type)@Retention(RetentionPolicy.RUNTIME)@Document@Componentpackage com.example.springbasicannotation.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class ViewController {
@RequestMapping("/view")
public String example() {
// logic
return "sparta"; // ViewName이 return
}
}
View가 있는 경우에 사용한다.
즉, Template Engine인 Thymeleaf, JSP 등을 사용하는 경우
Thymeleaf 예시
SpringBoot build.gradle 의존성 추가

main/resources/templates 가 기본 경로로 설정된다.

resources/templates/sparta.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Hello</title>
</head>
<body>
<h2>Thymeleaf Template Sample</h2>
</body>
</html>

- return 값이 String이면 `ThymeleafViewResolver` 에 의해 View Name으로 인식된다.
http://localhost:8080/view


package com.example.springbasicannotation.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class ResponseController {
@RequestMapping("/string")
public String example() {
// logic
return "sparta"; // ViewName이 return 되는게 아니라, String Data가 반환된다.
}
}
응답할 Data가 있는 경우에 사용한다.
현재는 대부분 @RestController를 사용하여 API가 만들어진다. (Restful API)
return 값으로 View를 찾는것이 아니라 HTTP Message Body에 Data를 입력한다.
View가 아닌 HTTP Message Body에 Data가 들어가는 이유는 아래에서 배울 @Responsebody와 관련이 있다.
동작 순서


@Controller에 동일한 Target이 선언되어 있는데 왜 중복으로 선언이 되어있나요?

@Target{ElementType.TYPE, ElementType.METHOD} 이지만, @RestController 은@Target(ElementType.TYPE) 이기 때문에 TYPE 범위에만 @ResponseBody가 적용된다.Ⅰ. @Component

- **Servlet의 생명주기**
- Servlet은 서블릿 컨테이너가 생성 및 관리한다.
- 즉, WAS(서블릿 컨테이너 포함)가 종료될 때 Servlet도 함께 종료된다.
- **Servlet 객체 생성시점**
- 개발자가 직접 인스턴스화 하여 사용하는것이 아닌, 코드만 작성하면 서블릿 컨테이너가 생성한다.

- 서블릿 예시 코드
@WebServlet(name="ExampleServlet", urlPatterns = "/example")
public class ExampleServlet extends HttpServlet { // HttpServlet을 상속받아 구현한다.
@Override
protected void service(
HttpServletRequest request, // HTTP 요청 정보를 쉽게 사용할 수 있게 만드는 Servlet
HttpServletResponse response // HTTP 응답 정보를 쉽게 제공할 수 있게 만드는 Servlet
) {
// application logic
}
}
@WebServlet(name="Example2Servlet", urlPatterns = "/example2")
// 위와 같은 코드
@WebServlet(name="Example3Servlet", urlPatterns = "/example3")
// 위와 같은 코드
@WebServlet(name="Example4Servlet", urlPatterns = "/example4")
// 위와 같은 코드
- **Servlet Container가 하는 일**
1. 서블릿을 초기화, 생성, 관리, 호출, 종료하는 역할을 수행
1. Servlet 객체를 `싱글톤`으로 관리한다.
2. 동시 요청에 대한 처리를 위해 `Multi Thread`를 지원한다.
<aside>
💬 Q. 싱글톤이 무엇인가요?
A. 싱글톤은 객체를 하나만 생성하여 생성된 인스턴스를 공유하여 사용하는것을 의미합니다. 특정 클래스의 인스턴스가 여러개 생성되지 않도록 하여 자원의 낭비를 방지하고, 인스턴스를 공유함으로써 상태를 일관되게 유지하기 위함입니다. 하지만, 공유 변수 사용을 주의해야 합니다.
</aside>
@IndexedⅡ. @Target

@Target 이 선언된 하위 어노테이션이 어떤 범위에 적용되는지 설정한다.
ElementType Enum 속성

Ⅲ. @Retention



Ⅳ. @Documented
