여태까지 버전관리를 할 일이 없었다. 외부에 api를 제공 할 일이 없고 회사내부에서만 작업을 하다보니...그런데 이번에 외부에 api를 제공하게 되면서 api 문서도 제공하였다. 근데 여러군데에 제공하다보니 version관리가 불가피 하게 되었다. 그래서 어떻게 할까 하다 좋은 예제가 있어 글로 작성해본다. 먼저 version어노테이션을 아래와 같이 작성한다. v1, v2등 여러 버전을 맵핑할 수있게 하기 위해서 value는 배열로선언했다. @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.METHOD, ElementType.TYPE}) public @interface Version { double[] value(); } Controller와 url을..
Spring에서 이벤트를 사용하는 방법에 대해 알아보자. 이벤트는 프레임 워크에서 간과 된 기능 중 하나이지만 더 유용한 기능 중 하나입니다. 그리고 Spring의 다른 많은 것들과 마찬가지로 이벤트 퍼블리싱은 ApplicationContext가 제공하는 기능 중 하나입니다. Spring ApplicationEvent는 기본적으로 동기입니다. 먼저 간단한 이벤트 메세지 클래스를 작성합니다. public class CustomEvent extends ApplicationEvent { private String message; public CustomEvent(Object source, String message) { super(source); this.message = message; } public St..
Spring REST Docs는 정확하고 읽기 쉬운 RESTful 서비스에 대한 문서를 생성합니다. 손으로 작성한 문서와 Spring 테스트로 생성 된 자동 생성 문서 snippets(스니펫)을 결합해서 사용 할 수 있게 해줍니다. 자바 문서 자동화에는 Spring REST Docs 이외에 대표적으로 Swagger가 있습니다. 필자는 Swagger의 경험만 있었다...문서 자동화라는 공통점이 있지만 각각 용도,목적??은 다르다. Spring REST Docs Swagger 용도 문서 제공용 API 테스트를 위한 용도에 더 집중됨 장점 깔금하고 API 명세에 집중 적용하기 상대적으로 쉬움 API 테스트 UI제공 단점 Test코드 기반 문서 작성됨 (Test코드 필수) 설정등 적용하기 어려움 코드에 어노테이..
스프링의 HandlerMethodArgumentResolver 구현하여 커스텀 데이터를 binding해보자. 데이터를 객체에 바인딩하려는 경우가 있지만 직접적이지 않은 방식 (예 : 세션, 헤더 또는 쿠키 변수) 또는 데이터 소스에 저장되는 경우가 있습니다. 이 경우 HandlerMethodArgumentResolver 이용하면 쉽게 해결할 수 있다. 먼저 커스텀 어노테이션을 작성하자. @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.PARAMETER) public @interface Version { } 커스텀 어노테이션을 정의하고 HandlerMethodArgumentResolver에 등록하면 어노테이션만 달면 컨트롤러에서 쉽게 바인딩 할수있다. H..
spring boot로 kafka를 간단하게 구현을 해보자. kafka가 이미 설치된 가정하에 진행하겠다. 이전글에 보면 kafka 설치 및 간단히 콘솔에서 실행하는 방법을 설명한 바 있다. 참조하도록 하자. 먼저 프로젝트를 생성하자. 인텔리j, maven기반으로 설명하겠다.Spring initializr를 선택해서 프로젝트를 생성하자. 디펜던시를 아래와 같이 추가해주자. Web -> Spring Web Starter와 Messaging -> Spring for Apache Kafka Streams, Spring for Apache Kafka 이제 kafka의 topic을 생성하는 KafkaTopicConfig 파일을 생성하고 KafkaAdmin 빈을 추가하자. KafkaAdmin 빈은 NewTopic ..
kafka producer와 cunsumer를 테스트해보자. 일단 kafka를 먼저 설치 하자. kafka를 다운받고 간단하게 producer, cunsumer 실행하고 압축을 풀고 해당 kafka 디렉토리로 이동하자. 아래와 같이 폴더들이 있다. ~/kafka.2.12-2.3.0 > ls LICENSE NOTICE bin config libs site-docs 아래와 같이 입력하여 zookeeper를 실행하자. bin/zookeeper-server-start.sh config/zookeeper.properties 실행되면 아래와 같이 메세지가 출력이 된다. INFO binding to port 0.0.0.0/0.0.0.0:2181 (org.apache.zookeeper.server.NIOServerCn..
IoC란 Inversion of Control의 약자로 해석하자면 제어의 역전이다. 즉 제어권이 역전되었다는 뜻인데 제어권이 뒤 바뀌었다는 뜻이다. 이말은 기존의 제어방식을 뒤집었다는 말이 된다. 그렇다면 기존의 방식은 어떠했는가 살펴보자. 자바가 등장하고 자바 기반의 어플리케이션이 개발되던 초기에는 자바 객체를 생성하고 객체간의 의존관계를 연결하는 등의 제어권을 개발자가 직접 가지고 있었다고 한다. 그러나 서블릿, EJB가 등장하면서 개발자가 독점적으로 가지고 있던 제어권이 서블릿과 EJB를 관리하는 외부의 컨테이너로 넘어갔고 객체의 생성부터 생명주기의 관리까지 모든 객체에 대한 제어권이 바뀐 것을 IoC, 제어의 역전이라 하는것이다. Spring (IoC) container 모든 작업을 사용하는 쪽에..
Spring AOP는 JDK 동적 프록시 또는 CGLIB를 사용하여 지정된 대상 객체에 대한 프록시를 만듭니다. JDK 동적 프록시 java의 리플렉션을 이용해서 객체를 만든다. CGLIB 경우에는 바이트코드를 조작해 프록시 객체를 만든다. Spring boot 는 기본적으로 transaction 대상의 aop를 동작시킬 프록시를 cglib 프록시를 사용하게 설정 해놨다. 그리고 성능 또한 jdk 프록시보다는 cglib가 빠르다. 우리가 느낄정도? 아니지만 일반적으로 cglib가 예외를 발생시킬 가능성이 낮다고 한다. 프록시 할 대상 객체가 하나 이상의 인터페이스를 구현하는 경우 JDK 동적 프록시가 사용됩니다.타겟 타입에 의해 구현 된 모든 인터페이스는 프록시 화됩니다.대상 객체가 인터페이스를 구현하지..
Mybatis oracle proedure xmlType 처리필자가 알기엔 oracle 11g부터인가 xmlType형식을 지원한다. 그리고 mybatis로 oracle procedure 함수를 호출해서 쿼리 대신 데이터를 받을 수 있다.굳이 왜 이렇게 하는가....근데 그렇게 해야 할 일이 생겨서 삽질을 좀 많이 했다. 프로젝트는 spring-boot 2.1.2, Java 8, maven, intellij 기반으로 했다. 근데 여기서 또 하나 문제가 발생한다. 아래에 설명할 테지만 spring-boot를 사용하는데 어쩔 수 없이 배포를 war로 해야 했다. war 배포 설정은 여기에 아주 잘 나왔다. 참고하도록 하자. 참고로 intellij 프로젝트 생성시 packaging war바꿔주면 알아서 다 해준..
spring boot MessageSource 다국어처리spring reactive 기반으로 다국어처리를 한번 해보겠다. 틀린 부분도 있을것이다. webflux로 진행해보겠다. 일단 프로젝트를 하나 생성해보자. 개발환경은 인텔리j, maven기반이다. 먼저 템플릿 엔진은 thymeleaf를 사용하기 때문 아래와 같이 pom.xml에 추가해주자. org.springframework.boot spring-boot-starter-thymeleaf 그 다음 MessageSource 와 templateResolver 설정이다.MessageSource beannames는 프로젝트 resources 하위 message 프로퍼티경로를 적어주면된다. messages/message는 resources 폴더아래 messag..