10월, 2019의 게시물 표시

Spring Boot Property 로딩 및 적용 순서

property 파일 로딩 순서 간단 정리 1. (local)      application 2. (local)      application-{profile} 3. (server)    application 4. (server)   {spring.application.name} 5. (server)   {spring.application.name}-{profile} 로딩 순서는 1 -> 5, 같은 값이 있을 때는 번호가 클 수록 winner (local은 application을 뜻하고, server는 spring cloud config 서버를 의미) Multiple Active Profile을 줄 때 dev, prd의 모든 property를 다 가져 오지만, 공통 값이 있을 경우 뒤에 것이 앞의 값을 덮는다. 아래와 같은 경우 dev와 prd에 겹치는 property가 있으면 prd가 dev의 값을 덮는다. -Dspring.profiles.active=dev,prd Config 서버 사용시 주의할 우선 순위 bootstrap에 아래와 같이 정의 되어 있고 active profile을 p1, p2로 주게 되면, 로컬은 application-p1, application-p2를 모두 로드 하고 같은 property가 있을 경우 p2가 p1의 값을 덮어 쓴다. 그러나 config 서버의 경우는 마지막에 선언된 active profile p2만 영향을 주어, 선언된 http://2.2.2.2:8888로부터 {application.name}-cp2.yml만 가져와 사용하고 공통 값이 있을 경우 로컬 property를 덮어 쓴다.(즉, cp1은 무시) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 ... --- spring: profiles: p1 cloud: config: uri: http://1.1.1.1:8888 profile:

JPA와 MyBatis를 같은 Transaction에서 사용하기

이 포스트는 같은 트랜잭션 내에  JPA 와  MyBatis 를 사용하는 방법을  Spring Transaction  을 이용한 예제를 보여준다. JpaTransactionManager Spring 은  PlatformTransactionManager  인터페이스로 트랜잭션을 처리한다. 이 인터페이스의 구현체 중에 하나인  JpaTransactionManager  는 단일 JPA  EntityManagerFactory  를 유지하면서 스레드별로  EntityManager 를 제공한다. JpaTransactionManager  는 JPA 를 위해 주로 사용하지만 트랜젝션이 사용하고 있는  DataSource 에 직접 접근이 가능하여 일반적인 JDBC 를 바로 사용할 수있다. MyBatis의 서브 프로젝트인  MyBatis-Spring 은 MyBatis의 트랜잭션 관리를  SqlSession 이 아닌  Spring Transaction 에 위임한다. 따라서  JpaTransactionManager  를 사용하면  JPA 와  MyBatis  를 같은 트랜젝션으로 묶을 수 있게된다. 예제 코드 환경 Spring-boot 2.1.7.RELEASE spring-boot-starter-data-jpa mybatis-spring-boot-starter h2 lombok spring-boot-starter-test META-INF/persistence.xml 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 <?xml version="1.0" encoding="UTF-8"?> <persistence xmlns= "http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance&quo

서버 TPS란?

TPS는 Transaction Per Second의 약자이며, 여기서의 transaction이란 하나의 HTTP request / response 쌍을 의미한다. 그러므로 TPS란 초당 request / response가 수행된 양을 뜻하게 되며 서버의 성능이나 모니터링 지표로 사용될 수 있다.

SpringMVC Command Object를 사용할 경우 Swagger의 path variable 표시 방법

SpringMVC Controller에서 path variable이나 query parameter를 일일이 매핑하지 않고 Command Object를 사용할 수도 있다. 이때 Swagger에서 path variable이나 query parameter를 제대로 표시 하지 못하는데 이럴 경우 아래와 같이 @ApiImplicitParams를 사용해서 매핑을 할수 있다. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 @ApiOperation (value = "Test API." ) @RequestMapping (value = "/test" , method = RequestMethod. GET ) @ApiImplicitParams ({ @ApiImplicitParam (name = "memberId" , value = "member identification number" , paramType = "path" , dataType = "long" , required = true ) }) public ResponseEntity<String> testMethod ( @Valid CommandObject command) { return "hello, world~" } @Setter @Getter @ToString @NoArgsConstructor @AllArgsConstructor public class CommandObject { private long memberId } 아래 링크는 StackOverflow에 내가 단 답변. https://stackoverflow.com/questions/47442926/spring-4-3-allows-query-params-to-override-path-variables-from-request

Java Semaphore

Multi thread 환경에서 하나의 thread가 작업중에 다른 thread의 진입을 막기 위해 synchronized 키워드를 사용한다. 즉, synchronized 는 한번에 하나의 thread가 작업을 할 수 있도록 해준다. 그러면 만약 10개의 thread가 있다고 가정했을때, 이중 3개씩만 동시 접근이 가능하도록 만들려면 어떻게 할까? 이럴때 Semaphore 를 사용해 보자. 아래는 예제 코드. 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 35 36 37 38 39 40 41 42 class SemaphoreTest { public static void main (String[] args) throws InterruptedException { List<Thread> threadList = new ArrayList<>(); final SomeResource resource = new SomeResource( 3 ); Thread temp = null ; for ( int i = 0 ; i < 10 ; i++) { temp = new Thread(() -> resource. use ()); threadList. add (temp); temp. start (); } for (Thread thread : threadList) { System. out . println ( "[" + thread. getName () + "] joining..." ); thread. join (); }