본문 바로가기

Spring

(38)
[Spring DB] 트랜잭션 AOP 주의 사항 - 프록시 내부 호출 문제 파악 및 해결 📌 학습 목차1. 프록시 방식 AOP의 한계2-1. 프록시를 통한 실제 객체 호출2-2. 내부 호출을 통한 실제 객체 호출3. 클래스 분리를 통한 해결1. 프록시 방식 AOP의 한계•트랜잭션 처리가 필요한 위치에 @Transactional 애노테이션을 사용할 경우,    스프링의 트랜잭션 AOP가 적용되고 트랜잭션 AOP는 프록시를 통해 트랜잭션을 적용함   이에 프록시를 거치지 않고 내부 호출로 실제 객체(Target)를 직접 호출할 경우, 프록시가 적용되지 않아 트랜잭션 또한 적용되지 않음2-1. 프록시를 통한 실제 객체 호출 •CallService의 internal()에 @Transactional 애노테이션을 사용함에 따라 스프링의 트랜잭션 AOP가 적용됨   이에 스프링은 실제 객체(Target..
[Spring DB] 트랜잭션 AOP 적용 흐름 📌 학습 목차1. 트랜잭션 AOP 적용 - 설정 정보2. 트랜잭션 AOP 적용 흐름1. 트랜잭션 AOP 적용 - 설정 정보•트랜잭션 AOP를 적용하기 위한 데이터 소스(DriverManagerDataSource)와    트랜잭션 매니저(DataSourceTransactionManager)를 직접 스프링 빈으로 등록함 spring.datasource.url=jdbc:h2:tcp://localhost/~/testspring.datasource.username=saspring.datasource.password= @TestConfigurationstatic class TestConfig { @Bean DataSource dataSource() { return new DriverMana..
[Spring DB] 트랜잭션 문제 해결4 - 트랜잭션 AOP 📌 학습 목차1. 트랜잭션 AOP의 필요성2-1. 스프링의 트랜잭션 AOP 이해2-2. 스프링의 트랜잭션 AOP 적용1. 트랜잭션 AOP의 필요성•서비스 계층을 순수하게 유지하기 위해 스프링의 트랜잭션 추상화, 트랜잭션 동기화, 트랜잭션 탬플릿을 통해 기존 여러 문제를 개선함   (1) 트랜잭션 추상화: 서비스 계층이 추상화된 트랜잭션 매니저에 의존함에 따라 데이터 접근 기술 변경에 대한 영향 범위를 최소화 함   (2) 트랜잭션 동기화: 트랜잭션 매니저는 트랜잭션 동기화 매니저를 통해 트랜잭션을 사용하는 동안 같은 리소스(커넥션)를 유지함   (3) 트랜잭션 탬플릿: 트랜잭션 탬플릿을 통해 서비스 계층에서 트랜잭션을 사용하기 위해 반복되는 로직 코드를 모두 제거함 •서비스 측면에서 애플리케이션을 구성..
[Spring DB] 트랜잭션 문제 해결3 - 트랜잭션 템플릿 📌 학습 목차1. 트랜잭션 템플릿의 필요성2. 스프링의 트랜잭션 템플릿1. 트랜잭션 템플릿의 필요성•현재 서비스 계층에서 트랜잭션을 사용하기 위한 로직은   트랜잭션을 시작하고 비즈니스 로직 실행 성공 여부에 따라 트랜잭션을 커밋 또는 롤백하는 패턴을 가짐   이에 다른 서비스 계층에서 트랜잭션을 사용할 경우,    각 서비스마다 비즈니스 로직은 서로 다르나 트랜잭션을 사용하기 위한 로직은 매번 반복됨 MemberServiceV3_1 - 트랜잭션 템플릿 사용 전•서비스 계층에서 트랜잭션을 사용하기 위한 로직 패턴을 가짐 @RequiredArgsConstructorpublic class MemberServiceV3_1 { private final PlatformTransactionManager tr..
[Spring DB] 트랜잭션 매니저 동작 흐름 📌 학습 목차1. 트랜잭션 매니저 동작 흐름 - 초기화 코드2. 트랜잭션 매니저 동작 흐름 - 트랜잭션 시작3. 트랜잭션 매니저 동작 흐름 - 비즈니스 로직 실행4. 트랜잭션 매니저 동작 흐름 - 트랜잭션 종료1. 트랜잭션 매니저 동작 흐름 - 초기화 코드•new DriverManagerDataSource(URL, USERNAME, PASSWORD):   커넥션 풀을 사용하지 않고 JDBC 드라이버를 통해 매번 새로운 커넥션을 생성하는 DriverManagerDataSource를 생성함•new DataSourceTransactionManager(dataSource):   DriverManagerDataSource를 기반으로 트랜잭션을 관리하는 DataSourceTransactionManager를 생성함..
[Spring DB] 트랜잭션 문제 해결2 - 트랜잭션 매니저(트랜잭션 동기화) 📌 학습 목차1. 트랜잭션 동기화의 필요성2. 스프링의 트랜잭션 동기화1. 트랜잭션 동기화의 필요성•애플리케이션에 DB 트랜잭션을 적용하는 경우, 트랜잭션을 유지하는 동안 같은 커넥션을 사용해야 같은 세션을 사용할 수 있음•현재 서비스 계층의 경우, 같은 커넥션을 사용하기 위해 단순히 트랜잭션이 시작된 커넥션을 전달해 비즈니스 로직을 실행함   이에 순수하게 유지되어야 할 서비스 계층의 코드가 매우 복잡해져 유지보수가 어려움 1) MemberServiceV2•bizLogic(con, fromId, toId, money):   트랜잭션을 시작한 서비스 계층은 트랜잭션이 시작된 커넥션(con)을 사용해 비즈니스 로직을 실행함 @RequiredArgsConstructorpublic class MemberSe..
[Spring DB] 트랜잭션 문제 해결1 - 트랜잭션 매니저(트랜잭션 추상화) 📌 학습 목차1. 트랜잭션 추상화의 필요성2. 스프링의 트랜잭션 추상화1. 트랜잭션 추상화의 필요성 •트랜잭션을 사용하는 방법은 데이터 접근 계층의 데이터 접근 기술마다 다름   예시) JDBC: con.setAutoCommit(false) / JPA: transaction.begin()•현재 서비스 계층의 경우, 원자적 단위로 비즈니스 로직을 처리하기 위해 트랜잭션을 사용할 때 JDBC 트랜잭션 기술에 의존함   이에 향후 데이터 접근 기술이 변경될 때마다 서비스 계층 내 트랜잭션 관련 코드도 함께 수정해야 함 @RequiredArgsConstructorpublic class MemberServiceV2 { private final DataSource dataSource; private f..
[Spring DB] 순수한 서비스 계층 / 단순 트랜잭션 적용에 따른 문제 📌 학습 목차1. 애플리케이션 구조 - 순수한 서비스 계층2. 단순 트랜잭션 적용에 따른 문제점1. 애플리케이션 구조 - 순수한 서비스 계층 •애플리케이션 구조는 일반적으로 프레젠테이션, 서비스, 데이터 접근의 총 3가지 계층으로 구분함   이때 애플리케이션 구조를 3가지 계층으로 구분한 이유는 핵심 비즈니스 로직이 있는 서비스 계층을 최대한 순수하게 유지하기 위함임•서비스 계층을 순수하게 유지할 경우, 유지보수와 테스트가 용이하고 향후 구현 기술을 변경하더라도 영향 범위를 최소화할 수 있음   이에 기술에 종속적인 부분은 프레젠테이션 및 데이터 접근 계층에서 처리하고,    서비스 계층은 특정 구현 기술에 의존하지 않도록 개발해야 함2. 단순 트랜잭션 적용에 따른 문제•MemberServiceV2 &..
[Spring DB] 트랜잭션의 이해 / DB 락의 이해 및 사용 📌 학습 목차1. 트랜잭션의 이해2-1. DB 락의 이해2-2. DB 락 사용1. 트랜잭션의 이해1-1) 트랜잭션 개념•데이터를 DB에 저장하는 대표적인 이유는 DB에서 트랜잭션(transaction)이라는 개념을 지원하기 때문임•트랜잭션은 ACID를 기반으로 DB에서 실행되는 여러 작업을 하나의 작업으로 처리해 하나의 거래가 안전하게 처리될 수 있도록 보장함   예시) 계좌이체 거래의 경우, 트랜잭션 내에서 A 계좌 잔고가 감소하고 B 계좌 잔고가 추가되는 2개의 작업이 하나의 작업으로 처리됨•트랜잭션 내에서 실행한 여러 작업이 모두 성공적으로 DB에 정상 반영되는 것을 커밋(commit)이라고 함   커밋을 호출하기 전까진 임시로 데이터를 저장하는 것과 같으며, 해당 트랜잭션을 시작한 세션(사용자)..
[Spring DB] 커넥션 풀 & DataSource의 이해 / DataSource를 통한 커넥션 획득 📌 학습 목차1. 커넥션 풀의 이해2. DataSource의 이해3-1. DataSource를 통한 커넥션 획득 - DriverManager3-2. DataSource를 통한 커넥션 획득 - 커넥션 풀1. 커넥션 풀의 이해1) 커넥션의 필요성•DB 커넥션을 획득할 경우, 다음과 같은 복잡한 과정을 거침   (1) 애플리케이션 로직은 사용자 요청에 따라 DB 드라이버를 통해 커넥션을 조회함   (2) DB 드라이버는 DB와 TCP/IP 커넥션을 연결함   (3) TCP/IP 커넥션이 연결된 후, DB 드라이버는 ID와 비밀번호 등의 정보를 DB에 전달함   (4) DB는 ID와 비밀번호를 통해 내부 인증을 완료하고, 내부에 DB 세션을 생성함   (5) DB는 DB 드라이버에 커넥션 생성이 완료되었다는 ..
[Spring DB] JDBC의 이해 / DriverManager를 통한 커넥션 획득 📌 학습 목차1. JDBC의 이해2. DriverManager를 통한 커넥션 획득1. JDBC의 이해1) JDBC의 필요성•클라이언트가 애플리케이션 서버를 통해 데이터를 저장하거나 조회할 경우,   애플리케이션 서버는 일반적으로 다음 과정을 통해 DB를 사용함    (1) 커넥션 연결: 주로 TCP/IP를 사용해 DB와 커넥션을 연결함   (2) SQL 전달: 연결된 커넥션을 통해 SQL을 DB에 전달함     (3) 결과 응답: DB는 전달받은 SQL을 수행해 결과를 응답하고, 애플리케이션 서버는 해당 결과를 활용함  •이때 수십 개의 DB 종류마다 커넥션 연결, SQL 전달, 결과 응답 방법이 모두 달라 다음과 같은 문제가 발생함   (1) DB 종류를 변경할 때마다 애플리케이션 서버의 DB 사용 ..
[Spring MVC] MVC 구조4-2 - HTTP 메시지 컨버터 📌 학습 목차1. HttpMessageConverter 구조 및 동작 방식2. HttpMessageConverter 동작 예시1. HttpMessageConverter 구조 및 동작 방식1) HttpMessageConverter 구조•ArgumentResolver와 ReturnValueHandler는 다음 경우에   HTTP 메시지 컨버터(HttpMessageConverter)를 사용해 HTTP 요청 및 응답 메시지 바디의 데이터를 처리함   (1) HTTP 요청 시 @RequestBody 또는 HttpEntity(RequestEntity)를 사용할 경우   (2) HTTP 응답 시 @ResponseBody 또는 HttpEntity(ResponseEntity)를 사용할 경우 •스프링 부트는 기본 Htt..
[Spring MVC] MVC 구조4-1 - 요청 매핑 핸들러 어댑터 📌 학습 목차1. RequestMappingHandlerAdapter2-1. ArgumentResolver 구조 및 동작 방식2-2. ReturnValueHandler 구조 및 동작 방식3. ArgumentResolver & ReturnValueHandler 동작 예시1. RequestMappingHandlerAdapter•애노테이션 기반 컨트롤러(핸들러)를 처리하는 요청 매핑 핸들러 어댑터(RequestMappingHandlerAdapter)는   ArgumentResolver와 ReturnValueHandler를 사용해 HTTP 요청 및 응답 데이터를 처리함   이때 HTTP 요청 및 응답 메시지 바디의 데이터를 처리할 때 사용되는 HTTP 메시지 컨버터(HttpMessageConverter)는  ..
[Spring MVC] HTTP 응답 - 정적 리소스 / 뷰 템플릿 / HTTP API 📌 학습 목차1. HTTP 응답2-1. 정적 리소스2-2. 뷰 템플릿2-3. HTTP API1. HTTP 응답•서버에서 HTTP 응답 데이터를 만드는 경우는 다음 3가지로 구분됨   (1) 정적 리소스(HTML, CSS 등)를 제공하는 경우   (2) 템플릿 엔진으로 뷰 템플릿을 렌더링해 동적 HTML을 제공하는 경우     (3) HTTP API를 통해 HTTP 응답 메시지 바디에 데이터를 담아 제공하는 경우2-1. 정적 리소스•스프링 부트는 클래스 패스의 시작 경로(src/main/resources) 내   /static , /public , /resources ,/META-INF/resources 디렉토리에 있는 정적 리소스를 제공함   예시) 웹 브라우저에서 http://localhost:808..
[Spring MVC] HTTP 요청 메시지 - Text / JSON 📌 학습 목차1. HTTP 요청 메시지2-1. Text2-2. JSON1. HTTP 요청 메시지•HTTP 요청 메시지 바디에 데이터를 직접 담아 클라이언트에서 서버로 전달하는 방식은   주로 HTTP API에서 JSON 형식으로 POST, PUT, PATCH와 같은 HTTP 메서드와 함께 사용됨   이때 서블릿과 스프링으로 요청 메시지 바디의 데이터를 조회하는 방법을 단계적으로 학습하고자 함 •요청 파라미터를 조회할 때 @RequestParam 또는 @ModelAttribute가 생략된 경우, 스프링은 다음 규칙을 적용함   (1) 메서드 파라미터 타입이 단순 타입(int, Integer, String 등)일 경우, @RequestParam이 생략된 것으로 간주함   (2) 메서드 파라미터 타입이 단순..
[Spring MVC] HTTP 요청 파라미터 - 쿼리 파라미터 / HTML Form 📌 학습 목차1. HTTP 요청 파라미터2-1. @RequestParam2-2. @ModelAttribute1. HTTP 요청 파라미터•HTTP 요청 메시지를 통해 클라이언트에서 서버로 데이터를 전달하는 방식은 다음 3가지로 구분됨   (1) GET 쿼리 파라미터: URL의 쿼리 파라미터에 데이터를 담아 전달하는 방식   (2) POST HTML Form: 메시지 바디에 쿼리 파라미터 형식의 데이터를 담아 전달하는 방식   (3) 메시지 바디에 데이터를 직접 담아 전달하는 방식•서버 입장에서 GET 쿼리 파라미터 방식과 POST HTML Form 방식으로 전달되는 데이터 형식이 동일함   이때 두 방식으로 전달되는 데이터를 조회하는 것을 요청 파라미터(request parameter) 조회라고 함2-1..
[Spring MVC] MVC 구조3 - 애노테이션 기반 스프링 MVC 컨트롤러 사용 📌 학습 목차1. 스프링 MVC 시작(V1)2-1. 리펙터링1(V2)2-2. 리펙터링2(V3)1. 스프링 MVC 시작(V1)•스프링은 @RequestMapping 애노테이션을 기반으로 동작하는 매우 유연하고 실용적인 컨트롤러를 제공함•@RequestMapping 애노테이션 기반 컨트롤러를 지원하는 핸들러 매핑과 핸들러 어댑터는   RequestMappingHandlerMapping과 RequestMappingHandlerAdapter에 해당함   1) @Controller 사용•@Controller 애노테이션은 코드 내부에 @Component 애노테이션을 포함함   이에 @Controller을 사용한 클래스는 스프링의 컴포넌트 스캔 대상이 되어 스프링 빈으로 자동 등록됨•@Controller을 사용한 ..
[Spring MVC] MVC 구조2 - 핸들러 매핑 & 핸들러 어댑터 / 뷰 리졸버 📌 학습 목차1-1. 핸들러 매핑 & 핸들러 어댑터1-2. Controller1-3. HttpRequestHandler2. 뷰 리졸버1-1. 핸들러 매핑 & 핸들러 어댑터•핸들러(컨트롤러)가 호출되기 위해선 핸들러를 찾을 수 있는 핸들러 매핑과 해당 핸들러를 실행할 수 있는 핸들러 어댑터가 필요함•스프링 부트는 기본 핸들러 매핑과 핸들러 어댑터를 우선순위에 따라 자동 등록함   핸들러 매핑: RequestMappingHandlerMapping / BeanNameUrlHandlerMapping 등   핸들러 어댑터: RequestMappingHandlerAdapter / HttpRequestHandlerAdapter / SimpleControllerHandlerAdapter 등•애노테이션 기반 컨트롤러를..
[Spring MVC] MVC 구조1 - 디스패처 서블릿 / doDispatch() 동작 흐름 📌 학습 목차1. 스프링 MVC 구조2. 디스패처 서블릿 구조1. 스프링 MVC 구조•직접 구현한 MVC 프레임워크의 구조와 서블릿을 기반으로 동작하는 MVC 프레임워크인 스프링 MVC의 구조가 동일함   이때 스프링 MVC의 핵심인 DispatcherServlet이 프론트 컨트롤러 패턴으로 구현됨을 알 수 있음•스프링 MVC의 강점은 DispatcherServlet의 코드 변경 없이 주요 인터페이스를 구현해 원하는 기능으로 변경하거나 확장할 수 있음   org.springframework.web.servlet.HandlerMapping, HandlerAdapter, ViewResolver, View 1) 직접 구현한 MVC 프레임워크 구조  2) 스프링 MVC 구조 2. 디스패처 서블릿 구조1) 서블..
[Spring MVC] MVC 프레임워크 만들기3 - 핸들러 어댑터 도입 & 추가(V5) 📌 학습 목차1. 핸들러 어댑터 도입(V5-1)2. 핸들러 어댑터 추가(V5-2)1. 핸들러 어댑터 도입(V5-1)•V4까지 개발한 프론트 컨트롤러는 한 가지 방식의 컨트롤러 인터페이스만 사용할 수 있음   이에 호환되지 않는 인터페이스들을 연결하기 위해 어댑터 패턴(adapter pattern)을 적용하여   프론트 컨트롤러가 특정 인터페이스에 종속되지 않고 다양한 종류의 컨트롤러를 호출할 수 있도록 변경함•어댑터를 사용할 경우, 컨트롤러뿐만 아니라 어떠한 것이라도 해당 종류를 지원하는 어댑터만 있으면 처리할 수 있음   이에 기존 컨트롤러의 이름을 더 넓은 범위의 핸들러로 변경함  1-1) MyHandlerAdapter•핸들러를 실행할 수 있는지 여부를 확인하는 supports()와    실제 핸들..