Spring Boot 완벽 정리
1. Spring Boot 소개
1) Spring Boot란?
Spring Boot는 Spring 프레임워크를 기반으로 한 경량화된 애플리케이션 개발 프레임워크입니다. 기존의 Spring 프레임워크보다 설정이 간편하고, 내장 서버를 제공하여 빠르게 애플리케이션을 실행할 수 있도록 설계되었습니다.
2) Spring Framework와 Spring Boot의 차이
특징Spring FrameworkSpring Boot
| 설정 | XML 기반 설정 필요 | 최소한의 설정 (Annotation 기반) |
| 서버 | 별도 톰캣 등 필요 | 내장 Tomcat, Jetty 지원 |
| 의존성 관리 | 수동 설정 필요 | starter로 자동 관리 |
| 코드 작성 | 복잡한 보일러플레이트 코드 포함 | 간단한 코드로 개발 가능 |
3) Spring Boot의 주요 기능
- 의존성 관리: spring-boot-starter를 이용한 간편한 라이브러리 관리
- 자동 구성(Auto Configuration): 최소한의 설정으로 실행 가능한 기본 환경 제공
- 내장 서버: 톰캣(Tomcat), 제티(Jetty) 등 내장 웹 서버 제공
- 외부 설정 지원: application.properties 또는 application.yml을 이용한 설정 가능
- 관점 지향 프로그래밍(AOP): 핵심 로직과 공통 로직을 분리하여 코드 간결화
- 테스트 지원: JUnit과 통합된 강력한 테스트 환경 제공
4) Spring Boot 프로젝트 생성
Spring Boot 프로젝트는 Spring Initializr를 사용하여 손쉽게 생성할 수 있습니다.
프로젝트 생성 방법
- Spring Initializr 웹 사이트 이용: https://start.spring.io/
- IDE(IntelliJ, STS)에서 생성
- Maven 또는 Gradle로 직접 생성
예제: Gradle 기반 Spring Boot 프로젝트
plugins {
id 'org.springframework.boot' version '3.0.0'
id 'io.spring.dependency-management' version '1.0.15.RELEASE'
id 'java'
}
group = 'com.example'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '17'
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
tasks.named('test') {
useJUnitPlatform()
}
2. Spring IoC (Inversion of Control, 제어의 역전)
1) IoC란?
Spring의 가장 핵심적인 개념 중 하나로, 객체의 생성 및 관리 주체를 개발자가 아닌 프레임워크(Spring Container)가 담당하도록 하는 원리입니다. IoC를 사용하면 객체 간의 의존성이 최소화되며, 유지보수성이 향상됩니다.
2) Spring IoC의 핵심 구성 요소
| 구성 요소 | 설명 |
| Bean | Spring 컨테이너에서 관리하는 객체 |
| ApplicationContext | Bean을 생성하고 관리하는 컨테이너 |
| Dependency Injection | 객체 간의 의존성을 외부에서 주입하는 기법 |
3) IoC 컨테이너 사용 예제
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class Main {
public static void main(String[] args) {
ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
MyService myService = context.getBean(MyService.class);
myService.doSomething();
}
}
3. 의존성 주입 (Dependency Injection, DI)
1) DI란?
**의존성 주입(DI, Dependency Injection)**은 객체를 직접 생성하는 것이 아니라, 외부에서 객체를 주입받는 방식을 의미합니다. 이를 통해 객체 간의 결합도를 줄이고, 유연한 코드 구조를 만들 수 있습니다.
2) 의존성 주입 방식
| 방식 | 설명 |
| 생성자 주입 | 생성자를 이용하여 의존성을 주입 |
| 필드 주입 | @Autowired를 이용하여 필드에 직접 주입 |
| 메서드 주입 | Setter 메서드를 이용하여 주입 |
3) 생성자 주입 예제
import org.springframework.stereotype.Service;
@Service
public class UserService {
private final UserRepository userRepository;
public UserService(UserRepository userRepository) {
this.userRepository = userRepository;
}
public User getUser(Long id) {
return userRepository.findById(id).orElse(null);
}
}
4) 필드 주입 예제 (@Autowired 사용)
@Service
public class UserService {
@Autowired
private UserRepository userRepository;
}
5) Setter 주입 예제
@Service
public class UserService {
private UserRepository userRepository;
@Autowired
public void setUserRepository(UserRepository userRepository) {
this.userRepository = userRepository;
}
}
4. Spring Boot 코드 구조 살펴보기
Spring Boot 프로젝트는 계층적인 구조를 가지며, 주요 디렉터리 및 파일의 역할을 이해하는 것이 중요합니다.
1) Spring Boot 프로젝트 구조 예시
my-spring-boot-app/
├── src/
│ ├── main/
│ │ ├── java/com/example/demo/
│ │ │ ├── DemoApplication.java # Spring Boot 메인 클래스
│ │ │ ├── controller/ # 컨트롤러 (웹 요청 처리)
│ │ │ ├── service/ # 서비스 (비즈니스 로직)
│ │ │ ├── repository/ # 데이터 액세스 계층
│ │ │ ├── config/ # 설정 관련 클래스
│ │ ├── resources/
│ │ │ ├── application.properties # 환경 설정 파일
│ │ │ ├── static/ # 정적 리소스 (CSS, JS, 이미지)
│ │ │ ├── templates/ # 템플릿 파일 (Thymeleaf 등)
│ ├── test/java/com/example/demo/ # 테스트 코드
├── pom.xml (Maven 설정 파일)
├── build.gradle (Gradle 설정 파일)
2) 주요 파일 및 폴더 설명
폴더/파일설명
| DemoApplication.java | 애플리케이션의 진입점, @SpringBootApplication 포함 |
| controller/ | 웹 요청을 처리하는 클래스 (@RestController 사용) |
| service/ | 비즈니스 로직을 처리하는 클래스 (@Service 사용) |
| repository/ | 데이터 액세스 계층 (@Repository 사용) |
| config/ | 설정 클래스 (예: CORS 설정, AOP 설정) |
| application.properties | 애플리케이션 환경 설정 파일 |
| static/ | 정적 리소스 (HTML, CSS, JavaScript) |
| templates/ | Thymeleaf, Freemarker 등의 템플릿 파일 |
5. 자동 구성(Auto Configuration)과 조건(Conditional)
1) 자동 구성(Auto Configuration)이란?
Spring Boot는 자동 구성(Auto Configuration) 기능을 제공하여, 기본 설정을 자동으로 수행합니다. 예를 들어, spring-boot-starter-web을 추가하면 자동으로 내장 톰캣과 MVC 설정이 활성화됩니다.
2) @SpringBootApplication과 자동 구성
@SpringBootApplication은 다음 3가지 기능을 포함합니다.
@SpringBootApplication = @Configuration + @EnableAutoConfiguration + @ComponentScan
- @Configuration → Java 기반 설정을 위한 클래스 지정
- @EnableAutoConfiguration → Spring Boot의 자동 설정 활성화
- @ComponentScan → 패키지를 스캔하여 @Component, @Service, @Repository 등을 자동으로 등록
3) @Conditional을 활용한 조건부 빈 등록
@Conditional을 사용하면 특정 조건에서만 빈을 등록할 수 있습니다.
@Configuration
@ConditionalOnProperty(name = "feature.enabled", havingValue = "true")
public class FeatureConfig {
@Bean
public FeatureService featureService() {
return new FeatureService();
}
}
- feature.enabled=true로 설정된 경우 FeatureService 빈이 활성화됩니다.
6. 외부 구성(Externalized Configuration)
Spring Boot는 환경 변수, 프로퍼티 파일 등을 통해 애플리케이션 설정을 외부에서 쉽게 변경할 수 있도록 지원합니다.
1) application.properties 또는 application.yml
Spring Boot에서는 application.properties 또는 application.yml 파일을 사용하여 설정을 관리합니다.
server.port=8081 # 서버 포트 변경
spring.datasource.url=jdbc:mysql://localhost:3306/mydb # 데이터베이스 연결 정보
spring.profiles.active=dev # 활성화할 프로필 설정
2) @Value를 활용한 설정 값 주입
@Value("${server.port}")
private int serverPort;
3) @ConfigurationProperties를 이용한 설정 값 바인딩
@ConfigurationProperties(prefix = "app")
@Component
public class AppConfig {
private String name;
private int version;
// Getter, Setter
}
app.name=MySpringBootApp
app.version=1
7. 관점 지향 프로그래밍(AOP) - 1
1) AOP란?
AOP(Aspect-Oriented Programming, 관점 지향 프로그래밍)는 핵심 로직과 부가 기능(로깅, 트랜잭션, 보안 등)을 분리하는 개념입니다. AOP를 사용하면 코드 중복을 줄이고, 유지보수성을 높일 수 있습니다.
2) Spring AOP의 주요 개념
| 개념 | 설명 |
| Aspect | 공통 기능(로깅, 트랜잭션 등)을 모아둔 모듈 |
| Advice | Aspect에서 수행하는 기능 (Before, After 등) |
| JoinPoint | Advice가 적용될 실행 지점 |
| Pointcut | 특정 JoinPoint를 지정하는 표현식 |
3) AOP 예제 (메서드 실행 전후 로깅)
@Aspect
@Component
public class LoggingAspect {
@Before("execution(* com.example.service.*.*(..))")
public void logBefore(JoinPoint joinPoint) {
System.out.println("Method 호출 전: " + joinPoint.getSignature().getName());
}
@After("execution(* com.example.service.*.*(..))")
public void logAfter(JoinPoint joinPoint) {
System.out.println("Method 호출 후: " + joinPoint.getSignature().getName());
}
}
- @Before → 메서드 실행 전 로그 출력
- @After → 메서드 실행 후 로그 출력
- execution(* com.example.service.*.*(..)) → com.example.service 패키지의 모든 메서드에 적용
4) AOP 적용 대상 예제
@Service
public class UserService {
public void getUser() {
System.out.println("유저 정보를 가져옵니다.");
}
}
- UserService.getUser() 실행 시 AOP가 동작하여 로깅이 수행됩니다.
8. 관점 지향 프로그래밍(AOP) - 2
1) AOP의 주요 개념 심화
Spring AOP를 사용하면 핵심 로직과 공통 기능을 분리하여 코드 중복을 줄이고 유지보수성을 향상할 수 있습니다. 다양한 어드바이스(Advice)와 포인트컷(Pointcut) 표현식을 활용하여 보다 정교한 AOP를 구현할 수 있습니다.
2) AOP의 다양한 Advice 유형
Advice 유형설명
| @Before | 메서드 실행 전에 실행됨 |
| @After | 메서드 실행 후에 실행됨 |
| @AfterReturning | 정상적으로 실행 후 결과값 반환 시 실행됨 |
| @AfterThrowing | 예외 발생 시 실행됨 |
| @Around | 메서드 실행 전후에 실행되며 직접 실행 여부를 결정 |
3) @Around Advice를 활용한 실행 시간 측정
@Aspect
@Component
public class ExecutionTimeAspect {
@Around("execution(* com.example.service.*.*(..))")
public Object logExecutionTime(ProceedingJoinPoint joinPoint) throws Throwable {
long start = System.currentTimeMillis();
Object result = joinPoint.proceed();
long elapsedTime = System.currentTimeMillis() - start;
System.out.println(joinPoint.getSignature() + " 실행 시간: " + elapsedTime + "ms");
return result;
}
}
- @Around를 사용하여 메서드 실행 전후의 시간을 측정하고 출력합니다.
4) 특정 클래스에만 AOP 적용
@Pointcut("within(com.example.controller..*)")
public void controllerMethods() {}
@Before("controllerMethods()")
public void beforeControllerMethod(JoinPoint joinPoint) {
System.out.println("컨트롤러 메서드 실행 전: " + joinPoint.getSignature().getName());
}
- within(com.example.controller..*) → 특정 패키지 내 클래스에만 AOP를 적용합니다.
9. Spring Boot 테스트
1) Spring Boot에서 테스트의 중요성
Spring Boot는 강력한 테스트 지원 기능을 제공합니다. 테스트를 작성하면 코드 변경 후에도 기능이 정상적으로 동작하는지 검증할 수 있습니다.
2) 주요 테스트 종류
| 테스트 유형 | 설명 |
| 단위 테스트 (Unit Test) | 특정 클래스나 메서드를 개별적으로 테스트 |
| 통합 테스트 (Integration Test) | 여러 컴포넌트가 함께 동작하는지 검증 |
| 웹 테스트 (Web Test) | REST API가 정상적으로 동작하는지 검증 |
3) 단위 테스트 예제 (@SpringBootTest 활용)
@SpringBootTest
public class UserServiceTest {
@Autowired
private UserService userService;
@Test
public void testGetUser() {
User user = userService.getUser(1L);
assertNotNull(user);
}
}
- @SpringBootTest → Spring Boot 환경에서 테스트 실행
- @Autowired → 테스트에서 빈을 주입받아 사용
4) MockMvc를 이용한 웹 테스트 예제
@WebMvcTest(UserController.class)
public class UserControllerTest {
@Autowired
private MockMvc mockMvc;
@Test
public void testGetUser() throws Exception {
mockMvc.perform(get("/users/1"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.name").value("John Doe"));
}
}
- @WebMvcTest → 웹 계층만 테스트하도록 설정
- MockMvc → HTTP 요청을 모의로 실행하여 응답 검증
10. 로깅 시스템
1) Spring Boot에서 로깅의 중요성
Spring Boot는 SLF4J(Simple Logging Facade for Java)와 Logback을 기본 로깅 시스템으로 제공합니다. 로깅을 활용하면 애플리케이션의 실행 정보를 기록하고, 디버깅 및 성능 모니터링에 활용할 수 있습니다.
2) 기본 로깅 설정 (application.properties)
logging.level.root=INFO
logging.level.com.example=DEBUG
logging.file.name=application.log
- logging.level.root=INFO → 전체 애플리케이션의 기본 로그 레벨을 INFO로 설정
- logging.level.com.example=DEBUG → 특정 패키지의 로그 레벨을 DEBUG로 설정
- logging.file.name=application.log → 로그를 파일로 저장
3) @Slf4j를 활용한 로깅 예제
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
@Slf4j
@Service
public class UserService {
public void getUser(Long id) {
log.info("사용자 조회: ID={}", id);
}
}
- @Slf4j → Lombok에서 제공하는 간편한 로깅 어노테이션
- log.info() → 로그 레벨 INFO로 메시지를 출력
4) 로그 레벨
| 레벨 | 설명 |
| TRACE | 가장 상세한 로그 (디버깅 용도) |
| DEBUG | 디버깅 정보를 출력 |
| INFO | 일반적인 실행 정보 (기본값) |
| WARN | 경고 메시지 출력 |
| ERROR | 오류 발생 시 출력 |
11. 결론
Spring Boot는 자동 설정, 외부 구성, AOP, 테스트, 로깅 등 강력한 기능을 제공하며, 이를 활용하면 생산성을 극대화하고 유지보수성을 향상할 수 있습니다.
🛠 Spring Boot 핵심 정리
- 자동 구성(Auto Configuration) → 설정 없이 즉시 실행 가능
- 외부 설정(Externalized Configuration) → 환경별 설정 관리
- 관점 지향 프로그래밍(AOP) → 공통 기능 분리로 코드 간결화
- 테스트 지원 → 강력한 단위 테스트 및 통합 테스트 기능
- 로깅 시스템 → 실행 정보를 기록하고 디버깅 지원
'개발 이론 > Spring' 카테고리의 다른 글
| SSR (0) | 2025.03.18 |
|---|---|
| Spring, Spring Boot, JPA의 정의 (0) | 2025.03.01 |
| Spring Security (0) | 2025.02.20 |
| Spring MVC (0) | 2025.02.20 |