2. Spring boot 공통 작업

최강일·2023년 11월 5일
0

Spring boot

목록 보기
7/7

2.1 애플리케이션 설정 관리

동일한 애플리케이션을 dev,test,staging,product 환경 등 여러 환경에 배포해야 하는 경우도 있다.
배포할 환경에 따라서 설정들을 각각 적용하고 싶다면 property 파일, 환경변수, 명령행 인자 등 여러가지 방법으로 소스코드 변경없이 환경마다 다르게 적용할 수 있다.

2.1.1 SpringApplication 클래스 사용

소스코드로 정의하는 방식으로 1번 정의하면 바뀌지 않는 경우에 적합하다.
setDefaultProperties()를 사용하여 세팅할 수 있다.

2.1.2 @PropertySource 사용

property 파일 위치를 지정할 수 있다. 단 YML 또는 YAML 파일을 지정하려면 추가 작업이 필요하다.
ex. @PropertySource("classpath:dbConfig.properties")

2.1.3 환경 설정 파일

가장 많이 사용되는 방법으로 application.properties 또는 application.yml파일에서 설정한다.
해당 파일에 명시된 설정 정보는 Spring의 Environment 개체에 로딩되고, 해당 인스턴스에 접근하거나 @Value 어노테이션으로 접근할 수 있다.
원하는 properties 파일로 실행하고 싶다면 java -jar {jar 파일} --spring.config.name=xxx 로 사용하면 된다.
또한 spring.config.location을 통해 spring boot의 기본 설정 디렉터리가 아닌곳을 설정할 수 있으나, 사용하지 말자.(협업 개발자에게 불필요한 혼선을 일으킨다.)

profile

배포 환경마다 설정을 분리해서 환경별로 다르게 적용할 수 있다.
application.properties파일이 아닌 application-{profile}.properties 처럼 작성한다.
사용할 profile 지정은 application.properties에서 spring.profiles.active=dev와 같이 설정한다.

2.1.4 운영 체제 환경 변수

운영 체제 환경 변수로 지정한 값도 설정 정보 파일(application.properties)에서 사용할 수 있다.
ex. app.timeout={APP.TIMEOUT}

설정 우선순위

  1. 명령행 인자
  2. 운영 체제 환경 변수
  3. 설정 정보 파일
  4. @PropertySource
  5. SpringApplication

예를들어 3.설정 정보 파일의 설정보다 1.명령행 인자 설정이 덮어 적용된다.

properties vs yml

취향차이다.
데이터의 위계 구조를 더 잘 표현하며 반복적인 내용을 줄일 수 있는 측면에서 yml이 주는 장점도 있다.
하지만 문법 오류에 취약하다. (공백, 들여쓰기 등등)
때문에 간단하고 직관적이며 많은 설정들 사이에서 찾을 수 있는 장점이 있는 properties 사용도 괜찮아 보인다.

2.2 @ConfigurationProperties로 커스텀 프로퍼티 만들기

Spring boot의 설정 정보는 크게 빌트인 property, custom property로 나뉜다.
빌트인 property로는 server.port 등등이 있다.
앞장에서 알아봤듯이 설정 정보는 Spring의 Environment 인스턴스에 바인딩되고, 해당 인스턴스를 주입받으면 property값들을 사용할 수 있다.
하지만 해당 방법으로는 property 타입 안전성을 보장하고 유효성을 검증할 수 없다.

사용법

@Configuration 어노테이션을 사용해 설정 정보를 담는 클래스를 만들어서 타입의 안정성을 보장하고 유효성을 검증한다.
이렇게하면 @Value 어노테이션이나 Environment 객체를 사용하지 않고도 property 값을 사용할 수 있다.
spring-boot-configuration-processor 디펜던시가 필요하다.

예제

property 파일에 app.sbip.ct.name=testName이라는 property를 추가한다.
prorperty 네이밍의 클래스를 생성하고@ConstructorBinding,@ConfigurationProperties("app.sbip.ct")어노테이션을 추가한다.
그러면 프로퍼티를 담는 클래스가 생성되고,이를 사용해서 프로퍼티를 읽는 클래스를 생성한다.(@Serice 어노테이션)
그러고 Main()에서 @EnableConfigurationProperties(service 클래스 지정)하여 컨테이너에 등록하고 사용할 수 있다.

2.3 애플리케이션 시작 시 코드 실행

Spring boot app을 실행할 때 특정 코드를 실행해야 할 때가 있다.
ex. app 초기화 완료 전 db 초기화 스크립트 실행 또는 외부 rest api 호출 등등

CommandLineRunner와 ApplicationRunner는 run()메서드만 가지고 있는 인터페이스인데, 구현하여 빈으로 등록해두면 app 초기화 완료 직전에 run()메서드가 실행된다.

2.3.1 애플리케이션 시작 시 CommandLineRunner로 코드 실행

사용법 3가지를 알아본다.

  1. boot main 클래스가 CommandLineRunner 인터페이스를 구현
  2. CommandLineRunner 구현체에 @Bean을 붙여 빈으로 정의
  3. CommandLineRunner 구현체에 @Component를 붙여서 스프링 컴포넌트로 정의

1번째 방식은 구현체 1개만 정의할 수 있고, 실행 순서를 지정할 수 없다는 점에서 제한적이다.
3번째방식은 별도의 클래스로 작성할 수 있어서 더 나은 코드를 작성하는데 도움된다.

@Bean, @Component 차이

Spring에 의해 빈으로 등록된다는 공통점이 있지만, 사용법에 차이가 있다.
빈으로 등록하고자 하는 클래스의 소스코드에 직접 접근할 수 없을 때는 해당 클래스의 인스턴스를 반환하는 메서드를 작성하고 이 메서드에 @Bean 어노테이션을 붙여서 빈으로 등록되게 한다.
반대로 빈으로 등록하고자 하는 클래스의 소스 코드에 직접 접근할 수 있을 때는 이 클래스에 직접 @Component 어노테이션을 붙이면 빈으로 등록된다.

2.4 로깅 커스터마이징

Spring boot starter 의존성을 주가하면 기본적으로 logback을 포함하여 사용한다.

로그 구성 요소

  • 일시
  • 로그 레벨 - FATAL,ERROR,WARN,ERROR,INFO,DEBUG
  • 프로세스 ID
  • 스레드 명
  • 로거 이름
  • 메세지

logger,appender

  • logger : 1개 이상의 appender를 사용해서 로그 메시지 표시를 담당하는 로깅 프레임워크의 컴포넌트다.
  • appender : 로그가 출력되는 대상과 로깅 포맷을 지정할 수 있다.

2.5 Bean Validation으로 데이터 유효성 검증

사용자 입력 데이터가 비즈니스 요구사항에 적합한지 검증해야 할 때가 있다.
빈 값을 허용하지 않거나, 최소 x글자 등등의 요구사항이 될 수 있다.
java에서는 bean validation이 표준으로 자리잡고 있으며, 제약사항을 충족하지 않으면 어노테이션에서 지정한 에러 메시지가 표시된다.
관련 디펜던스는 spring-boot-starter-validation이다.

필드에 붙여 사용하는 hibernate validate 어노테이션

  • @NotBlank : CharSequence 타입이며 문자열이 null이 아니고, 앞뒤 공백 문자를 제거한 후 문자열 길이가 0보다 큰지 검사
  • @NotEmpty : CharSequence,Collection,Map 타입과 배열에 사용되어 null이 아니고 비어있지 않음을 검사
  • @NotNull : 모든 타입에 사용할 수 있으며 null이 아님을 체크
  • @Min(value=) : 이 값보다 크거나 같은지 체크
  • @Max(value=)
  • @Pattern(regex=,flags) : regex로 지정한 정규 표현식을 준수하는지 검사
  • @Size(min=,max=) : 개수의 최솟값,최댓값을 준수하는지 검사
  • @Email : 문자열이 유효한 이메일 주소인지 검사

더 다양한 하이버네이트 제약사항이 있으며, 대부분의 시나리오에서는 빌트인 어노테이션으로도 충분하다.
하지만 IP 주소, 비밀번호, 커스텀 제약사항 검증이 필요하다.


예제
  • Min(value = 1, `message = "msg")
  • Max(value = 5, message = "msg")
  • 동시 적용도 가능

커스텀 bean validation 어노테이션을 사용한 POJO 빈 요효성 검증

  • 비밀번호 규칙을 강제하는 Passay 디펜던시를 사용하여 구현
  • ConstraintValidator를 상속받고 isValid를 Override하여 구현
  • 해당 구현체를 어노테이션으로 등록하여 사용
profile
Search & Backend Engineer

0개의 댓글