7월, 2019의 게시물 표시

@Transactional 고찰

이미지
Spring의 @Transactional은 기본적으로  AOP Proxy 를 통해 이루어 진다. 아래 그림 참조. (출처:  https://docs.spring.io/spring/docs/3.0.x/spring-framework-reference/html/transaction.html ) 중요한 점은 AOP Proxy 는 class 단위로 이루어 진다. 그러므로 아래와 같이 하나의 class 내부의 method call은 해당 class 외부의 최초 call인 addUser() 의 @Transactional 만 의미가 있고 proxyAddUser() 의 @Transactional 은 의미가 없다.(안붙인거와 같다) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 import org.springframework.beans.factory.annotation.Autowired ; import org.springframework.stereotype.Service ; import org.springframework.transaction.annotation.Transactional ; import test.jpa.demo.domain.User ; import test.jpa.demo.domain.UserData ; import test.jpa.demo.domain.UserDataRepository ; import test.jpa.demo.domain.UserRepository ; @Service public class UserService { @Autowired private UserRepository userRepository ; @Autowired private UserDataRepository userDataRepository ;

@Transactional 주의점

@Transactional은 생성된 객체의 처음 불린 method의 트랜잭션 상태를 유지한다. 동일 오브젝트 내에서 method 호출이 있을 때, 처음 호출 method에 @Transactional이 있으면 이후 호출된 메소드들도 모두 transaction 처리 되지만, 처음 호출된 method가 아닌 곳에서 @Transactional이 있을 때는 transaction 처리가 되지 않는다. 예제) POM dependency 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 <dependency> <groupId> org.springframework.boot </groupId> <artifactId> spring-boot-starter-web </artifactId> </dependency> <dependency> <groupId> org.mybatis.spring.boot </groupId> <artifactId> mybatis-spring-boot-starter </artifactId> <version> 2.1.0 </version> </dependency> <dependency> <groupId> mysql </groupId> <artifactId> mysql-connector-java </artifactId> </dependency> <dependency> <groupId>

Spring Request Interceptor

이미지
Request가 Controller에 도달하기 전에 intercept 할수 있는 방법은 두가지가 있다. Servlet Filter Spring Interceptor 차이점 Servlet Filter는 J2EE 표준 스펙이지만, Interceptor는 Spring 프레임워크에서 자체적으로 제공하는 기능이다. Servlet Filter는 Dispatcher Servlet 전에 호출되고 Interceptor는 Dispatcher와 Controller 사이에서 호출된다. 아래 그림 참조 정리하면, Request -> Servlet Filter -> Dispatcher Servlet -> Interceptor -> Controller HandlerInterceptor vs HandlerInterceptorAdapter HandlerInterceptor는 Interface이고, HandlerInterceptorAdapter는 이를 구현한 abstract class. HandlerInterceptor의 모든 interface를 구현하고 싶지 않으면 HandlerInterceptorAdapter를 사용하면 된다. HandlerInterceptor Methods PreHandle(...) Controller 직전에 실행. PostHandle(...) Controller 수행후 실행. afterComplete(...) Controller 후 view가 전상적으로 랜더링 된 후 제일 마지막에 실행. afterConcurrentHandlingStarted(...) Servlet 3.0부터 가능한 비동기 요청에서 PostHandle()과 afterCompletion() 수행하지 않고 이 메서드를 수행.(Spring에서 제공) 예제 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 2

Java Singleton Pattern

Double Checked Locking을 쓰기도 했는데... 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 public class Singleton { private volatile static Singleton instance; private Singeton () {} public static Singleton getInstance () { if (instance == null ) { synchronized (Singleton. class ) { if (instance == null ) { instance == new Singleton(); } } } return instance; } } 아래와 같이 LazyHolder를 이용한 방법이 Java 버전 상관없고 성능도 뛰어나다고 한다. 한줄씩 찬찬히 보면 왜그런지 알수 있음... 1 2 3 4 5 6 7 8 9 10 public class Singleton { private Singleton () {} public static Singleton getInstance () { return LazyHolder. INSTANCE ; } private static class LazyHolder { private static final Singleton INSTANCE = new Singleton(); } } 참고 출처:  https://medium.com/@joongwon/multi-thread-%ED%99%98%EA%B2%BD%EC%97%90%EC%84%9C%EC%9D%98-%EC%98%AC%EB%B0%94%EB%A5%B8-singleton-578d9511fd42

Linux Crontab 사용법

Position * * * * * min -> hour -> day -> month -> weekday * : any value , : value list separator - : range of values / : step values 예시) 5 4 * * * : 매일 4시 5분 마다 5 0 * 8 * : 8월달 매 0시 5분 마다 15 14 1 * * : 매달1일 14시 15분 마다 0 22 * * 1-5 : 월~금 22시 00분 마다 23 0-20/2 * * * : 0시에서 20시까지 매 2시간마다 23분에 참고:  https://crontab.guru

스프링 클라우드 - 마이크로서비스간 통신이란 (Ribbon)

이미지
스프링 클라우드 마이크로서비스간 통신에 대해 알아보자 지난 포스팅에서 서비스 발견(Service discovery)와 설정 서버(configuration Server)에 대해 알아보았다. 하지만, 이 두 설정은 단지 어플리케이션을 독립적이고 standalone하게 관리 할 수 있도록 도와주는 역할이다.   이제 내부 서비스간의 통신을 위해 HTTP 클라이언트와 클라이언트 사이드 로드밸런서를 살펴보아야 한다.  스프링 클라우드 마이크로서비스 통신에서 다루는 내용 서비스 발견을 사용하는 경우와 사용하지 않는 경우에 RestTemplate 사용해보기 Ribbon Client 커스터마이징 Feign Client에 대한 특징 ( 리본 클라이언트, 서비스 발견, 존 등과 통합 ) 스프링 클라우드 마이크로서비스 통신 다양한 스타일 마이크로 서비스간에 통신 스타일을 나눌때 2가지 척도가 있다.  동기 vs 비동기 비동기 통신에서 중요한 점은 클라이언트가 응답을 기다리는 동안 쓰레드를 Block해서는 안된다. 다음과 같은 통신에서 많이 쓰는 프로토콜이 AMQP이다.  메시지 받는 마이크로서비스의 수 ( Single message receiver vs multiple receivers ) 요청이 1:1인 경우와 요청이 1:다인 경우로 나누어진다. 해당 내용은 메시지 기반 마이크로서비스에서(TODO : link )  다시 다루겠다.  스프링 클라우드에서 동기적 통신 스프링 클라우드에는 마이크로서비스가 통신을 위해 몇가지 컴포넌트를 제공한다. 마이크로서비스 통신을 도와주는 컴포넌트 1 : RestTemplate 클라이언트가 RESTful webservice를 쓰기 위해서 사용하는 클래스이다. Spring Web 프로젝트에 포함되어 있다. 마이크로서비스 환경에서 효과적으로 사용하기 위해서는,  @ LoadBalanced  어노테이션을 사용해야 한다. 이 어노테이션 덕분에, Netflix Ribbo

JPA, Hibernate, Spring-data-jpa 개념

이미지
개념도 spring-data-jpa  default로 hibernate 사용. EclipseLink나 여타의 joa 구현체를 사용하려면 hibernate exclude 해야함.

JSP 기본 객체

1. 기본 객체  기본 객체  실제 타입   설명   request  javax.servlet.http.HttpServletRequest   클라이언트의 요청 정보를 저장한다.   response  javax.servlet.http.HttpServletResponse   응답 정보를 저장한다.   pageContext   javax.servlet.jsp.PageContext   JSP 페이지에 대한 정보를 저장한다.   session   javax.servlet.http.HttpSession   HTTP 세션 정보를 저장한다.   application   javax.servlet.ServletContext   웹 어플리케이션에 대한 정보를 저장한다.   out   javax.servlet.jsp.JspWriter   JSP 페이지가 생성하는 결과를 출력할 때 사용되는 출력 스트림이다.   config  javax.servlet.ServletConfig   JSP 페이지에 대한 설정 정보를 저장한다.   page  java.lang.Object   JSP 페이지를 구현한 자바 클래스 인스턴스이다.   exception  java.lang.Throwable   익셉션 객체, 에러 페이지에서만 사용된다.  2. out -  A PI :  http://docs.oracle.com/javaee/7/api/javax/servlet/jsp/JspWriter.html - 웹 브라우저에 데이터를 전송하는 출력 스트림이다. - 비-스크립트 요소들(HTML 코드 or 텍스트)과 값을 출력하는 표션식의 결과는 out 기본 객체에 그대로 전달된다. - JSP 페이지가 사용하는 버퍼는 실제로는 out 기본 객체가 내부적으로 사용하고 있는 버퍼이다. - isAutoFlush() 메서드의 값을 결정하는 것은 page 디렉티브