๐ฌ[์คํ๋ง ๋ถํธ - ์ดํด์ ์๋ฆฌ] ์คํ๋ง ๋ถํธ ์์ธํ ์ดํด๋ณด๊ธฐ
์คํ๋ง ๋ถํธ์ ์๋ ๊ตฌ์ฑ๊ณผ ํ ์คํธ๋ก ์ ํ
์ง์ ๊ตฌํํ๋ ์๋ ๊ตฌ์ฑ ํด๋์ค์ ์ ๋
ธํ
์ด์
๋ฑ์ ์ ๊ฑฐํ๋ค.
๋ฉ์ธ ์ ๋
ธํ
์ด์
์ ์คํ๋ง ๋ถํธ์ @SpringBootApplication๋ก ๋ณ๊ฒฝํ๋ค.
@SpringBootApplication
public class HellobootApplication {
ํ ์คํธ์ฉ์ผ๋ก ์คํ๋ง ๋ถํธ๊ฐ ๋ง๋ค์ด์ฃผ๋ ๋ด์ฅํ DB๋ฅผ ์ด์ฉํด์ ๋ฐ์ดํฐ ์ก์ธ์ค ๋ก์ง๋ง ํ ์คํธ ํ ๋๋ @JdbcTest๋ฅผ ์ฌ์ฉ ํ ์ ์๋ค. ํ๋กํผํฐ๋ก ์ค์ ํ DB ์ ์ ์ ๋ณด๊ฐ ์ฌ์ฉ๋์ง ์์ผ๋ ์ฃผ์ํ ๊ฒ.
์คํ๋ง ์ปจํ
์ด๋๋ฅผ ๋์ฐ๊ณ ์๋ ๊ตฌ์ฑ๊น์ง ์ ์ฉํด์ ํ
์คํธ๋ฅผ ํ ๋๋ ์๋ธ๋ฆฟ ์ปจํ
์ด๋๋ฅผ ๋์ธ ๊ฒ์ธ๊ฐ์ ๋ฐ๋ผ์ ๋ค์ ๋ ๊ฐ์ง ๋ฐฉ์์ ์ฌ์ฉํ ์ ์๋ค.
๋กค๋ฐฑ ํ
์คํธ๋ฅผ ์ํด์๋ @Transactional์ ๋ฃ์ด์ค์ผ ํ๋ค.
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE)
@Transactional
public class HelloRepositoryTest {
์๋ธ๋ฆฟ ์ปจํ ์ด๋๋ฅผ ๋์์ HTTP ์์ฒญ์ ๋ณด๋ด์ ํ ์คํธ๋ฅผ ์ํํ ๋๋ ๋ค์๊ณผ ๊ฐ์ด ํ ์คํธ๋ฅผ ์ค๋นํ๋ค.
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
public class HelloApiTest {
ํ๋กํผํฐ์ ์ด๋ฆ์ ์คํ๋ง ๋ถํธ์ ์๋ ๊ตฌ์ฑ์์ ์ฌ์ฉํ๋ ๊ฒ์ผ๋ก ๋ณ๊ฒฝํด์ค์ผ ํ๋ค.
์คํ๋ง ๋ถํธ ์์ธํ ์ดํด๋ณด๊ธฐ
์คํ๋ง ๋ถํธ์ ๋์ ๋ฐฉ์์ ์ดํดํ๊ณ , ์์ ์ด ์ฌ์ฉํ๋ ๊ธฐ์ ๊ณผ ๊ด๋ จ๋ ์๋ ๊ตฌ์ฑ๊ณผ ํ๋กํผํฐ ๋ฑ์ ๋ถ์ํ๊ณ , ์ด๋ป๊ฒ ํ์ฉํ ์ ์๋์ง ํ์ ํ๋ ๊ฒ์ด ํ์ํ๋ค.
์คํ๋ง ๋ถํธ์ ์๋ ๊ตฌ์ฑ์ผ๋ก๋ถํฐ ํ์ตํ ๊ธฐ์ ์ ํ๋์ฉ ์ฐพ์์ ํ์ํ ๋ถ๋ถ์ ๊ณต๋ถํ๋ ์ ๊ทผ ๋ฐฉ๋ฒ๋ ์ ์ฉํ๋ค.
์๋ ๊ตฌ์ฑ ๋ถ์ ๋ฐฉ๋ฒ
- ์๋ ๊ตฌ์ฑ ํ๋ณด ๋ชฉ๋ก๊ณผ ์กฐ๊ฑด ํ๋จ ๊ฒฐ๊ณผ๋ฅผ ์กฐํํ๋ ค๋ฉด -Ddebug์ด๋ โdebug ์ธ์ ๊ฐ์ ์ด์ฉํด์ ์คํ๋ง ๋ถํธ ์ ํ๋ฆฌ์ผ์ด์ ์ ์์ํ๋ฉด ๋๋ค.
- ์ฝ๋๋ฅผ ์ด์ฉํ๋ ๋ฐฉ๋ฒ๋ ์ ๊ณต๋๋ค. ConditionEvaluationReport ํ์ ์ ๋น์ ์ฃผ์ ๋ฐ์์ ํ์ํ ์ ๋ณด๋ง ์ ํํด์ ์๋ ๊ตฌ์ฑ ๊ฒฐ๊ณผ๋ฅผ ๋ณด๋ ๊ฒ๋ ๊ฐ๋ฅํ๋ค.
- ์ต์ข ์ ์ผ๋ก ๋ฑ๋ก๋ ๋น ๋ชฉ๋ก์ ๋ณด๊ณ ์ถ์ผ๋ฉด ListableBeanFactory ํ์ ์ ๋น์ ์ฃผ์ ๋ฐ์์ ๋น ์ด๋ฆ์ ๋ชจ๋ ๊ฐ์ ธ์ค๊ณ , ํ์ํ๋ฉด ๋น ์ค๋ธ์ ํธ๋ ๊ฐ์ ธ์์ ์ดํด๋ณผ ์ ์๋ค.
์๋ ๊ตฌ์ฑ ์ ์ ๊ฒฐ๊ณผ๋ฅผ ๊ธฐ์ค์ผ๋ก ์คํ๋ง ๋ถํธ ๋ ํผ๋ฐ์ค ๋ฌธ์, ๊ทธ๋ฆฌ๊ณ ์๋ ๊ตฌ์ฑ ํด๋์ค์ ์์ค ์ฝ๋, ํ๋กํผํฐ ํด๋์ค, ์ปค์คํ ๋ง์ด์ ๋ฑ์ ์ฐจ๊ทผ์ฐจ๊ทผ ๋ฐ๋ผ์ ์ดํด๋ณด๋ฉด์ ์ด๋ป๊ฒ ์ด๋ค ์กฐ๊ฑด์ผ๋ก ๋์ํ ์ง ๋ถ์ํ๋ค.
์๋ ๊ตฌ์ฑ ์กฐ๊ฑด ๊ฒฐ๊ณผ ํ์ธ
ConditionEvaluationReport๋ฅผ ์ด์ฉํด์ ์กฐ๊ฑด์ด ๋งค์นญ๋ ์๋ ๊ตฌ์ฑ ํด๋์ค์ ๋ฉ์๋๋ฅผ ์ถ๋ ฅํ๋ ์ฝ๋๋ฅผ ์์ฑํ ์ ์๋ค. ๊ทธ ์ค์์ Jmx ๊ด๋ จ ๊ตฌ์ฑ ์ ๋ณด๋ ์ ์ธํ๊ณ ์ถ์ผ๋ฉด ์๋์ ๊ฐ์ด ์ฝ๋๋ฅผ ์์ฑํ๋ฉด ๋๋ค.
@Bean ApplicationRunner run(ConditionEvaluationReport report) {
return args -> {
System.out.println(report.getConditionAndOutcomesBySource().entrySet().stream()
.filter(co -> co.getValue().isFullMatch())
.filter(co -> co.getKey().indexOf("Jmx") < 0)
.map(co -> {
System.out.println(co.getKey());
co.getValue().forEach(c -> {
System.out.println("\t" + c.getOutcome());
});
System.out.println();
return co;
}).count());
};
}
Core ์๋ ๊ตฌ์ฑ ์ดํด๋ณด๊ธฐ
@ConditionalOnProperty ์กฐ๊ฑด์ธ ๊ฒฝ์ฐ matchIfMissing = true๋ผ๋ฉด ํ๋กํผํฐ๊ฐ ์กด์ฌํ์ง ์์๋ ์กฐ๊ฑด์ด ๋งค์นญ๋๋ค.
@AutoConfiguration
@ConditionalOnProperty(prefix = "spring.aop", name = "auto", havingValue = "true", matchIfMissing = true)
public class AopAutoConfiguration {
Web ์๋ ๊ตฌ์ฑ ์ดํด๋ณด๊ธฐ
์น ์คํํฐ๋ฅผ ์ถ๊ฐํ๊ธฐ๋ง ํด๋ 50๊ฐ ๊ฐ๊น์ด ์๋ ๊ตฌ์ฑ ํด๋์ค์ ๋น ๋ฉ์๋ ์กฐ๊ฑด์ด ์ถ๊ฐ๋๋ค.
@ConditionalOnClass ๋ฑ์ด ๋ถ์ ํด๋์ค์ @Import๊ฐ ๋ถ์ด์๋ ๊ฒฝ์ฐ์ ํด๋์ค ๋ ๋ฒจ์ ์กฐ๊ฑด์ด ๋ชจ๋ ๋ง์กฑํ๋ ๊ฒฝ์ฐ @Import๊ฐ ๋์ํด์ ์๋ ๊ตฌ์ฑ์ ์ถ๊ฐ์๊ธฐ๋ ํ๋ค.
@AutoConfiguration(
after = { GsonAutoConfiguration.class, JacksonAutoConfiguration.class, JsonbAutoConfiguration.class })
@ConditionalOnClass(HttpMessageConverter.class)
@Conditional(NotReactiveWebApplicationCondition.class)
@Import({ JacksonHttpMessageConvertersConfiguration.class, GsonHttpMessageConvertersConfiguration.class,
JsonbHttpMessageConvertersConfiguration.class })
public class HttpMessageConvertersAutoConfiguration {
Customizer ๋น์ ์ด์ฉํ๋ ์๋ ๊ตฌ์ฑ์ ํ๋กํผํฐ ๋น์ Customizer๊ฐ ์ฃผ์
์ ๋ฐ๊ณ , ์ด๋ฅผ ๋น ์ค๋ธ์ ํธ๋ฅผ ๋ง๋๋ ๋ฉ์๋์์ Customizer๋ฅผ ์ฃผ์
๋ฐ์์ ํ๋กํผํฐ ์ค์ ๋ก์ง์ ์ ์ฉํ๋ ๋ฐฉ์์ผ๋ก ๋์ํ๊ธฐ๋ ํ๋ค.
์ต์ข
๋น ์ค๋ธ์ ํธ๋ฅผ ๋ง๋๋ Builder๋ฅผ ๋น์ผ๋ก ๋ฑ๋กํ๋ ๊ฒฝ์ฐ๋ ์๋ค. ์ด ๋น๋ ๋น์ ์ ํ๋ฆฌ์ผ์ด์
์์ ๊ฐ์ ธ๋ค ์ฌ์ฉํด์ ๋น ์ค๋ธ์ ํธ๋ฅผ ์ง์ ๊ตฌ์ฑํ๋ ๊ฒ๋ ๊ฐ๋ฅํ๋ค.
RestTemplateBuilder ์ฒ๋ผ ๋น๋๋ง ์๋ ๊ตฌ์ฑ์ผ๋ก ์ ๊ณตํ๋ ๊ฒฝ์ฐ๋ ์๋ค.
@Bean
@Lazy
@ConditionalOnMissingBean
public RestTemplateBuilder restTemplateBuilder(RestTemplateBuilderConfigurer restTemplateBuilderConfigurer) {
RestTemplateBuilder builder = new RestTemplateBuilder();
return restTemplateBuilderConfigurer.configure(builder);
}
Jdbc ์๋ ๊ตฌ์ฑ ์ดํด๋ณด๊ธฐ
DataSource ์๋ ๊ตฌ์ฑ์์ driver class name์ ํ๋กํผํฐ์ ๋ฃ์ง ์์ผ๋ฉด url์ ์ด์ฉํด์ ๋๋ผ์ด๋ฒ์ ํด๋์ค ์ด๋ฆ์ ๋ฃ์ด์ค๋ค. ๋ด์ฅํ DB๋ฅผ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ์ DataSource ํ๋กํผํฐ๊ฐ ์์ผ๋ฉด ์คํ๋ง ๋ถํธ๊ฐ ์๋์ผ๋ก ์ฐ๊ฒฐ ์ ๋ณด๋ฅผ ์ค์ ํด์ค๋ค.
JdbcTransactionManager๋ ๊ธฐ์กด DataSourceTransactionManager์ ์์ธ ์ถ์ํ ์์
์ ๋ณ๊ฒฝ์ด ๋ฐ์๋์ด์๋ค. ๊ธฐ์กด ๋ฒ
์ ๊ณผ ํธํ์ ์ํด์ ํ๋กํผํฐ๋ฅผ ์ง์ ํ ๊ฒฝ์ฐ์๋ง ์ ํ๋๋ค.
@AutoConfiguration์ ์๋ ๊ตฌ์ฑ์ ์งํํ ์ ํ ์์๋ฅผ ์ง์ ํ ์ ์๋ค.
@AutoConfiguration(after = DataSourceAutoConfiguration.class)
TransactionProperties๋ PlatformTransactionManagerCustomizer๋ฅผ ๊ตฌํํ๋ค. ํ๋กํผํฐ ํด๋์ค๊ฐ ์์ ์ด ๊ฐ์ง ๊ฐ์ ์ด์ฉํ๋ ๊ฐ๋จํ Customizer ๊ธฐ๋ฅ์ ๊ตฌํํด์ ์ฌ์ฉํ๋๊ธฐ๋ ํ๋ค.
@ConfigurationProperties(prefix = "spring.transaction")
public class TransactionProperties implements PlatformTransactionManagerCustomizer<AbstractPlatformTransactionManager> {
๋๊ธ๋จ๊ธฐ๊ธฐ