동일한 애플리케이션을 dev,test,staging,product 환경 등 여러 환경에 배포해야 하는 경우도 있다.
배포할 환경에 따라서 설정들을 각각 적용하고 싶다면 property 파일, 환경변수, 명령행 인자 등 여러가지 방법으로 소스코드 변경없이 환경마다 다르게 적용할 수 있다.
소스코드로 정의하는 방식으로 1번 정의하면 바뀌지 않는 경우에 적합하다.
setDefaultProperties()를 사용하여 세팅할 수 있다.
property 파일 위치를 지정할 수 있다. 단 YML 또는 YAML 파일을 지정하려면 추가 작업이 필요하다.
ex. @PropertySource("classpath:dbConfig.properties")
가장 많이 사용되는 방법으로 application.properties 또는 application.yml파일에서 설정한다.
해당 파일에 명시된 설정 정보는 Spring의 Environment 개체에 로딩되고, 해당 인스턴스에 접근하거나 @Value 어노테이션으로 접근할 수 있다.
원하는 properties 파일로 실행하고 싶다면 java -jar {jar 파일} --spring.config.name=xxx 로 사용하면 된다.
또한 spring.config.location을 통해 spring boot의 기본 설정 디렉터리가 아닌곳을 설정할 수 있으나, 사용하지 말자.(협업 개발자에게 불필요한 혼선을 일으킨다.)
배포 환경마다 설정을 분리해서 환경별로 다르게 적용할 수 있다.
application.properties파일이 아닌 application-{profile}.properties 처럼 작성한다.
사용할 profile 지정은 application.properties에서 spring.profiles.active=dev와 같이 설정한다.
운영 체제 환경 변수로 지정한 값도 설정 정보 파일(application.properties)에서 사용할 수 있다.
ex. app.timeout={APP.TIMEOUT}
예를들어 3.설정 정보 파일의 설정보다 1.명령행 인자 설정이 덮어 적용된다.
취향차이다.
데이터의 위계 구조를 더 잘 표현하며 반복적인 내용을 줄일 수 있는 측면에서 yml이 주는 장점도 있다.
하지만 문법 오류에 취약하다. (공백, 들여쓰기 등등)
때문에 간단하고 직관적이며 많은 설정들 사이에서 찾을 수 있는 장점이 있는 properties 사용도 괜찮아 보인다.
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 클래스 지정)하여 컨테이너에 등록하고 사용할 수 있다.
Spring boot app을 실행할 때 특정 코드를 실행해야 할 때가 있다.
ex. app 초기화 완료 전 db 초기화 스크립트 실행 또는 외부 rest api 호출 등등
CommandLineRunner와 ApplicationRunner는 run()메서드만 가지고 있는 인터페이스인데, 구현하여 빈으로 등록해두면 app 초기화 완료 직전에 run()메서드가 실행된다.
사용법 3가지를 알아본다.
1번째 방식은 구현체 1개만 정의할 수 있고, 실행 순서를 지정할 수 없다는 점에서 제한적이다.
3번째방식은 별도의 클래스로 작성할 수 있어서 더 나은 코드를 작성하는데 도움된다.
Spring에 의해 빈으로 등록된다는 공통점이 있지만, 사용법에 차이가 있다.
빈으로 등록하고자 하는 클래스의 소스코드에 직접 접근할 수 없을 때는 해당 클래스의 인스턴스를 반환하는 메서드를 작성하고 이 메서드에 @Bean 어노테이션을 붙여서 빈으로 등록되게 한다.
반대로 빈으로 등록하고자 하는 클래스의 소스 코드에 직접 접근할 수 있을 때는 이 클래스에 직접 @Component 어노테이션을 붙이면 빈으로 등록된다.
Spring boot starter 의존성을 주가하면 기본적으로 logback을 포함하여 사용한다.
사용자 입력 데이터가 비즈니스 요구사항에 적합한지 검증해야 할 때가 있다.
빈 값을 허용하지 않거나, 최소 x글자 등등의 요구사항이 될 수 있다.
java에서는 bean validation이 표준으로 자리잡고 있으며, 제약사항을 충족하지 않으면 어노테이션에서 지정한 에러 메시지가 표시된다.
관련 디펜던스는 spring-boot-starter-validation이다.
더 다양한 하이버네이트 제약사항이 있으며, 대부분의 시나리오에서는 빌트인 어노테이션으로도 충분하다.
하지만 IP 주소, 비밀번호, 커스텀 제약사항 검증이 필요하다.