질문 리스트
스프링 프레임워크란 무엇인가요?
스프링 프레임워크(Spring Framework)
자바 플랫폼을 위한 오픈소스 애플리케이션 개발 프레임워크
스프링의 두가지 특징
IoC (Inversion of Control, 제어의 역전)
객체의 생성과 의존성 관리를 개발자가 직접 하지 않고, 스프링 컨테이너가 대신 관리하는 것
AOP (Aspect-Oriented Programming, 관점 지향 프로그래밍)
핵심 비즈니스 로직과 공통 관심사(로깅, 트랜잭션 관리 등)를 분리하여 개발하는 것
스프링은 이런 기능들을 기반으로
생산성과 확장성 높은 애플리케이션을 쉽게 개발할 수 있도록 지원합니다.
* 스프링의 다양한 기술스택
Spring MVC (웹 애플리케이션 개발)
Spring JDBC, Spring Data JPA (데이터베이스 연동)
Spring Security (보안 처리)
Spring Batch (대량 데이터 처리)
Spring Boot (스프링 설정 자동화 및 간소화)
자바 플랫폼을 위한 오픈소스 애플리케이션 개발 프레임워크
스프링의 두가지 특징
IoC (Inversion of Control, 제어의 역전)
객체의 생성과 의존성 관리를 개발자가 직접 하지 않고, 스프링 컨테이너가 대신 관리하는 것
AOP (Aspect-Oriented Programming, 관점 지향 프로그래밍)
핵심 비즈니스 로직과 공통 관심사(로깅, 트랜잭션 관리 등)를 분리하여 개발하는 것
스프링은 이런 기능들을 기반으로
생산성과 확장성 높은 애플리케이션을 쉽게 개발할 수 있도록 지원합니다.
* 스프링의 다양한 기술스택
Spring MVC (웹 애플리케이션 개발)
Spring JDBC, Spring Data JPA (데이터베이스 연동)
Spring Security (보안 처리)
Spring Batch (대량 데이터 처리)
Spring Boot (스프링 설정 자동화 및 간소화)
IoC와 DI란 무엇인가요?
IoC (Inversion of Control, 제어의 역전)
객체의 생성과 생명주기 관리 권한을 개발자가 아닌 스프링 컨테이너가 가지는 것을 말합니다.
일반적으로 자바에서는 객체를 개발자가 new 키워드로 생성하고 조립했지만,
스프링에서는 컨테이너가 대신 객체를 생성하고 조립해줍니다.
이렇게 개발자가 직접 제어하던 객체 생성/관리를 스프링 컨테이너로 "역전"시키는 것이 IoC입니다.
객체의 생성과 생명주기 관리 권한을 개발자가 아닌 스프링 컨테이너가 가지는 것을 말합니다.
일반적으로 자바에서는 객체를 개발자가 new 키워드로 생성하고 조립했지만,
스프링에서는 컨테이너가 대신 객체를 생성하고 조립해줍니다.
이렇게 개발자가 직접 제어하던 객체 생성/관리를 스프링 컨테이너로 "역전"시키는 것이 IoC입니다.
DI (Dependency Injection, 의존성 주입)
IoC를 구현하는 구체적인 방법 중 하나입니다.
즉, 필요한 객체(의존 객체)를 개발자가 직접 생성하지 않고, 스프링 컨테이너가 대신 생성한 후, 필요한 객체를 주입(inject) 해주는 방식입니다.
주입 방법
생성자 주입 (Constructor Injection)
필드 주입 (Field Injection)
Setter 주입 (Setter Injection)
DI 주입 방식 중 가장 추천하는 방식은 무엇인가요?
DI(Dependency Injection) 주입 방식에는 생성자 주입, 필드 주입, Setter 주입이 있습니다.
이 중에서 가장 권장되는 방식은 생성자 주입(Constructor Injection) 입니다.
그 이유는 다음과 같습니다:
1. 불변성(Immutable) 보장
의존 객체를 생성 시점에만 주입받기 때문에, 이후에 의존 객체가 변경될 위험이 없습니다.
2. 필수 의존성 보장
생성자 주입을 사용하면 객체가 생성될 때 필요한 의존성이 모두 주입되어야 하므로,
주입이 누락될 가능성이 원천 차단됩니다. (컴파일/런타임 오류로 빠르게 감지)
3. 단위 테스트 용이성
생성자를 통해 Mock 객체나 테스트용 객체를 주입하기 쉽기 때문에,
테스트 코드 작성이 훨씬 수월해집니다.
스프링이 제공하는 기능 없이도 테스트 가능
필드 주입(Field Injection)처럼 스프링 컨테이너가 없어도 객체를 직접 생성해 테스트할 수 있습니다.
이 중에서 가장 권장되는 방식은 생성자 주입(Constructor Injection) 입니다.
그 이유는 다음과 같습니다:
1. 불변성(Immutable) 보장
의존 객체를 생성 시점에만 주입받기 때문에, 이후에 의존 객체가 변경될 위험이 없습니다.
2. 필수 의존성 보장
생성자 주입을 사용하면 객체가 생성될 때 필요한 의존성이 모두 주입되어야 하므로,
주입이 누락될 가능성이 원천 차단됩니다. (컴파일/런타임 오류로 빠르게 감지)
3. 단위 테스트 용이성
생성자를 통해 Mock 객체나 테스트용 객체를 주입하기 쉽기 때문에,
테스트 코드 작성이 훨씬 수월해집니다.
스프링이 제공하는 기능 없이도 테스트 가능
필드 주입(Field Injection)처럼 스프링 컨테이너가 없어도 객체를 직접 생성해 테스트할 수 있습니다.
스프링에서 빈(Bean)이란 무엇인가요? 생명주기는 어떻게 되나요?
스프링에서 빈(Bean) 이란, 스프링 컨테이너가 생성하고 관리하는 객체를 말합니다.
일반적으로 우리가 작성한 클래스에 @Component, @Service, @Repository, @Controller 등의 어노테이션을 붙이거나, @Bean을 사용해 등록하면 스프링이 해당 객체를 빈으로 관리하게 됩니다.
스프링 컨테이너(ApplicationContext)는 이러한 빈들을 생성, 의존성 주입, 소멸까지 관리합니다.
스프링 빈의 생명주기(Bean Life Cycle)
1. 빈 생성
스프링이 클래스의 객체를 생성합니다. (new)
2. 의존성 주입 (DI)
생성자, 필드, setter 등을 통해 필요한 의존 객체를 주입합니다.
3. 초기화 콜백
@PostConstruct 메서드 실행
또는 InitializingBean.afterPropertiesSet() 실행
또는 initMethod 설정된 메서드 실행
4. 사용 (서비스 로직 수행)
실제 애플리케이션에서 빈이 사용됩니다.
5. 소멸 콜백 (종료 전 정리 작업)
@PreDestroy 메서드 실행
또는 DisposableBean.destroy() 호출
또는 destroyMethod 설정된 메서드 실행
일반적으로 우리가 작성한 클래스에 @Component, @Service, @Repository, @Controller 등의 어노테이션을 붙이거나, @Bean을 사용해 등록하면 스프링이 해당 객체를 빈으로 관리하게 됩니다.
스프링 컨테이너(ApplicationContext)는 이러한 빈들을 생성, 의존성 주입, 소멸까지 관리합니다.
스프링 빈의 생명주기(Bean Life Cycle)
1. 빈 생성
스프링이 클래스의 객체를 생성합니다. (new)
2. 의존성 주입 (DI)
생성자, 필드, setter 등을 통해 필요한 의존 객체를 주입합니다.
3. 초기화 콜백
@PostConstruct 메서드 실행
또는 InitializingBean.afterPropertiesSet() 실행
또는 initMethod 설정된 메서드 실행
4. 사용 (서비스 로직 수행)
실제 애플리케이션에서 빈이 사용됩니다.
5. 소멸 콜백 (종료 전 정리 작업)
@PreDestroy 메서드 실행
또는 DisposableBean.destroy() 호출
또는 destroyMethod 설정된 메서드 실행
AOP란 무엇인가요? 왜 필요한가요?
AOP (Aspect-Oriented Programming, 관점 지향 프로그래밍)
공통 관심사(부가 기능)를 핵심 비즈니스 로직과 분리하여 모듈화하는 프로그래밍 기법입니다.
예를 들어, 로깅, 트랜잭션 처리, 보안 체크, 실행 시간 측정 같은 기능은 여러 서비스 로직에서 중복되거나 흩어져서 작성되기 쉽습니다. AOP를 사용하면 이러한 공통 기능을 별도의 클래스로 분리하고, 핵심 로직에는 영향을 주지 않고 자동으로 삽입할 수 있습니다.
공통 관심사(부가 기능)를 핵심 비즈니스 로직과 분리하여 모듈화하는 프로그래밍 기법입니다.
예를 들어, 로깅, 트랜잭션 처리, 보안 체크, 실행 시간 측정 같은 기능은 여러 서비스 로직에서 중복되거나 흩어져서 작성되기 쉽습니다. AOP를 사용하면 이러한 공통 기능을 별도의 클래스로 분리하고, 핵심 로직에는 영향을 주지 않고 자동으로 삽입할 수 있습니다.
* 왜 필요한가요? (AOP의 도입 이유)
1. 관심사 분리 (Separation of Concerns)
핵심 비즈니스 로직과 부가 기능(로깅, 보안 등)을 명확히 분리할 수 있어 가독성, 유지보수성이 향상됩니다.
2. 중복 코드 제거
공통 로직을 한 곳에 모아두기 때문에, 여러 클래스에서 반복 작성할 필요가 없습니다.
3. 유연한 확장
핵심 코드를 변경하지 않고도 기능을 추가하거나 제거할 수 있습니다.
* 스프링에서 AOP 구현 방법
스프링 AOP는 주로 프록시 기반 AOP 방식으로 구현됩니다.
@Aspect, @Around, @Before, @After 등의 어노테이션을 사용해 공통 기능을 정의합니다.
스프링 MVC 패턴의 흐름을 설명해주세요.
스프링 MVC 패턴은 Model-View-Controller 아키텍처를 기반으로 한 웹 애플리케이션 구조입니다.
사용자의 요청을 Controller → Service → Repository 단계를 통해 처리하고,
최종 결과를 View로 반환하는 명확한 책임 분리 구조를 가지고 있습니다.
전체 흐름
1. 사용자 요청 (HTTP Request)
사용자가 웹 브라우저에서 URL을 호출합니다.
2. DispatcherServlet 진입
스프링 프론트 컨트롤러인 DispatcherServlet이 모든 요청을 먼저 받습니다.
이 서블릿은 요청을 적절한 컨트롤러로 라우팅하는 역할을 합니다.
3. HandlerMapping 조회
요청 URL에 맞는 컨트롤러(Handler)를 찾습니다. (@RequestMapping)
4. Controller 실행
비즈니스 로직의 시작점이며, 필요한 데이터를 Service에 전달하고 처리 결과를 받습니다.
5. Service → Repository → DB 처리
핵심 비즈니스 로직 수행 → DB 접근은 Repository 계층에서 담당 (JPA, JDBC 등)
6. Controller → Model 반환
처리 결과 데이터를 Model 객체에 담아 View에 전달합니다.
7. ViewResolver 호출
뷰 이름(View Name)을 기반으로 실제 JSP, Thymeleaf 등 View 파일을 찾습니다.
8. View 렌더링 → 응답 반환
View가 완성된 HTML을 만들어 사용자에게 응답합니다. (HTTP Response)
사용자의 요청을 Controller → Service → Repository 단계를 통해 처리하고,
최종 결과를 View로 반환하는 명확한 책임 분리 구조를 가지고 있습니다.
전체 흐름
1. 사용자 요청 (HTTP Request)
사용자가 웹 브라우저에서 URL을 호출합니다.
2. DispatcherServlet 진입
스프링 프론트 컨트롤러인 DispatcherServlet이 모든 요청을 먼저 받습니다.
이 서블릿은 요청을 적절한 컨트롤러로 라우팅하는 역할을 합니다.
3. HandlerMapping 조회
요청 URL에 맞는 컨트롤러(Handler)를 찾습니다. (@RequestMapping)
4. Controller 실행
비즈니스 로직의 시작점이며, 필요한 데이터를 Service에 전달하고 처리 결과를 받습니다.
5. Service → Repository → DB 처리
핵심 비즈니스 로직 수행 → DB 접근은 Repository 계층에서 담당 (JPA, JDBC 등)
6. Controller → Model 반환
처리 결과 데이터를 Model 객체에 담아 View에 전달합니다.
7. ViewResolver 호출
뷰 이름(View Name)을 기반으로 실제 JSP, Thymeleaf 등 View 파일을 찾습니다.
8. View 렌더링 → 응답 반환
View가 완성된 HTML을 만들어 사용자에게 응답합니다. (HTTP Response)
트랜잭션은 스프링에서 어떻게 관리하나요?
스프링에서는 트랜잭션을 AOP 기반으로 선언적(Declarative)으로 관리합니다.
가장 많이 사용하는 방식은 @Transactional 어노테이션을 클래스나 메서드에 붙이는 방식입니다.
이 어노테이션을 붙이면, 스프링이 해당 메서드를 실행할 때 자동으로 트랜잭션을 시작하고, 예외가 발생하지 않으면 커밋(commit), 예외가 발생하면 롤백(rollback)을 수행합니다.
* 스프링 트랜잭션 흐름 (AOP 기반)
트랜잭션이 적용된 메서드가 호출되면, 스프링 AOP 프록시가 먼저 동작하여 트랜잭션을 시작함
실제 메서드 로직이 실행됨
예외가 없으면 → 트랜잭션 커밋
예외가 발생하면 → 트랜잭션 롤백
* @Transactional 주요 특징
1. 기본적으로 체크 예외(Checked Exception)는 롤백되지 않음
RuntimeException 또는 Error만 롤백 대상 → 필요 시 rollbackFor 속성으로 설정 가능
→ @Transactional(rollbackFor = Exception.class)
2. 메서드 간 내부 호출은 트랜잭션이 적용되지 않음
→ 자기 자신(this) 내부에서 호출하는 경우 AOP 프록시가 동작하지 않음 (주의)
3. 전파 옵션 (Propagation) 으로 트랜잭션 동작 방식 제어 가능
→ ex. REQUIRED, REQUIRES_NEW, NESTED 등
가장 많이 사용하는 방식은 @Transactional 어노테이션을 클래스나 메서드에 붙이는 방식입니다.
이 어노테이션을 붙이면, 스프링이 해당 메서드를 실행할 때 자동으로 트랜잭션을 시작하고, 예외가 발생하지 않으면 커밋(commit), 예외가 발생하면 롤백(rollback)을 수행합니다.
* 스프링 트랜잭션 흐름 (AOP 기반)
트랜잭션이 적용된 메서드가 호출되면, 스프링 AOP 프록시가 먼저 동작하여 트랜잭션을 시작함
실제 메서드 로직이 실행됨
예외가 없으면 → 트랜잭션 커밋
예외가 발생하면 → 트랜잭션 롤백
* @Transactional 주요 특징
1. 기본적으로 체크 예외(Checked Exception)는 롤백되지 않음
RuntimeException 또는 Error만 롤백 대상 → 필요 시 rollbackFor 속성으로 설정 가능
→ @Transactional(rollbackFor = Exception.class)
2. 메서드 간 내부 호출은 트랜잭션이 적용되지 않음
→ 자기 자신(this) 내부에서 호출하는 경우 AOP 프록시가 동작하지 않음 (주의)
3. 전파 옵션 (Propagation) 으로 트랜잭션 동작 방식 제어 가능
→ ex. REQUIRED, REQUIRES_NEW, NESTED 등
생성자 주입, 필드 주입, Setter 주입의 차이점은 무엇인가요?
스프링에서 의존성 주입(DI)은 객체 간의 결합을 낮추기 위해 사용하는 방식으로, 대표적으로 생성자 주입, 필드 주입, Setter 주입이 있습니다.
각각의 방식은 의존 객체를 주입하는 위치와 시점이 다릅니다.
1. 생성자 주입 (Constructor Injection)
생성자를 통해 의존 객체를 전달받는 방식, 실무에서 가장 권장되는 방식
장점:
불변성 보장 (final 사용 가능)
필수 의존성 보장 (누락 시 컴파일 오류)
단위 테스트 용이 (Mock 주입 쉬움)
단점:
의존 객체가 많을수록 생성자가 길어짐
각각의 방식은 의존 객체를 주입하는 위치와 시점이 다릅니다.
1. 생성자 주입 (Constructor Injection)
생성자를 통해 의존 객체를 전달받는 방식, 실무에서 가장 권장되는 방식
장점:
불변성 보장 (final 사용 가능)
필수 의존성 보장 (누락 시 컴파일 오류)
단위 테스트 용이 (Mock 주입 쉬움)
단점:
의존 객체가 많을수록 생성자가 길어짐
@Service
public class OrderService {
private final UserRepository userRepository;
public OrderService(UserRepository userRepository) {
this.userRepository = userRepository;
}
}
2. 필드 주입 (Field Injection)
필드에 직접 @Autowired를 붙여 주입하는 방식
장점:
코드가 간결하다
단점:
테스트 어려움 (리플렉션 없이는 주입 불가)
불변성 보장 불가, 의존성 누락 시 런타임 오류
@Service
public class OrderService {
@Autowired
private UserRepository userRepository;
}
3. Setter 주입 (Setter Injection)
Setter 메서드를 통해 의존 객체를 주입
장점:
선택적 의존성 주입 가능
런타임에 객체 변경 가능
단점:
불변성 없음, 의존성 보장이 약함
@Service
public class OrderService {
private UserRepository userRepository;
@Autowired
public void setUserRepository(UserRepository userRepository) {
this.userRepository = userRepository;
}
}
🍕 꼬리질문대비
→ (private 필드를 직접 바꿀 수 없어서, 리플렉션을 사용해야 하기 때문입니다.)
"Setter 주입은 언제 사용하나요?"
→ (선택적인 의존성 주입이 필요한 경우, ex. 개발용 설정 등)
싱글톤(Singleton) 패턴과 스프링 빈의 관계는 무엇인가요?
싱글톤(Singleton) 패턴
클래스의 인스턴스를 하나만 생성하여 전역적으로 공유하는 디자인 패턴입니다.
일반적으로 생성자를 private으로 제한하고, 정적 메서드를 통해 인스턴스를 반환합니다.
스프링의 싱글톤 빈(Singleton Bean)
스프링 컨테이너(ApplicationContext)가 관리하는 객체로,
빈의 이름(식별자)마다 하나의 인스턴스만 생성되어 애플리케이션 전역에서 공유됩니다.
메모리 효율성과 일관성을 제공하지만 상태 관리에 주의가 필요합니다.
클래스의 인스턴스를 하나만 생성하여 전역적으로 공유하는 디자인 패턴입니다.
일반적으로 생성자를 private으로 제한하고, 정적 메서드를 통해 인스턴스를 반환합니다.
스프링의 싱글톤 빈(Singleton Bean)
스프링 컨테이너(ApplicationContext)가 관리하는 객체로,
빈의 이름(식별자)마다 하나의 인스턴스만 생성되어 애플리케이션 전역에서 공유됩니다.
메모리 효율성과 일관성을 제공하지만 상태 관리에 주의가 필요합니다.
스프링에서 예외 처리는 어떻게 하나요?
1. @ExceptionHandler (개별 컨트롤러 단위 예외 처리)
특정 컨트롤러 내에서 발생하는 예외를 해당 컨트롤러 안에서 처리할 수 있도록 해주는 어노테이션입니다.
2. @ControllerAdvice (글로벌 공통 예외 처리)
모든 컨트롤러에서 발생하는 예외를 중앙에서 일괄 처리할 수 있게 해주는 전역 예외 처리기입니다.
여러 예외 타입을 하나의 클래스에서 모듈화해 관리 가능.
특정 컨트롤러 내에서 발생하는 예외를 해당 컨트롤러 안에서 처리할 수 있도록 해주는 어노테이션입니다.
@Controller
public class MyController {
@ExceptionHandler(IllegalArgumentException.class)
public ResponseEntity<String> handleException(IllegalArgumentException e) {
return ResponseEntity.badRequest().body("잘못된 요청입니다: " + e.getMessage());
}
}
2. @ControllerAdvice (글로벌 공통 예외 처리)
모든 컨트롤러에서 발생하는 예외를 중앙에서 일괄 처리할 수 있게 해주는 전역 예외 처리기입니다.
여러 예외 타입을 하나의 클래스에서 모듈화해 관리 가능.
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(Exception.class)
public ResponseEntity<String> handleGlobalException(Exception e) {
return ResponseEntity.internalServerError().body("서버 에러 발생");
}
}
3. ResponseEntity와 함께 상태 코드 반환
예외 발생 시, 적절한 HTTP 상태 코드와 함께 메시지를 반환해 프론트엔드와의 통신에 용이합니다.
(예: 400 Bad Request, 404 Not Found, 500 Internal Server Error 등)
4. 비즈니스 로직 수준에서 예외 클래스 정의
사용자 정의 예외를 만들어 비즈니스 로직에서 의미를 명확하게 할 수 있음
(ex. InsufficientBalanceException, InvalidTokenException 등)
🍕 꼬리 질문대비
"왜 @ControllerAdvice를 사용하는 것이 좋나요?"
→ (예외 처리를 한 곳에서 관리해 중복을 줄이고, 유지보수가 쉬워지기 때문입니다.)
"예외 처리 시 상태 코드를 나눠주는 이유는?"
→ (프론트엔드와의 명확한 통신을 위해 클라이언트가 상황을 정확히 판단할 수 있게 하기 위함입니다.)
스프링과 스프링 부트의 차이는 무엇인가요?
스프링(Spring) 은 자바 기반의 애플리케이션을 만들기 위한 프레임워크이고 유연하지만 설정이 복잡합니다.
스프링 부트(Spring Boot) 는 스프링을 더 빠르고 쉽게 사용할 수 있게 도와주는 확장 프레임워크로, 설정을 자동화하고 간편화하여 빠른 개발과 배포에 초점을 둡니다.
스프링과 스프링 부트의 차이는 크게 설정 방식, 서버 실행 방법, 배포 방식, 개발 생산성, 의존성 관리 측면에서 나눌 수 있습니다.
우선 설정에서의 차이를 보면, 기존 스프링은 XML 설정이나 Java Config를 통해 개발자가 수동으로 많은 설정을 해야 했던 반면, 스프링 부트는 @SpringBootApplication 어노테이션을 중심으로 대부분의 설정을 자동화해 개발 생산성을 높였습니다.
서버 실행 방식에서도 차이가 있습니다. 스프링은 외부 톰캣과 같은 WAS(Web Application Server)에 애플리케이션을 배포해야 실행할 수 있는 구조였지만, 스프링 부트는 톰캣이나 제티 같은 WAS를 내장하고 있어, 실행 파일처럼 java -jar 명령 한 줄로 바로 실행이 가능합니다.
또한 배포 방식도 다릅니다. 스프링은 보통 WAR 파일로 빌드해서 서버에 배포하는 방식인 반면, 스프링 부트는 JAR 파일 하나로 패키징해서 독립 실행형 애플리케이션으로 배포가 가능합니다.
개발 생산성 면에서도 차이가 큽니다. 스프링은 설정 항목이 많고 초기 세팅이 복잡해서 진입 장벽이 있는 반면, 스프링 부트는 필요한 기능만 선택하면 자동으로 설정해주기 때문에 빠르게 개발을 시작할 수 있습니다.
마지막으로 의존성 관리에서도, 스프링은 개발자가 직접 라이브러리 버전을 맞추고 관리해야 했지만, 스프링 부트는 spring-boot-starter-* 형태의 스타터 의존성을 제공하여 버전 충돌 없이 쉽게 구성할 수 있게 도와줍니다.
🍕 꼬리질문대비
"스프링 부트는 왜 내장 톰캣을 사용하나요?"
→ (개발/배포 환경을 단순화하고, 애플리케이션을 실행 파일처럼 실행할 수 있어서 편리합니다.)
"스프링 부트의 자동 설정은 어떻게 작동하나요?"
→ (@EnableAutoConfiguration, 클래스패스 기반 조건 설정을 바탕으로 필요한 Bean을 자동 등록)
스프링과 스프링 부트의 차이는 크게 설정 방식, 서버 실행 방법, 배포 방식, 개발 생산성, 의존성 관리 측면에서 나눌 수 있습니다.
우선 설정에서의 차이를 보면, 기존 스프링은 XML 설정이나 Java Config를 통해 개발자가 수동으로 많은 설정을 해야 했던 반면, 스프링 부트는 @SpringBootApplication 어노테이션을 중심으로 대부분의 설정을 자동화해 개발 생산성을 높였습니다.
서버 실행 방식에서도 차이가 있습니다. 스프링은 외부 톰캣과 같은 WAS(Web Application Server)에 애플리케이션을 배포해야 실행할 수 있는 구조였지만, 스프링 부트는 톰캣이나 제티 같은 WAS를 내장하고 있어, 실행 파일처럼 java -jar 명령 한 줄로 바로 실행이 가능합니다.
또한 배포 방식도 다릅니다. 스프링은 보통 WAR 파일로 빌드해서 서버에 배포하는 방식인 반면, 스프링 부트는 JAR 파일 하나로 패키징해서 독립 실행형 애플리케이션으로 배포가 가능합니다.
개발 생산성 면에서도 차이가 큽니다. 스프링은 설정 항목이 많고 초기 세팅이 복잡해서 진입 장벽이 있는 반면, 스프링 부트는 필요한 기능만 선택하면 자동으로 설정해주기 때문에 빠르게 개발을 시작할 수 있습니다.
마지막으로 의존성 관리에서도, 스프링은 개발자가 직접 라이브러리 버전을 맞추고 관리해야 했지만, 스프링 부트는 spring-boot-starter-* 형태의 스타터 의존성을 제공하여 버전 충돌 없이 쉽게 구성할 수 있게 도와줍니다.
🍕 꼬리질문대비
"스프링 부트는 왜 내장 톰캣을 사용하나요?"
→ (개발/배포 환경을 단순화하고, 애플리케이션을 실행 파일처럼 실행할 수 있어서 편리합니다.)
"스프링 부트의 자동 설정은 어떻게 작동하나요?"
→ (@EnableAutoConfiguration, 클래스패스 기반 조건 설정을 바탕으로 필요한 Bean을 자동 등록)
스프링부트의 핵심 기능은 무엇인가요
1. 자동 설정 (Auto Configuration)
application.properties 또는 application.yml 파일만으로도 설정 가능
2. 스타터(Starter) 의존성 제공
필요한 기능을 쉽게 추가 (예: spring-boot-starter-web, starter-data-jpa)
3. 내장 톰캣 지원
따로 서버 설치 없이 java -jar 명령으로 애플리케이션 실행 가능
4. Actuator 제공
운영/모니터링을 위한 헬스 체크, 메트릭스, 상태 확인 등 기능 제공
application.properties 또는 application.yml 파일만으로도 설정 가능
2. 스타터(Starter) 의존성 제공
필요한 기능을 쉽게 추가 (예: spring-boot-starter-web, starter-data-jpa)
3. 내장 톰캣 지원
따로 서버 설치 없이 java -jar 명령으로 애플리케이션 실행 가능
4. Actuator 제공
운영/모니터링을 위한 헬스 체크, 메트릭스, 상태 확인 등 기능 제공
@Transactional 어노테이션은 왜 사용하나요?
@Transactional은 스프링에서 트랜잭션을 선언적으로 관리하기 위해 사용하는 어노테이션입니다.
일반적으로 여러 DB 작업이 포함된 메서드에서, 모든 작업이 성공해야 커밋되고,
하나라도 실패하면 전체를 롤백해야 할 때 사용합니다.
이를 수동으로 관리하면 코드가 복잡해지지만,
@Transactional을 사용하면 스프링 AOP가 메서드를 감싸서 트랜잭션 시작, 커밋, 롤백을 자동으로 처리해줍니다.
예를 들어, 주문 처리 로직에서 재고 차감 → 결제 → 주문 내역 저장이 하나의 트랜잭션 안에서 이루어져야 한다면, 이 메서드에 @Transactional을 붙이면 중간에 오류가 생겼을 때 이전 DB 변경도 전부 롤백됩니다.
일반적으로 여러 DB 작업이 포함된 메서드에서, 모든 작업이 성공해야 커밋되고,
하나라도 실패하면 전체를 롤백해야 할 때 사용합니다.
이를 수동으로 관리하면 코드가 복잡해지지만,
@Transactional을 사용하면 스프링 AOP가 메서드를 감싸서 트랜잭션 시작, 커밋, 롤백을 자동으로 처리해줍니다.
예를 들어, 주문 처리 로직에서 재고 차감 → 결제 → 주문 내역 저장이 하나의 트랜잭션 안에서 이루어져야 한다면, 이 메서드에 @Transactional을 붙이면 중간에 오류가 생겼을 때 이전 DB 변경도 전부 롤백됩니다.
싱글톤 빈과 일반 클래스의 차이는?
스프링의 싱글톤 빈과 일반 클래스의 가장 큰 차이는 인스턴스 관리 주체와 개수에 있습니다.
스프링에서 빈을 등록하면, 기본적으로 싱글톤(Singleton) 스코프로 관리됩니다.
즉, 컨테이너가 클래스당 하나의 인스턴스만 생성해서 공유합니다.
반면 일반 클래스는 우리가 new로 직접 생성해야 하며, 필요할 때마다 새로운 객체를 만들어야 하기 때문에
개발자가 인스턴스 생명주기와 관리 책임을 직접 져야 합니다.
스프링에서 빈을 등록하면, 기본적으로 싱글톤(Singleton) 스코프로 관리됩니다.
즉, 컨테이너가 클래스당 하나의 인스턴스만 생성해서 공유합니다.
반면 일반 클래스는 우리가 new로 직접 생성해야 하며, 필요할 때마다 새로운 객체를 만들어야 하기 때문에
개발자가 인스턴스 생명주기와 관리 책임을 직접 져야 합니다.
'Interview' 카테고리의 다른 글
개발자 기술면접 대비 - DB (0) | 2025.04.12 |
---|---|
개발자 기술면접 대비 - 운영체제 (0) | 2025.04.12 |
개발자 기술면접 대비 - 네트워크 (0) | 2025.04.11 |
개발자 기술면접 대비 - 보안 (0) | 2025.04.11 |
개발자 기술면접 대비 - JAVA (0) | 2025.04.10 |