9주차 회고록
1) 9주차를 시작하며
이번 주는 스프링 웹 애플리케이션의 기반을 전반적으로 다졌다. DI와 빈 관리, AOP를 정리하고 스프링 MVC의 요청 매핑과 핸들러 메서드, 뷰 리졸버, 예외 처리, 인터셉터까지 흐름을 연결했다. 데이터 접근에서는 MyBatis 설정과 동적 쿼리를 실습했다.
피우다 프로젝트는 개발에 착수했고 마이페이지 기능을 진행 중이다. 백엔드 팀이 확정되었고 팀명은 ADHD이며 주제는 광고 모음 사이트로 정했다. 두 프로젝트를 동시에 진행하면서 일정 분배가 쉽지 않았다.
2) 학습 요약
2-1) DI와 DI 애노테이션
- 의존성 주입 방식 정리: 생성자 주입 중심, 필요 시 필드 주입 지양
- 구성 방법 비교: 컴포넌트 스캔과 자바 설정 병행, 외부 라이브러리는 @Bean으로 수동 등록
- 빈 충돌 대응: @Primary와 @Qualifier로 명시적 선택
- 생명주기 콜백과 후처리기 개념 확인
2-2) Bean
- 스코프 이해: singleton 기본, prototype은 컨테이너 관리 범위 제한
- 초기화와 소멸 콜백 정리
- 빈 이름 규칙과 등록 위치 점검
2-3) AOP
- 핵심 개념: Aspect, Pointcut, Advice, JoinPoint
- Advice 유형: Before, After, AfterReturning, AfterThrowing, Around
- 적용 사례: 트랜잭션 경계, 로깅, 성능 측정
- 프록시 기반 동작과 자기 호출 시 미적용 이슈 주의
2-4) Request Mapping
- @RequestMapping과 세부 단축 애노테이션 정리
- 클래스 레벨 매핑과 메서드 레벨 매핑 조합
- PathVariable, params, consumes, produces 활용
- RedirectAttributes로 PRG 플로우에서 메시지 전달
2-5) Handler Method
- WebRequest, HttpServletRequest 사용
- @RequestParam 단일 값과 Map 바인딩, defaultValue로 파싱 오류 방지
- @ModelAttribute 커맨드 객체 바인딩 규칙
- HttpSession, @SessionAttributes, SessionStatus 활용
- @RequestBody, @RequestHeader, @CookieValue 처리
2-6) View Resolver
- ThymeleafViewResolver prefix와 suffix
- 문자열 뷰 이름과 ModelAndView 반환 비교
- redirect 접두어와 flash 속성 전달 패턴
2-7) Exception Handler
- 컨트롤러 단위 @ExceptionHandler
- 전역 @ControllerAdvice 구성
- ResponseStatusExceptionResolver, SimpleMappingExceptionResolver 개념 확인
- 기본 예외 페이지와 사용자 정의 응답 분리
2-8) Interceptor
- HandlerInterceptor의 preHandle, postHandle, afterCompletion 흐름
- WebMvcConfigurer로 등록, 정적 리소스와 에러 경로 제외
- 수행 시간 측정과 공통 파이프라인 구성
2-9) MyBatis Configuration
- Environment와 Configuration 구성
- SqlSessionFactory와 SqlSession 스코프 전략
- XML 설정 태그 정리: properties, settings, typeAliases, environments, mappers
- 캐시 기본 동작과 주의점
2-10) MyBatis Dynamic Query
- XML 태그: if, choose, trim where set, foreach, bind
- where와 set로 불완전 SQL 방지
- Provider 기반 동적 쿼리와 @Param 사용 규칙
3) 문제와 해결
-
빈 충돌
- 증상: 동일 타입 빈 주입 시 중복 매칭
- 해결: @Primary 기본 지정 후 예외 케이스는 @Qualifier로 선택
-
AOP 미적용 구간
- 증상: 내부 메서드 호출에서 어드바이스가 적용되지 않음
- 해결: 역할 분리로 외부 빈을 통해 호출하거나 호출 경로 변경
-
파라미터 바인딩 오류
- 증상: 요청 파라미터 이름 불일치로 400 발생
- 해결: 폼 name과 핸들러 매개변수 일치, 필요 시 @RequestParam 이름 지정과 defaultValue 사용
-
인터셉터와 리다이렉트 동작
- 증상: redirect 경로에서 ModelAndView가 null
- 해결: postHandle에서 null 체크, 메시지는 RedirectAttributes로 전달
-
MyBatis 동적 쿼리 예외
- 증상: 빈 리스트로 foreach 생성 시 구문 오류
- 해결: 서비스 단에서 빈 컬렉션 분기 처리, 조건이 없으면 조회를 수행하지 않도록 방어 로직 추가
4) 느낀 점
- DI와 빈 관리가 정리되니 객체 연결과 생명주기 제어가 일관적이다.
- AOP로 횡단 관심사를 분리하니 로깅과 성능 측정이 코드에 섞이지 않는다.
- 요청 매핑부터 예외 처리까지 스프링 MVC 흐름을 단계별로 따라가니 디버깅이 수월하다.
- 동적 쿼리 태그와 Provider를 적절히 섞으면 SQL 분기 코드가 간결해진다.
- 피우다와 백엔드 프로젝트를 병행하며 시간 관리를 철저히 하는것이 중요하다고 느꼈다.
5) 다음 주 계획
-
피우다 마이페이지 완성
- 회원 정보 조회와 수정
- 비밀번호 변경과 세션 연동
- Vue.js 를 활용해서 프론트엔드 구현하기
-
백엔드 ADHD 프로젝트
- 요구사항 명세 초안과 페이지 플로우 작성
- ERD와 핵심 API 정의
- 팀원들과 서로의 담당 역할(기능) 정하기
-
김영한 스프링 MVC 강의 듣기
두 프로젝트를 병행하면서 시간 분배가 가장 큰 과제로 보인다. 작업 단위를 더 잘게 나누고 우선순위를 명확히 하며 진행 속도를 유지해 보겠다.
다음주 부터는 두 개의 프로젝트가 본격적으로 개발에 들어갈 것 같아서 더욱 바빠질 것 같다.
목표로 김영한 MVC 강의를 적어두긴 했는데 가능할지는 모르겠다...