-
[스프링 인 액션] Chapter 5 - 구성 속성 사용하기 :: 자동-구성 세부 조정하기개발서적읽기/Spring in Action 제 5판 2020. 7. 31. 01:22
자동 - 구성(auto configuration)은 스프링 애플리케이션 개발을 단순화해 준다.
스프링 XML 구성으로 속성 값을 설정하던 지난 10년간은
명시적으로 빈을 구성하지 않고는 속성을 설정하는 마땅한 방법이 없었다.
다행스럽게도 스프링 부트는 구성 속성(configuration property)을
사용하는 방법을 제공한다.
스프링 애플리케이션 컨텍스트에서 구성 속성은 빈의 속성이다.
그리고 JVM 시스템 속성, 명령행 인자, 환경 변수 등의
여러 가지 원천 속성 중에서 설정할 수 있다.
이 장에서는 타코 애플리케이션에 새로운 기능을 구현하는 것을 잠시 멈추고
구성 속성의 이모저모를 살펴볼 것이다. 구성 속성을 알아 두면
이후의 진도를 나가는 데 확실히 도움이 되기 때문이다.
우선 스프링 부트가 자동으로 구성하는 것을 세부 조정하기 위해
구성 속성을 사용하는 방법부터 알아보자.
스프링에는 서로 다르면서도 관련이 있는 두 가지 형태의 구성이 있다.
- 빈 연결 : 스프링 애플리케이션 컨텍스트에서 빈으로 생성되는 애플리케이션 컴포넌트들이
상호간에 주입
- 속성 주입 : 스프링 애플리케이션 컨텍스트에서 빈의 속성 값을 설정
자바 기반 구성에서 @Bean 애노테이션이 지정된 메서드는
사용하는 빈의 인스턴스를 생성하고 속성 값도 설정한다.
예를 들어, 스프링에 내장된 H2 DB를 DataSource로 선언하는 다음의 @Bean을 보자.
@Bean
public DataSource dataSource() {
return new EmbeddedDatabaseBuilder()
.setType(EmbeddedDatabaseType.H2)
.addScript("schema.sql")
.addScript("user_data.sql","ingredient_data.sql")
.build();
}만일 스프링 부트를 사용중이 아니라면
이 메서드(dataSource)를 통해 DataSource 빈을 구성할 수 있다.
하지만 스프링 부트를 사용 중일 때는 자동-구성이 DataSource 빈을 구성해준다.
스프링 부트는 런타임 시에 H2 의존성 라이브러리를 찾고
DataSource 빈을 자동으로 찾아 스프링 애플리케이션 컨텍스트에 생성한다.
그리고 해당 빈이 SQL 스크립트를 실행하여 DB에 적용시킨다.
그러나 SQL 스크립트 파일의 이름을 다르게 지정하고 싶거나 3개 이상을 지정해야 한다면?
바로 이런 경우에 위 코드와 같이 구성 속성을 사용할 수 있다.
■스프링 환경 추상화 이해하기
스프링 환경 추상화는 구성 가능한 모든 속성을 한 곳에서 관리하는 개념이다.
즉, 속성의 근원을 추상화하여 각 속성을 필요로 하는 빈이
스프링 자체에서 해당 속성을 사용할 수 있게 해준다.
스프링 환경에서는 다음과 같은 속성의 근원으로부터 원천 속성을 가져온다.
- JVM 시스템 속성
- 운영체제의 환경 변수
- 명령행 인자
- 애플리케이션의 속성 구성 파일
그리고 스프링 환경에서는 이 속성들을 한 군데로 모은 후 각 속성이 주입되는
스프링 빈을 사용할 수 있게 해준다.
예를 들어 port를 application.properties 파일이나 application.yml 파일에 지정할 수 있다.
혹은 java 명령어 옵션이나 운영체제 환경 변수에 설정할 수도 있다.
이처럼 구성 속성을 설정하는 방법에는 여러 가지가 있다.
이제 가장 많이 사용되는 속성 설정들을 살펴보자.
■데이터 소스 구성하기
타코 애플리케이션을 production 환경에서 사용하려면
H2보다 더 확실한 DB 솔루션이 필요하다.
스프링 부트는 DataSource 빈을 자동으로 구성한다.
하지만 더 간단하게 DB를 설정하려면 구성 속성을 이용하면 된다.
application.properties 파일을 수정해보자.
spring:
datasource:
url: jdbc:mysql://localhost/tacocloud
username: tacouser
password: tacopassword그다음에 적합한 JDBC 드라이버를 추가해야 하지만
구체적인 JDBC 드라이버 클래스를 지정할 필요는 없다.
스프링 부트가 DB URL로부터 찾을 수 있기 때문이다.
그러나 다음과 같이 직접 DB 드라이버 클래스 속성을 추가할 수도 있다.
spring:
datasource:
url: jdbc:mysql://localhost/tacocloud
username: tacouser
password: tacopassword
driver-class-name: com.mysql.jdbc.Driver그러면 DataSource 빈을 자동-구성할 때 스프링 부트가 위 속성 설정을
연결 데이터로 사용한다. 또한 톰캣의 JDBC 커넥션 풀을 classpath에서 자동으로
찾을 수 있다면 DataSource 빈이 그것을 사용한다.
그렇지 않다면 스프링 부트는 다음 중 하나의 커넥션 풀을 classpath에서 찾아 사용한다.
- HikariCP
- Commons DBCP 2
애플리케이션이 시작될 때 DB를 초기화하는 SQL 스크립트의 실행 방법을
이번 장 앞에서 얘기했었다.
다음과 같이 설정하면 더 간단하게 지정할 수 있다.
spring:
datasource:
schema:
- order-schema.sql
- ingredient-schema.sql
- taco-schema.sql
- user-schema.sql
data:
- ingredients.sql또는 명시적인 데이터 소스 구성 대신 JNDI(Java Naming and Directory Interface)에
구성하는 방법도 있다.
spring:
datasource:
jndi-name: java:/comp/env/jdbc/tacoCloudDs단, 위 속성을 지정하면 기존에 설정된 다른 데이터 소스 구성 속성은 무시된다.
■내장 서버 구성하기
port가 0으로 설정되면 어떻게 될까?
무작위로 포트가 선택되어 서버가 실행된다.
이것은 자동화된 통합 테스트를 실행할 때 유용하다.
즉, 동시에 실행되는 테스트들이 같은 포트 번호를 사용하게 되는 것을 막을 수 있다.
MSA 환경같이 애플리케이션이 시작되는 포트가 중요하지 않을 때도 유용하다.
한편, 서버에 관련해서는 포트 외에도 중요한 것이 더 있다.
그중 하나가 HTTPS 요청 처리를 위한 컨테이너 관련 설정이다.
먼저 JDK의 keytool 명령행 유틸리티를 사용해서 키스토어를 생성해야 한다.
keytool 은 Keystore 기반으로 인증서와 키를 관리할 수 있는
커맨드 방식의 유틸리티로 JDK 에 포함되어 있다.
keytool -keystore mykeys.jks -genkey -alias tomcat -keyalg RSA
keytool이 실행되면 저장 위치 등의 여러 정보를 입력받는데,
무엇보다 우리가 입력한 비밀번호를 잘 기억해 두는 것이 중요하다.
여기서는 letmein을 비밀번호로 지정할 것이다.
키스토어 생성이 끝난 후에는 내장 서버의 HTTPS를 활성화하기 위해
몇 가지 속성을 설정해야 한다. 이 속성들은 모두 명령행에 지정할 수 있다.
그러나 굉장히 불편하다. 대신 application.properties 또는 application.yml 파일에 설정하자.
server:
port: 8443
ssl:
key-store: file://path/to/mykeys.jks
key-store-password: letmein
key-password: letmeinserver.ssl.key-store 속성은 키스토어 파일이 생성된 경로로 설정되어야 한다.
여기서는 운영체제의 파일 시스템에서 키스토어 파일을 로드하기 위해
file://를 URL로 지정하였다. 그러나 애플리케이션 JAR 파일에 키스토어 파일을 넣는 경우는
classpath:를 url로 지정하여 참조해야 한다.
그리고 server.ssl.key-store-password와 server.ssl.key-password 속성에는
키스토어를 생성할 때 지정했던 비밀번호를 설정한다.
이 모든 속성이 제대로 설정되면
우리 애플리케이션은 8443 포트의 HTTPS 요청을 기다린다.
■로깅 구성하기
대부분의 애플리케이션은 로깅을 제공한다.
기본적으로 스프링 부트는 콘솔에 로그 메시지를 쓰기 위해
Logback을 통해 로깅을 구성한다.
이때 기본 로깅 수준은 INFO다.
로깅 구성을 제어할 때는 classpath의 루트에(src/main/resources)
logback.xml 파일을 생성하면 된다.
<configuration>
<appender name="STDOUT" class="ch.qos. logback.core.ConsoleAppender">
<encoder>
<pattern>
%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} – "ómsg%n
</pattern>
</encoder>
</appender>
<logger name="root" level="INFO"/>
<root level="INFO">
<appender-ref ref="STDOUT"/>
</root>
</configuration>로깅에 사용되는 패턴을 제외하면 이 Logback 구성은 logback.xml 파일이
없을 때의 기본 로깅 구성과 동일하다.
로깅 구성에서 가장 많이 변경하는 것은 로깅 수준과 로그를 수록할 파일이다.
스프링 부트의 구성 속성을 사용하면 logback.xml 파일을 생성하지 않고
로그 설정을 변경할 수 있다.
로깅 수준을 설정할 때는 logging.level을 접두어로 갖는 속성들을 생성한다.
그리고 그다음에 로깅 수준을 설정하기 원하는 로거의 이름을 붙인다.
logging:
level:
root: WARN
org:
springframework:
security: DEBUG또한 알아보기 쉽도록 스프링 시큐리티 패키지 이름을 붙여서 한 줄로 지정할 수도 있다.
logging:
level:
root: WARN
org.springframework.security: DEBUG그다음에 로그 항목들을 /var/logs/ 경로의 TacoCloud.log 파일에 수록하고 싶다면
logging:
file:
path: /var/logs/
name: TacoCloud.log
level:
root: WARN
org.springframework.security: DEBUG이렇게 설정하면 된다.
이 경우 애플리케이션이 /var/logs/에 대해 쓰기 퍼미션을 갖고 있다면
로그 항목들이 /var/logs/TacoCloud.log에 수록될 것이다.
기본적인 로그 파일의 크기인 10MB가 가득 차게 되면 새로운 로그 파일이 생성되어
로그 항목이 계속 수록된다.
스프링 2.0 부터는 날짜별로 로그 파일이 남으며
지정된 일 수가 지난 로그 파일은 삭제된다.
■다른 속성의 값 가져오기
하드코딩된 String과 숫자 값으로만 속성 값을 설정해야 하는 것은 아니다.
다른 구성 속성들로부터 값을 가져올 수도 있다.
예를 들어 greeting.welcome 이라는 속성을 또 다른 속성인
spring.application.name의 값으로 설정하고 싶다고 해보자.
greeting:
welcome: ${spring.application.name}또한 다른 텍스트 속에 ${}를 포함시킬 수도 있다.
greeting:
welcome: You are using ${spring.application.name}이렇게 구성 속성을 사용해서 스프링 자체의 컴포넌트를 구성하면
해당 컴포넌트의 속성 값을 쉽게 주입할 수 있고 자동-구성을 세부 조정할 수 있다.
'개발서적읽기 > Spring in Action 제 5판' 카테고리의 다른 글
[스프링 인 액션] Chapter 5 - 구성 속성 사용하기 :: 프로파일 사용해서 구성하기 (0) 2020.07.31 [스프링 인 액션] Chapter 5 - 구성 속성 사용하기 :: 우리의 구성 속성 생성하기 (0) 2020.07.31 [스프링 인 액션] Chapter 4 - 스프링 시큐리티 :: 각 폼에 로그아웃 버튼 추가하고 사용자 정보 보여주기 (0) 2020.07.30 [스프링 인 액션] Chapter 4 - 스프링 시큐리티 :: 사용자 인지하기 (0) 2020.07.30 [스프링 인 액션] Chapter 4 - 스프링 시큐리티 :: 웹 요청 보안 처리하기 (0) 2020.07.30 댓글