
@Component
스프링이 컴포넌트 스캔으로 자동 등록하는 일반 빈(Bean) 표시. 특별한 역할 구분이 필요 없을 때 기본으로 사용.
@Service
비즈니스 로직(서비스 계층) 컴포넌트임을 나타내는 @Component의 특화. 기능적으로는 빈 등록이 동일하지만, 계층/의도 표현에 유리.
@Controller
MVC 웹 계층에서 요청을 처리하는 컨트롤러를 나타내는 @Component의 특화. 주로 View를 반환(또는 @ResponseBody와 함께 데이터 반환).
@RestController
@Controller + @ResponseBody로, 메서드 반환값을 뷰가 아닌 HTTP 응답 바디(JSON 등) 로 바로 내려주는 REST API 컨트롤러 표시.
@Mapper
MyBatis에서 SQL 매핑 인터페이스(DAO 역할) 를 스프링 빈으로 등록하기 위한 표시. 매퍼 스캔을 통해 구현체(프록시)가 자동 생성되어 주입 가능.
@Repository
데이터 접근 계층(DAO/Repository) 컴포넌트임을 나타내는 @Component의 특화. DB 예외를 스프링의 DataAccessException 계열로 변환(예외 변환)해주는 역할도 가짐.
@ Configuration
@Bean 정의를 모아 스프링 컨테이너에 “설정대로” 빈을 등록하는 설정 클래스 표시입니다.**
@Autowired@RequiredArgsConstructor (Lombok)final 또는 @NonNull 필드만을 인자로 받는 생성자를 자동 생성. 스프링에서 생성자 주입과 함께 쓰면 보일러플레이트를 줄임.@Inject (JSR-330)@Autowired와 유사한 표준 DI 어노테이션. 스프링에서도 지원. 보통 타입 기준으로 주입되며, 선택적 의존성/필수 여부 등 세부 옵션은 스프링 어노테이션이 더 풍부한 편.@Resource (JSR-250)@Resource(name="beanName")처럼 빈 이름을 지정해 주입 대상을 명확히 할 때 유용.@Qualifier@Autowired와 함께 주입할 빈을 식별하는 용도. 예: @Qualifier("mainDataSource"). (참고: 노트에 @Qulifier로 적혀 있는데 올바른 철자는 @Qualifier.)@RequestMapping (class level)@RequestMapping("/api/users")를 클래스에 붙이면, 아래 메서드 매핑은 /api/users/... 아래로 묶임.@RequestMapping (method level)method 속성으로 GET/POST/... 등을 지정할 수 있음.@RequestMapping(value="/{id}", method=RequestMethod.GET)@GetMapping / @PostMapping / @PutMapping / @PatchMapping / @DeleteMapping@RequestMapping(method=...)의 축약형(sugar). 가독성이 좋아서 실무에서는 보통 이 매핑들을 주로 사용.@GetMapping("/{id}"), @PostMapping(""){id} 같은 값을 파라미터로 받기 위해 @PathVariable을 사용. 예: getUser(@PathVariable Long id)?page=1 같은 값을 받기 위해 @RequestParam을 사용.@RequestMapping을 포함한 매핑 어노테이션을 분석해 어떤 컨트롤러 메서드가 어떤 요청을 처리할지 DispatcherServlet의 라우팅(HandlerMapping) 단계에서 결정함.@GetMapping, @PostMapping은 메서드 레벨 @RequestMapping을 더 명확하고 짧게 쓴 “전용(축약) 매핑 애노테이션”입니다. 즉, “메서드 레벨 요청 매핑”이라는 큰 범주 안에 들어가고, 내부적으로는 결국 @RequestMapping으로 해석됩니다.

지난 수업처럼 서버 포트와 XML 매퍼 경로 챙겨놓기

dto (Data Transfer Object):
vo (Value Object): 데이터베이스 테이블과 1:1로 매핑되는 순수한 회원 엔티티(Entity) 데이터 모델 구조를 담음
🔄 한눈에 보는 데이터 흐름 (Mechanism)
[1. 웹 브라우저 / 리액트]
↓ (로그인 요청: 이메일, 패스워드)
[2. UserController] <-- UserRequestDTO 바구니에 데이터를 담아 접수!
↓
[3. UserService] <-- 비밀번호 암호화 및 비즈니스 로직 검증 판단!
↓
[4. UserMapper] <-- 데이터베이스에 회원이 있는지 쿼리 요청!
↓
[5. MariaDB (DB)]
CorsConfig 부분
프론트엔드에서 보낸 로그인 데이터 (이메일, 패스워드)를 백엔드 MyBatis DB 조회 쿼리에 안전하게 매핑해주는 파라미터 규격 역할을 함.

react 회원가입 부분과

Controller에서 연결해주면




회원가입 정보가 DB로 들어온다!
+) XML 연동은 지난 시간에 했던 과정을 동일하게 거치면 된다.

이런 페이지를 만들어서 API 명세서 처럼 생각하면 될 듯 하다.
package com.inspire.lgcns_mybatis.features.user.ctrl;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.inspire.lgcns_mybatis.features.user.domain.dto.UserRequestDTO;
import com.inspire.lgcns_mybatis.features.user.domain.dto.UserResponseDTO;
import com.inspire.lgcns_mybatis.features.user.service.UserService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import java.util.Map;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
/*
Controller 의 역할
- 파라미터를 DTO로 바인딩 해서 데이터의 유효성을 체크
- 서비스 레이어의 의존성을 가짐
- ResponseEntity 통해서 데이터 및 상태 코드를 전달
*/
@Tag(name = "User API", description = "사용자 생성 및 로그인 관련 API 명세서")
@RestController
@RequestMapping("/user")
@RequiredArgsConstructor
public class UserController {
private final UserService userService;
@Operation(
summary = "회원가입",
tags = {"User API"},
responses = {
@ApiResponse(responseCode = "201", description = "가입성공"),
@ApiResponse(responseCode = "500", description = "가입실패")
}
)
@PostMapping("/signUp")
public ResponseEntity<Void> signUp(
@io.swagger.v3.oas.annotations.parameters.RequestBody(
description = "사용자 가입정보를 담는 DTO",
required = true,
content = @Content(
schema = @Schema(implementation = UserRequestDTO.class)
))
@RequestBody UserRequestDTO request) {
//TODO: process POST request
System.out.println(">>> debug user controller signUp");
System.out.println(" >>> debug params :" + request);
int insertFlag = userService.signUp(request);
if (insertFlag != 0){
return ResponseEntity.status(HttpStatus.CREATED).build();
} else {
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
}
}
@Operation(
summary = "로그인",
description = "사용자 로그인(email,password)",
tags = {"User API"},
responses = {
@ApiResponse(responseCode = "200", description = "로그인성공"),
@ApiResponse(responseCode = "400", description = "로그인실패")
}
)
@PostMapping("/signIn")
/*
- json web Token
- 인증 : 너 누귀야 ? 인가 : 너에게 권한을 줄게
*/
public ResponseEntity<UserResponseDTO> signIn(@RequestBody UserRequestDTO request) {
System.out.println(">>> debug user controller signIn");
System.out.println(" >>> debug params :" + request);
Map<String,Object> map = userService.signIn(request);
HttpHeaders headers = new HttpHeaders();
headers.add("Authorization", (String)(map.get("at")));
headers.add("Refresh-Token", (String)(map.get("rt")));
headers.add("Access-Control-Expose-Headers", "Authorization, Refresh-Token");
return ResponseEntity
.status(HttpStatus.OK)
.headers(headers)
.body((UserResponseDTO)(map.get("data")));
}
}
여기서

빨간박스 내용들이 Swagger Code다
사후평가가 얼마 안 남았다...
진짜 달려야해 ㅜㅜ