이 페이지의 MockBean, SpyBean, test slice, logging configuration 예시는 source 작성 시점의 Spring Boot 관례다. 자동 설정의 조건부 조합 원리는 유지하되, 특정 annotation과 property를 현재 version의 기본값으로 해석하지 않는다.
Spring Framework Core가 제공하는 IoC/DI/AOP/PSA 위에서, Spring Boot는 classpath에 있는 의존성을 보고 필요한 Bean을 자동으로 구성한다. @SpringBootApplication이 이 "zero config" 시작점이고, Spring MVC Controller의 DispatcherServlet/HandlerMapping/ViewResolver도 이 메커니즘으로 자동 등록된다.
@SpringBootApplication = 3개 어노테이션 조합@SpringBootConfiguration // ① Spring Boot 전용 @Configuration
@EnableAutoConfiguration // ② 클래스패스 기반 Bean 자동 등록
@ComponentScan // ③ @Component 스캔 (메인 클래스 패키지 + 하위)
public class App {
public static void main(String[] args) {
SpringApplication.run(App.class, args);
}
}
| 어노테이션 | 역할 |
|---|---|
@SpringBootConfiguration |
Spring Boot의 설정 클래스임을 표시. 내부적으로 @Configuration을 상속하며, 같은 방식으로 Spring Container에 Bean을 등록한다.[1] |
@EnableAutoConfiguration |
사전 정의된 라이브러리 의존성(starter) 기반으로 필요한 Bean을 자동 생성·등록한다. AutoConfiguration.imports 파일에서 자동 설정 클래스를 읽고, @ConditionalOnClass/@ConditionalOnMissingBean 등 @Conditional 계열로 조건부 등록한다.[2] |
@ComponentScan |
@SpringBootApplication이 붙은 클래스 패키지와 하위 패키지를 스캔해 @Controller, @Service, @Repository, @Configuration 등을 Bean으로 등록한다. 메인 클래스는 프로젝트 최상단 패키지에 위치해야 한다.[3] |
@Conditional 계열 — 자동 설정의 핵심| 어노테이션 | 조건 |
|---|---|
@ConditionalOnClass |
특정 클래스가 클래스패스에 존재할 때만 Bean 등록 |
@ConditionalOnMissingBean |
사용자가 정의한 동일 타입 Bean이 없을 때만 Bean 등록 |
@ConditionalOnBean |
특정 Bean이 이미 등록되어 있을 때만 추가 Bean 등록 |
@ConditionalOnProperty |
특정 property가 설정돼 있을 때만 Bean 등록 |
예를 들어 spring-boot-starter-web이 클래스패스에 있으면 내장 Tomcat(ServletWebServerFactory)과 DispatcherServlet을 자동 등록한다.[2:1] 원문의 일반 규칙("사용자가 정의한 동일한 타입의 Bean이 없을 때만" 조건부 등록)을 이 사례에 적용하면,[2:2] 사용자가 직접 DispatcherServlet Bean을 만들 때 @ConditionalOnMissingBean으로 자동 등록이 건너뛰어진다고 볼 수 있다. 이 적용은 이 page의 해석이다.
공식 문서 기준으로 이 메커니즘의 경계는 다음과 같다.
DataSource Bean을 추가하면 기본 embedded database 지원은 물러난다(back off).[4:1]@SpringBootApplication 또는 @EnableAutoConfiguration으로 opt-in한다. exclude 속성으로 특정 auto-configuration 클래스를 끌 수 있다.[5]| 테스트 종류 | 로드 범위 | 속도 | 용도 |
|---|---|---|---|
@SpringBootTest(통합) |
모든 Spring Bean + 환경 설정[6] | 느림 | Controller→Service→Repository→DB 전체 연동 검증 |
@WebMvcTest(슬라이스) |
Controller + 웹 MVC 관련만(HandlerMapping/ViewResolver/Filter)[7] | 빠름 | Controller 단위. Service/Repository는 @MockBean으로 대체 |
@DataJpaTest(슬라이스) |
JPA 관련 Bean만. @Transactional 포함(테스트 후 자동 롤백)[7:1] |
빠름 | Repository 계층. 임베디드 DB(H2) 기본 |
@MockBean은 Spring Container에 Mock 객체를 Bean으로 등록하고, 이미 동일 타입 실제 Bean이 있으면 Mock으로 교체한다. @SpyBean은 실제 Bean을 래핑해 지정한 메서드만 stubbing하고 나머지는 실제 구현을 호출한다.[8]
Spring Boot는 spring-boot-starter-logging으로 SLF4J(API) + Logback(구현체)를 기본 채택한다.[9]
TRACE < DEBUG < INFO < WARN < ERRORapplication.properties에서 logging.level.root=info, logging.level.com.example=debug 설정logback-spring.xml의 <springProfile> 태그로 개발/운영 환경별 로깅 전략 분리 가능[9:1]@ComponentScan 대상이 빠지는 경우.@ConditionalOnMissingBean을 이해하지 못하고 자동 설정 Bean을 덮어썼는데 자동 설정을 기대하는 경우 — 또는 반대로 덮어쓴 줄 모르고 자동 설정이 계속 동작하는 경우.@SpringBootTest로만 작성해 전체 컨테이너를 매번 로드하는 경우 — 테스트 속도가 급감한다.@WebMvcTest에서 Service를 Mock 처리하지 않고 실제 Bean을 기대하는 경우 — 슬라이스 테스트는 Service/Repository를 로드하지 않는다.@SpyBean을 @MockBean처럼 써서 모든 메서드를 stub하면 "실제 구현 호출"이라는 이점이 사라진다.System.out.println으로 디버깅하는 경우 — 운영 환경에서 로그가 남지 않는다.spring-boot-starter-web 감지 시 DispatcherServlet/HandlerMapping/ViewResolver 자동 등록.@SpringBootApplication을 구성하는 3개 어노테이션과 각 역할은?@ConditionalOnClass와 @ConditionalOnMissingBean이 자동 설정에서 어떤 역할을 하는가?@WebMvcTest가 Service/Repository Bean을 로드하지 않는 이유와, 그 대안은?@MockBean과 @SpyBean의 차이와 선택 기준은?Spring Boot.md — "내부적으로 스프링의 @Configuration을 상속받고 있어, 스프링 컨테이너에 Bean을 등록하는 설정 클래스 역할을 동일하게 수행합니다." ↩︎
Spring Boot.md — "META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports 파일... 에 정의된 수많은 자동 설정 클래스들을 읽어 들입니다.", "@ConditionalOnClass, @ConditionalOnMissingBean 등 @Conditional 계열 어노테이션을 사용하여 ... "사용자가 정의한 동일한 타입의 Bean이 없을 때만" 조건부로 Bean을 등록합니다."(L39), "spring-boot-starter-web이 존재하면 내장 Tomcat(ServletWebServerFactory)과 DispatcherServlet을 자동으로 등록합니다."(L40) ↩︎ ↩︎ ↩︎
Spring Boot.md — "@SpringBootApplication이 붙은 클래스가 위치한 패키지와 그 하위 패키지가 기본 스캔 범위가 됩니다. 따라서 메인 클래스는 프로젝트 구조의 최상단 패키지에 위치해야 합니다." ↩︎
spring-boot-official-auto-configuration.md — "Spring Boot auto-configuration attempts to automatically configure your Spring application based on the jar dependencies that you have added. For example, if HSQLDB is on your classpath...", "Auto-configuration is non-invasive... if you add your own DataSource bean, the default embedded database support backs away." ↩︎ ↩︎
spring-boot-official-auto-configuration.md — "You need to opt-in to auto-configuration by adding the @EnableAutoConfiguration or @SpringBootApplication annotations...", "you can use the exclude attribute of @SpringBootApplication to disable them." ↩︎
Spring Boot.md — "실제 애플리케이션을 구동할 때와 유사하게 모든 Spring Bean과 환경 설정을 로드하여 테스트를 진행합니다." ↩︎
Spring Boot.md — "Controller와 웹 MVC 관련 설정(HandlerMapping, ViewResolver, Filter 등)만 로드합니다.", "@Transactional을 기본적으로 포함하고 있어 테스트 완료 후 자동으로 롤백됩니다." ↩︎ ↩︎
Spring Boot.md — "@MockBean: 스프링 컨테이너에 Mock(가짜) 객체를 빈으로 등록합니다. 이미 동일한 타입의 실제 Bean이 컨테이너에 있다면 Mock Bean으로 교체됩니다.", "@SpyBean: 실제 Bean을 래핑하여 특정 메서드만 동작을 모킹(Stubbing)하고, 지정하지 않은 메서드는 실제 구현을 호출하도록 제어합니다." ↩︎