chap 5 1 - JAVA-JIKIMI/SPRING-IN-ACTION-5 GitHub Wiki
μλ - ꡬμ±(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 νμΌμ μ€μ νμ.
port: 8443
ssl:
key-store: file://path/to/mykeys.jks
key-store-password: letmein
key-password: letmein
server.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}
μ΄λ κ² κ΅¬μ± μμ±μ μ¬μ©ν΄μ μ€νλ§ μ체μ μ»΄ν¬λνΈλ₯Ό ꡬμ±νλ©΄
ν΄λΉ μ»΄ν¬λνΈμ μμ± κ°μ μ½κ² μ£Όμ ν μ μκ³ μλ-ꡬμ±μ μΈλΆ μ‘°μ ν μ μλ€.