Q1. Spring 프레임워크란 무엇인가요?
Spring 프레임워크는 자바 기반의 엔터프라이즈 애플리케이션을 구축하는 데 사용되는 강력하고 기능이 풍부하며 유연한 프레임워크입니다. 자바 애플리케이션 개발을 위한 포괄적인 인프라 지원을 제공합니다. Spring 프레임워크의 핵심 기능은 모든 자바 애플리케이션을 만드는 데 사용할 수 있으며, Java EE(Enterprise Edition) 플랫폼 위에 웹 애플리케이션을 구축할 수 있는 확장 기능도 제공합니다.
Q2. Spring 프레임워크를 사용하는 장점은 무엇인가요?
- 경량성: Spring은 크기와 투명성(Transparency) 측면에서 경량이며, 불필요한 기능을 배제하고 필요한 모듈만 선택하여 사용할 수 있다.
- 제어의 역전 (Inversion of Control, IoC): Spring은 IoC 컨테이너를 활용하여 객체의 생명주기와 의존성(Dependency Injection, DI)을 관리하여 코드의 결합도를 낮춤.
- 관점 지향 프로그래밍 (Aspect-Oriented Programming, AOP): 로깅, 보안, 트랜잭션 관리 등의 횡단 관심사(Cross-cutting Concerns)를 분리하여 코드의 유지보수성을 높이고 모듈화된 개발을 가능하게 함.
- 트랜잭션 관리: Spring은 포괄적인 트랜잭션 관리 인터페이스를 제공하여 JDBC, Hibernate, JPA 등의 기술과 쉽게 연동할 수 있음.
- MVC 프레임워크: Spring은 Spring MVC를 제공하여 웹 애플리케이션을 구축할 때 유연하고 강력한 아키텍처를 제공함.
- 통합 (Integration): Spring은 Hibernate, JPA, EJB 등 다양한 기술과 원활하게 통합되며, RESTful API, SOAP, 메시징 시스템(Kafka, RabbitMQ)과도 쉽게 연동 가능함.
Q3. Spring 프레임워크의 핵심 모듈은 무엇인가요?
- Spring Core: IoC와 의존성 주입 기능을 제공합니다.
- Spring AOP: 관점 지향 프로그래밍 지원을 제공합니다.
- Spring ORM: Hibernate, JPA 등의 ORM 프레임워크와의 통합을 지원합니다.
- Spring DAO: 데이터베이스 상호작용을 간소화하는 JDBC 추상화 계층을 제공합니다.
- Spring Context: Spring 애플리케이션에 대한 컨텍스트 정보를 제공합니다.
- Spring Web: 웹 지향 통합 기능을 제공합니다.
- Spring MVC: Model-View-Controller 아키텍처 및 구성 요소를 제공합니다.
Q4. 제어의 역전(IOC)이란 무엇인가요?
제어의 역전(IoC)은 객체 생성과 종속성 관리를 애플리케이션 코드에서 컨테이너나 프레임워크로 넘기는 설계 원칙입니다. Spring에서는 IoC가 의존성 주입(Dependency Injection, DI)을 통해 구현됩니다.
Q5. 의존성(DI)이란 무엇인가요?
기존에는 객체가 직접 다른 객체를 생성하여 사용했지만, DI를 사용하면 외부 컨테이너(예: Spring IoC 컨테이너)가 객체를 생성하고 주입합니다.
DI를 활용하면 객체 간의 결합도를 줄이고 테스트 용이성을 높일 수 있습니다.
-
객체 간 결합도 낮춤 (Loose Coupling)
클래스 간의 강한 의존성을 제거하여 유지보수 및 확장성을 높임.
-
테스트 용이성 향상
객체를 직접 생성하지 않기 때문에 Mock 객체를 쉽게 주입하여 단위 테스트(Unit Test) 수행 가능.
-
유지보수성 및 확장성 증가
새로운 기능 추가 시 기존 코드 수정 없이 새로운 구현체만 주입하면 됨.
-
객체 생성과 관리의 일관성 유지
객체의 생명주기를 Spring 컨테이너가 관리하므로, 개발자가 객체 생성 및 관리를 직접 할 필요 없음.
public class Car {
private Engine engine;
// 생성자 기반 DI
public Car(Engine engine) {
this.engine = engine;
}
// Setter 기반 DI
public void setEngine(Engine engine) {
this.engine = engine;
}
}
Q6. Spring에서 의존성 주입의 종류는 무엇인가요?
- 생성자 주입: 생성자를 통해 종속성을 제공합니다.
- 세터 주입: Setter 메서드를 통해 종속성을 제공합니다.
- 필드 주입: 종속성이 필드에 직접 주입됩니다(테스트 및 유지보수 문제로 인해 권장되지 않음).
Q7. Spring Bean이란 무엇인가요?
Spring Bean은 Spring IoC 컨테이너에 의해 인스턴스화되고 구성되며 관리되는 객체입니다.
Bean은 Spring 애플리케이션의 구성 요소이며, Spring 설정 파일에 정의되거나 @Component, @Service, @Repository, @Controller 등의 애노테이션으로 표시됩니다.
Q8. Spring Bean을 정의하는 방법은 무엇인가요?
자바 기반 설정
@Configuration
public class AppConfig {
@Bean
public MyBean myBean() {
return new MyBean();
}
}
💡 특징
@Configuration을 사용하여 Spring 설정 클래스를 정의@Bean을 사용하여 메서드의 반환값을 Spring Bean으로 등록- XML 설정보다 가독성이 좋고, 타입 안정성(Type Safety)을 제공
- 애노테이션
@Component
public class MyBean { }
💡 특징
@Component를 사용하면 Spring이 자동으로 Bean을 등록@ComponentScan을 통해 해당 패키지를 스캔하여 Bean을 자동 감지@Service,@Repository,@Controller같은 특화된 애노테이션 제공
Q9. Spring Bean 생명주기는 어떻게 되나요?
- 인스턴스화: 컨테이너가 Bean 인스턴스를 생성합니다.
- 속성 설정: 컨테이너가 Bean의 속성을 설정합니다.
- BeanNameAware 및 BeanFactoryAware 콜백: Bean은 자신의 이름과 소유 팩토리에 접근할 수 있습니다.
- 초기화 전 BeanPostProcessor: Bean 초기화 메서드가 호출되기 전입니다.
- InitializingBean 인터페이스 및 사용자 정의 초기화 메서드: afterPropertiesSet 메서드 또는 사용자 정의 초기화 메서드가 호출됩니다.
- 초기화 후 BeanPostProcessor: Bean 초기화 메서드가 호출된 후입니다.
- Bean 사용 준비 완료: Bean이 완전히 초기화되어 사용 준비가 완료되었습니다.
- DisposableBean 인터페이스 및 사용자 정의 소멸 메서드: Bean이 소멸될 때 destroy 메서드 또는 사용자 정의 소멸 메서드가 호출됩니다.
Q10. @Component, @Service, @Repository, @Controller 애노테이션의 차이점은 무엇인가요?
- @Component: Spring이 관리하는 모든 구성 요소에 대한 일반적인 스테레오타입 애노테이션입니다.
- @Service: 서비스 레이어 구성 요소를 위한 @Component의 특수화입니다.
- @Repository: DAO(Data Access Object) 구성 요소를 위한 @Component의 특수화로, 예외 번역 등의 추가 기능을 제공합니다.
- @Controller: 웹 컨트롤러 구성 요소를 위한 @Component의 특수화입니다.
Q11. Spring Boot란 무엇인가요?
Spring Boot는 Spring 프레임워크 위에 구축된 프로젝트로, 제품 단계(Production Ready) 의 애플리케이션 개발을 간소화합니다.
Spring Boot는 임베디드 서버, 보안, 메트릭스, 외부화된 설정과 같은 다양한 비기능적 기능을 제공하여 개발자가 최소한의 설정으로 애플리케이션을 빠르게 구축할 수 있도록 돕습니다.
Q12. Spring boot를 사용하는 장점은 무엇인가요?
- 설정보다 관례(Convention over Configuration): 설정 필요성을 최소화합니다.
- 독립 실행형 애플리케이션: Tomcat, Jetty, Undertow와 같은 임베디드 서버를 사용하여 독립 실행형 애플리케이션을 만들 수 있습니다.
- 제품 단계(Production Ready) 기능: 건강 체크, 메트릭스, 외부화된 설정과 같은 기능을 제공합니다.
- 간편한 의존성 관리: 스타터를 사용하여 의존성 관리를 간소화합니다.
Q13. Spring Boot 애플리케이션을 만드는 방법은 무엇인가요?
Spring Boot 애플리케이션은 Spring Initialize를 사용하여 만들 수 있으며, 이는 start.spring.io에서 사용할 수 있습니다. 또한 필요한 의존성을 pom.xml 또는 build.gradle 파일에 포함시키고, 메인 클래스를 @SpringBootApplication으로 어노테이트하여 수동으로 생성할 수도 있습니다.
@SpringBootApplication
public class MySpringBootApplication {
public static void main(String[] args) {
SpringApplication.run(MySpringBootApplication.class, args);
}
}
Q14. @SpringBootApplication 애노테이션이란 무엇인가요?
@SpringBootApplication 애노테이션은 다음 세 가지 애노테이션의 조합입니다
- @Configuration: 이 클래스가 Spring IoC 컨테이너에 의해 Bean 정의의 소스로 사용될 수 있음을 나타냅니다.
- @EnableAutoConfiguration: 클래스 경로 설정, 다른 Bean 및 다양한 속성 설정을 기반으로 Spring Boot가 자동으로 Bean을 추가하기 시작하도록 지시합니다.
- @ComponentScan: 웹 컨트롤러 클래스 및 기타 구성 요소를 자동으로 검색하고 Spring 애플리케이션 Context에서 Bean으로 등록할 수 있도록 구성 요소 스캐닝을 활성화합니다.
Q15. Spring Data JPA란 무엇인가요?
Spring Data JPA는 더 큰 Spring Data 가족의 일부입니다. 데이터 액세스 계층 개발을 간소화하여 데이터 액세스를 위한 반복적인 코드를 줄입니다. JPA(Java Persistence API)를 사용하여 데이터 액세스를 수행하며, CRUD 작업을 위한 인터페이스인 리포지토리를 제공합니다.
Q16. Spring Repository란 무엇인가요?
Spring Repository는 데이터 액세스 기술에 대한 추상화입니다. Spring Data JPA의 일부이며 @Repository로 애노테이트됩니다. 리포지토리는 데이터베이스와 상호작용하기 위한 CRUD 작업 및 쿼리 메서드를 제공합니다.
@Repository
public interface UserRepository extends JpaRepository<User, Long> {
List<User> findByLastName(String lastName);
}
Q17. CrudRepository와 JpaRepository의 차이점은 무엇인가요?
- CrudRepository: CRUD 작업을 제공합니다.
- JpaRepository: CrudRepository와 PagingAndSortingRepository를 확장합니다. JPA와 관련된 추가 작업(예: 영속성 컨텍스트 플러싱, 배치에서 레코드 삭제)을 제공합니다.
Q18. Spring MVC란 무엇인가요?
Spring MVC(Model-View-Controller)는 유연하고 느슨하게 결합된 웹 애플리케이션을 개발할 수 있는 모델-뷰-컨트롤러 아키텍처와 준비된 구성 요소를 제공하는 웹 프레임워크입니다.
MVC 패턴은 애플리케이션의 다양한 측면(입력 로직, 비즈니스 로직, UI 로직)을 분리하면서 이러한 요소들 간의 느슨한 결합을 제공합니다.
Q19. DispatcherServlet이란 무엇인가요?
DispatcherServlet은 Spring MVC 프레임워크에서 프론트 컨트롤러 역할을 합니다. 이 서블릿은 들어오는 요청을 적절한 핸들러로 디스패치하고, 요청을 처리한 후 적절한 응답을 생성하는 책임이 있습니다.
Q20. Spring AOP에서 Advice의 종류는 무엇인가요?
- Before Advice: 메서드 실행 전에 실행됩니다.
- After Returning Advice: 메서드가 결과를 반환한 후에 실행됩니다.
- After Throwing Advice: 메서드가 예외를 던진 후에 실행됩니다.
- After (Finally) Advice: 메서드가 완료된 후, 결과와 상관없이 실행됩니다.
- Around Advice: 메서드 실행 전과 후에 실행됩니다.
@Aspect
public class LoggingAspect {
@Before("execution(* com.example.service.*.*(..))")
public void logBefore(JoinPoint joinPoint) {
System.out.println("Method called: " + joinPoint.getSignature().getName());
}
@AfterReturning(pointcut = "execution(* com.example.service.*.*(..))", returning = "result")
public void logAfterReturning(JoinPoint joinPoint, Object result) {
System.out.println("Method returned: " + joinPoint.getSignature().getName());
System.out.println("Result: " + result);
}
}
21. @Transactional 애노테이션이란 무엇인가요?
@Transactional 애노테이션은 Spring에서 선언적으로 트랜잭션을 관리하는 데 사용됩니다. 메서드나 클래스에 적용되어 트랜잭션의 범위를 정의할 수 있습니다.
@Service
public class UserService {
@Transactional
public void createUser(User user) {
// 트랜잭션 코드
}
}
22. Spring Profiles이란 무엇인가요?
Spring Profiles는 애플리케이션 구성의 일부를 분리하여 특정 환경에서만 사용할 수 있도록 하는 방법을 제공합니다. 이는 개발, 테스트, 프로덕션 환경을 위한 다양한 구성을 관리하는 데 특히 유용합니다.
@Profile("dev")
@Configuration
public class DevConfig {
// 개발 환경에 특화된 빈들
}
23. Spring Security란 무엇인가요?
Spring Security는 자바 애플리케이션을 위한 포괄적이고 고도로 커스터마이징 가능한 인증 및 접근 제어 프레임워크입니다. CSRF, 세션 고정 등과 같은 일반적인 보안 위협으로부터 애플리케이션을 보호합니다.
24. Spring Security의 주요 구성 요소는 무엇인가요?
- 인증(Authentication): 사용자가 인증되었는지 여부를 결정합니다.
- 권한 부여(Authorization): 인증된 사용자가 특정 리소스에 접근할 수 있는지 여부를 결정합니다.
- 서블릿 필터(Servlet Filters): 인증 및 권한 부여를 위한 다양한 필터를 제공합니다.
- 보안 컨텍스트(Security Context): 현재 실행 스레드에 대한 보안 정보를 보유합니다.
25. Spring Boot 애플리케이션에서 보안을 구현하는 방법은 무엇인가요?
Spring Boot 애플리케이션에서 보안을 구현하려면 spring-boot-starter-security 의존성을 추가하고 SecurityConfig 클래스를 구성해야 합니다.(과거 방식, Spring Security 5.x까지)
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/public/**").permitAll()
.anyRequest().authenticated()
.and()
.formLogin().permitAll();
}
}
WebSecurityConfigurerAdapter는 보안 설정을 커스터마이징할 수 있는 추상 클래스
configure(HttpSecurity http)를 오버라이드해서 인증, 권한, 로그인/로그아웃 등을 설정
@Component 또는 @Configuration만 사용 (현대 방식, Spring Security 5.7+)
@EnableWebSecurity 없이도 Spring Security 자동 설정이 활성화됩니다.
SecurityFilterChain Bean을 명시적으로 등록하여 보안 설정을 구성합니다.
WebSecurityConfigurerAdapter는 더 이상 사용하지 않고 람다식 기반 설정을 선호
@Configuration
public class SecurityConfig {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
return http
.authorizeHttpRequests(auth -> auth
.anyRequest().authenticated()
)
.formLogin(withDefaults())
.build();
}
}
26. @RequestMapping과 @GetMapping의 차이점은 무엇인가요?
- @RequestMapping: MVC 및 REST 컨트롤러의 핸들러 메서드에 웹 요청을 매핑하는 데 사용됩니다. method 속성을 지정하여 모든 HTTP 메서드를 처리할 수 있습니다.
- @GetMapping: @RequestMapping의 특수 버전으로, @RequestMapping(method = RequestMethod.GET)을 대체합니다.
@RestController
public class MyController {
@RequestMapping(value = "/hello", method = RequestMethod.GET)
public String hello() {
return "Hello, World!";
}
@GetMapping("/hi")
public String hi() {
return "Hi, World!";
}
}
27. Spring Bean Scope란 무엇인가요?
Spring Bean의 범위는 Spring 컨텍스트 내에서 해당 Bean의 생명주기와 가시성을 정의합니다. 일반적인 Bean 범위는 다음과 같습니다:
- Singleton: 하나의 인스턴스가 생성되어 공유됩니다.
- Prototype: Bean이 요청될 때마다 새 인스턴스가 생성됩니다.
- Request: HTTP 요청마다 새 인스턴스가 생성됩니다.
- Session: HTTP 세션마다 새 인스턴스가 생성됩니다.
- Global-Session: 글로벌 HTTP 세션마다 새 인스턴스가 생성됩니다(포틀릿 기반 애플리케이션에서 사용).
28. Spring Bean에 대해 프로토타입 범위를 정의하는 방법은 무엇인가요?
@Scope 애노테이션 또는 XML 설정을 사용하여 프로토타입 범위를 정의할 수 있습니다.
@Component
@Scope("prototype")
public class PrototypeBean {
// Bean 정의
}
29. Spring Actuator란 무엇인가요?
Spring Actuator는 Spring Boot의 서브 프로젝트로, 애플리케이션을 모니터링하고 관리할 수 있는 프로덕션 제품 단계(Production Ready)을 제공합니다. 건강 체크, 메트릭스, 정보 등의 엔드포인트를 포함합니다.
30. Spring Boot 애플리케이션에서 Spring Actuator를 활성화하는 방법은 무엇인가요?
Spring Actuator는 프로젝트에 spring-boot-starter-actuator 의존성을 추가하여 활성화할 수 있습니다.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
31. Spring Cloud란 무엇인가요?
Spring Cloud는 개발자가 분산 시스템에서 공통적으로 사용되는 패턴(예: 구성 관리, 서비스 검색, 회로 차단기, 지능형 라우팅, 마이크로 프록시, 제어 버스, 일회용 토큰 등)을 빠르게 구축할 수 있는 도구를 제공합니다.
32. Spring Cloud Config란 무엇인가요?
Spring Cloud Config는 분산 시스템에서 외부화된 구성을 지원하는 서버 및 클라이언트 측 지원을 제공합니다. Config Server를 사용하면 모든 환경에서 애플리케이션에 대한 외부 속성을 중앙에서 관리할 수 있습니다.
33. Spring Boot Starter란 무엇인가요?
Spring Boot Starters는 애플리케이션에 종속성을 추가하는 과정을 간소화하는 의존성 기술자입니다. 사용하기 편리한 종속성 기술자 세트를 제공하여 애플리케이션에 포함할 수 있습니다.
34. Spring Initializr란 무엇인가요?
Spring Initializr는 Spring 팀이 제공하는 웹 기반 도구로, 새로운 Spring Boot 프로젝트를 부트스트랩할 수 있습니다. 필요한 종속성을 선택하고 프로젝트 구조를 생성하여 zip 파일로 다운로드하거나 IDE로 직접 가져올 수 있습니다.
35. @Controller와 @RestController의 차이점은 무엇인가요?
- @Controller: 뷰를 반환하는 웹 컨트롤러를 정의하는 데 사용됩니다.
- @RestController: @Controller와 @ResponseBody를 결합한 편리한 애노테이션입니다. RESTful 웹 서비스를 만들고 응답 본문을 직접 반환하는 데 사용됩니다.
@Controller
public class MyController {
@GetMapping("/view")
public String view() {
return "viewName";
}
}
@RestController
public class MyRestController {
@GetMapping("/data")
public String data() {
return "Hello, World!";
}
}
36. @RequestParam 애노테이션이란 무엇인가요?
@RequestParam 애노테이션은 요청 URL에서 쿼리 매개변수, 폼 매개변수 또는 기타 매개변수를 추출하는 데 사용됩니다.
@RestController
public class MyController {
@GetMapping("/greet")
public String greet(@RequestParam(name = "name", defaultValue = "World") String name) {
return "Hello, " + name + "!";
}
}
37. @PathVariable 애노테이션이란 무엇인가요?
@PathVariable 애노테이션은 URI 경로에서 값을 추출하는 데 사용됩니다.
@RestController
public class MyController {
@GetMapping("/user/{id}")
public String getUser(@PathVariable("id") String userId) {
return "User ID: " + userId;
}
}
38. Spring Batch란 무엇인가요?
Spring Batch는 배치 처리 — 일련의 작업을 실행하기 위한 프레임워크입니다. 로깅/추적, 트랜잭션 관리, 작업 처리 통계, 작업 재시작, 스킵, 리소스 관리 등을 포함한 대량 레코드 처리에 필수적인 재사용 가능한 기능을 제공합니다.
39. Spring Boot DevTools란 무엇인가요?
Spring Boot DevTools는 개발 경험을 향상시킬 수 있는 도구 세트입니다. 자동 재시작, 라이브 리로드, 개발용 구성 등의 기능을 포함합니다.
40. @Configuration 애노테이션의 용도는 무엇인가요?
@Configuration 애노테이션은 Spring IoC 컨테이너에서 빈 정의의 소스로 사용할 수 있는 설정 클래스를 정의하는 데 사용됩니다.
@Configuration
public class AppConfig {
@Bean
public MyBean myBean() {
return new MyBean();
}
}
41. Spring Integration이란 무엇인가요?
Spring Integration은 엔터프라이즈 통합 패턴에 대한 지원을 제공하는 Spring 프로그래밍 모델의 확장입니다. Spring 기반 애플리케이션 내에서 경량 메시징을 가능하게 하며, 선언적 어댑터를 통해 외부 시스템과의 통합을 지원합니다.
42. Spring AMQP란 무엇인가요?
Spring AMQP(Advanced Message Queuing Protocol)는 메시지 지향 미들웨어에 대한 지원을 제공합니다. Spring JMS와 유사하게 메시징을 다루기 위한 추상화 및 공통 API 세트를 제공합니다.
43. @Conditional 애노테이션이란 무엇인가요?
@Conditional 애노테이션은 조건부로 빈을 생성할 수 있게 해줍니다. 빈을 생성해야 하는 조건을 정의하는 데 사용할 수 있습니다.
@Configuration
public class AppConfig {
@Bean
@Conditional(DevEnvironmentCondition.class)
public MyBean myBean() {
return new MyBean();
}
}
public class DevEnvironmentCondition implements Condition {
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
return "dev".equals(System.getProperty("env"));
}
}
44. Spring WebFlux란 무엇인가요?
Spring WebFlux는 Spring 5 프레임워크의 일부로, 반응형 프로그래밍을 지원합니다. Reactive Streams API를 사용하여 비동기적이고 논블로킹 방식으로 웹 애플리케이션을 구축할 수 있는 방법을 제공합니다.
45. 반응형 프로그래밍이란 무엇인가요?
반응형 프로그래밍은 비동기 데이터 스트림과 변화의 전파를 다루는 프로그래밍 패러다임입니다. 이를 통해 개발자는 더 견고하고 반응성이 뛰어난 애플리케이션을 구축할 수 있습니다.
46. Spring WebFlux와 Spring MVC의 차이점은 무엇인가요?
- Spring MVC: 전통적인 서블릿 API를 기반으로 하며, 블로킹 방식입니다.
- Spring WebFlux: 반응형 프로그래밍 모델을 기반으로 하며, 논블로킹 방식입니다.
47. @RestControllerAdvice의 용도는 무엇인가요?
@RestControllerAdvice 애노테이션은 RESTful 웹 서비스에서 전역적으로 예외를 처리하는 데 사용됩니다. 여러 @ExceptionHandler 메서드를 하나의 공유 구성 요소로 통합할 수 있습니다.
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(ResourceNotFoundException.class)
public ResponseEntity<String> handleResourceNotFound(ResourceNotFoundException ex) {
return new ResponseEntity<>(ex.getMessage(), HttpStatus.NOT_FOUND);
}
}
48. Spring Retry란 무엇인가요?
Spring Retry는 실패한 작업을 자동으로 다시 호출할 수 있는 기능을 제공합니다. 일시적인 오류를 처리하고 구성 가능한 백오프 정책을 통해 재시도를 수행할 수 있습니다.
49. @Value 애노테이션이란 무엇인가요?
@Value 애노테이션은 속성 파일, 시스템 속성 또는 환경 변수에서 필드에 값을 주입하는 데 사용됩니다.
@Component
public class MyComponent {
@Value("${app.name}")
private String appName;
@Value("#{systemProperties['user.name']}")
private String userName;
}
50. @Value 어노테이션 사용 시 주의할 점을 설명해주세요.
첫 번째로 주의해야 할 부분은 주입 시점입니다. @Value 어노테이션은 대상 컴포넌트가 스프링 빈으로 등록되고 의존 관계를 주입할 때 동작합니다. 따라서 환경 변수를 주입받는 대상 클래스에 @Component 어노테이션을 붙여주지 않는다면 해당 클래스는 컴포넌트 스캔이 대상이 되지 않아 스프링 빈으로 등록되지 않고, @Value 어노테이션 또한 동작하지 않습니다.
또한 상황에 따라서 적절한 주입 방식을 선택해야 하는데요. 빈을 주입받을 때와 마찬가지로 @Value 어노테이션을 사용할 때도 필드 주입, 생성자 주입, setter 주입 등의 방식을 사용할 수 있습니다. 따라서 이들의 장단점을 비교하고, 상황에 따라 적절한 주입 방식을 선택해야 합니다.
마지막으로 프로퍼티 파일의 경로와 스코프를 확인해야 합니다. application.yaml 이 클래스 패스에 존재해야 하고, 프로퍼티 파일이 여러 개일 경우 우선순위를 고려해야 합니다.
51. @ConfigurationProperties 어노테이션과의 차이점은 무엇인가요?
스프링의 프로퍼티 파일의 값은 Environment에 등록되는데요. 두 어노테이션 모두 이 값을 불러올 수 있다는 공통점이 있습니다. 단, @Value의 경우에는 단일 값을 주입받기 위해서 사용되며, RelaxedBinding이 적용되지 않습니다. RelaxedBingding이란 프로퍼티 이름이 조금 달라도 유연하게 바인딩을 시켜주는 규칙을 의미합니다. 반면, @ConfigurationProperties 어노테이션은 프로퍼티에 있는 값을 클래스로 바인딩하기 위해 사용됩니다. 그리고, 한 번에 여러 값을 바인딩 받을 수 있으며 RelaxedBinding을 적용합니다.
52. @ExceptionHandler 어노테이션은 무엇인가요?
@ExceptionHandler 애너테이션은 Spring MVC에서 컨트롤러(@Controller)나 전역 예외 처리를 위한 @ControllerAdvice 클래스의 메서드에서 발생하는 예외를 처리하는 데 사용되는데요. 이 애너테이션은 특정 예외를 처리하는 메서드를 지정하거나 메서드의 파라미터로 처리할 예외를 설정할 수 있습니다.
어떤 방식으로 동작하나요? 🤔
Spring MVC 애플리케이션에서 예외가 발생하면, DispatcherServlet이 적절한 HandlerExceptionResolver를 찾아 예외를 처리합니다. Spring에 기본적으로 등록된 HandlerExceptionResolver는 세 가지가 있으며, 각 리졸버는 우선순위에 따라 예외를 처리합니다. 그 중 ExceptionHandlerExceptionResolver가 가장 먼저 동작하며, 발생한 예외가 @ExceptionHandler에 등록되어 있는지 확인합니다. 만약 처리할 수 없는 예외라면 다음 리졸버로 넘어갑니다. ExceptionHandlerExceptionResolver의 특징은 예외가 WAS로 던져지지 않고 직접 처리된다는 것입니다.
이렇게 함으로써 예외가 발생했을 때 적절한 방법으로 처리되어 사용자에게 친화적인 에러 메시지를 제공하거나 로깅 등의 추가 작업을 수행할 수 있습니다.
53. @Async 애노테이션의 용도는 무엇인가요?
@Async 애노테이션은 메서드를 비동기적으로 실행하도록 표시하는 데 사용됩니다. 메서드가 별도의 스레드에서 실행되도록 하여 호출자가 메서드가 완료될 때까지 기다리지 않고 계속 진행할 수 있게 합니다.
54. RequestBody VS ModelAttribute의 차이점을 말해주세요.
클라이언트 측에서 보낸 데이터를 Java 객체로 만들어주는데 RequestBody 는 요청의 본문(Body)에 있는 값을 바인딩할 때 사용하고, ModelAttribute 는 요청 파라미터나 multipart/form-data 형식을 바인딩할 때 사용합니다.
RequestBody
- 클라이언트가 보내는 요청의 본문을 자바 객체로 변환합니다.
- 내부적으로 HttpMessageConverter를 거치는데, 이때 ObjectMapper를 통해 JSON 값을 java 객체로 역직렬화합니다.
- 따라서 변환될 java 객체에 기본 생성자를 정의해야 하고, getter나 setter를 선언해야 합니다.
- record에 기본 생성자를 따로 정의하지 않았는데 역직렬화가 되는 이유
- record 는 기본생성자를 자동으로 제공하지 않는 대신, ’모든 필드를 초기화하는 생성자’를 제공합니다.
- jackson 은 일반 객체와 달리, record를 역직렬화할 때는 ’모든 필드를 초기화하는 생성자’를 사용해 역직렬화하기 때문입니다.
ModelAttribute
- 첫번째 사용법인 메서드 단에서의 사용법은 jsp의 Model에 하나 이상의 속성을 추가하고 싶을 때 사용합니다. ex) model.addAttribute(“속성 이름”, “속성 값”)
- 두번째 사용법인 인자 단에서의 사용으로 클라이언트가 보내는 요청의 파라미터나 multipart/form-data 형식의 데이터를 자바 객체로 변환합니다.
- 내부적으로 ModelAttributeMethodProcessor를 거치는데, 이때 지정된 클래스의 생성자를 찾아 객체로 변환합니다.
55. AutoConfiguration 동작 원리를 설명해주세요.
AutoConfiguration의 시작은 @SpringBootApplication 어노테이션 안에 있는@EnableAutoConfiguration 이라는 애노테이션입니다.
@EnableAutoConfiguration은 @Import(AutoConfigurationImportSelector.class)를 통해 자동 구성 클래스를 가져옵니다.
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import({AutoConfigurationImportSelector.class})
public @interface EnableAutoConfiguration {
String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";
Class<?>[] exclude() default {};
String[] excludeName() default {};
}
자동 구성 클래스를 가져올 때는 AutoConfigurationImportSelector 클래스의 selectImports(AnnotationMetadata annotationMetadata) 라는 메서드를 이용하고, getAutoConfigurationEntry(AnnotationMetadata annotationMetadata); 메서드를 통해 Import할 클래스가 무엇인지 알 수 있게 됩니다.
간단한 메서드 동작 과정 설명
- getCandidateConfigurations(annotationMetadata, attributes); - AutoConfiguration의 후보들을 가져온다.
- removeDuplicates(configurations); - 중복을 제거한다.
- getExclusions(annotationMetadata, attributes); - 자동 설정에서 제외되는 설정에 대한 정보를 가져온다.
- configurations.removeAll(exclusions); - 제외되는 설정을 제거한다.
- getConfigurationClassFilter().filter(configurations); - 필터를 적용한다.
56. Spring과 Spring Boot의 차이를 말해주세요.
Spring은 Spring Framework의 핵심 모듈들을 기반으로 한 프레임워크로 엔터프라이즈 애플리케이션 개발을 지원하기 위한 대규모 오픈 소스 프로젝트입니다. Spring Framework를 사용하기 위해서는 설정 파일 작성을 통한 스프링 컨테이너 구성, 필요한 빈 객체 등록 및 의존성 설정, 데이터베이스 연결, 트랜잭션 관리 등 다양한 설정을 개발자가 직접 수동으로 구성해야 했습니다. 따라서 프로젝트 초기화 과정에서 많은 설정과 의존성을 추가하게 되며 프로젝트는 시작하는데 시간이 많이 걸렸습니다. 또한 스프링을 통해 웹 애플리케이션을 구축하기 위해서는 별도의 WAS를 설치하고 설정해야 했습니다.
Spring Boot는 Spring의 문제점을 해결해주고, 더 쉽고 빠르게 스프링 애플리케이션을 개발할 수 있도록 해주는 도구입니다. Spring Boot를 사용하면 Spring에서 제공하는 여러 기능들을 자동으로 설정하여 개발자가 보다 쉽게 사용할 수 있도록 해줍니다.
Spring Boot의 주요 특징
-
자동 설정(Auto Configuration)
-
Spring Boot는 애플리케이션의 설정을 자동으로 구성합니다.
-
@EnableAutoConfiguration, @SpringBootApplication 어노테이션을 통해 자동 설정을 활성화합니다.
-
-
의존성 관리 간소화
-
특정 기능을 쉽게 추가할 수 있도록 여러 개의 라이브러리와 의존성을 하나의 패키지로 묶어 제공하는 starter 의존성 통합 모듈을 제공합니다.
-
예: spring-boot-starter-web, spring-boot-starter-data-jpa, spring-boot-starter-security
-
-
내장 서버
-
Tomcat, Jetty, Undertow와 같은 내장 웹 서버를 제공하여, 애플리케이션을 독립 실행형 JAR 파일로 배포하고, 바로 실행할 수 있게 합니다.
-
배포를 위해 War 파일을 생성해서 Tomcat에 배포할 필요 없으며, JAR 파일에는 모든 의존성 라이브러리가 포함되어 있어 외부 서버 없이도 애플리케이션을 실행할 수 있습니다.
-
57. JPA, Hibernate, Spring Data JPA 의 차이가 무엇인가요?
-
JPA는 기술 명세입니다. 자바 애플리케이션에서 관계형 데이터베이스를 사용하는 방식을 정의한 인터페이스입니다. JPA는 단순한 명세이기 때문에 인터페이스와 규약만 정의하며, 실제 구현체는 제공하지 않습니다.
-
Hibernate는 JPA의 구현체 중 하나입니다. JPA가 정의한 javax.persistence.EntityManager와 같은 인터페이스를 직접 구현한 라이브러리입니다. JPA의 구현체 중 하나일 뿐이므로, DataNucleus, EclipseLink 등 다양한 JPA 구현체로 대체할 수 있습니다.
-
Spring Data JPA는 JPA를 쉽게 사용할 수 있도록 지원하는 모듈입니다. JPA를 한 단계 추상화시킨 Respository 라는 인터페이스를 제공합니다. 개발자가 Respository 인터페이스에 정해진 규칙대로 메서드를 만들어주기만 하면, 해당 메서드 이름에 적합한 쿼리를 날리는 구현체를 만들어 자동으로 Bean으로 등록해줍니다.
Spring Data JPA는 JPA를 기반으로 하며, 반복적인 코드 작성을 줄이고 데이터 접근 계층을 단순화 합니다. 이 때 JPA를 추상화 했다는 의미는, Spring Data JPA의 Repository 의 구현에서 JPA를 사용하고 있다는 것입니다. 예를 들어 Respository 인터페이스의 기본 구현체인 SimpleJpaResporitory 는 내부적으로 EntityManager 를 사용합니다.
58. Spring에서 객체를 Bean으로 관리하는 이유를 설명해주세요.
Bean으로 객체를 관리하는 이유는 애플리케이션의 설계, 확장성, 유지보수 측면에서 많은 이점을 제공하기 때문입니다.
- 의존성 관리 자동화 : 빈으로 등록된 객체들은 Spring 컨테이너가 자동으로 의존성을 주입해주기 때문에 개발자가 직접 객체를 생성하고 의존성을 연결할 필요가 없어집니다. 또 컨테이너가 빌드 시점에 순환 의존성을 감지하여 설계 오류를 조기에 발견할 수 있습니다.
- 싱글톤 패턴 구현 : 기본적으로 Spring은 빈을 싱글톤으로 관리하여 메모리 사용을 최적화하고, 불필요한 객체 생성을 방지합니다.
- 생명주기 관리 : Spring은 빈의 초기화와 소멸 과정을 자동으로 관리합니다. 이를 통해 리소스 할당 및 해제를 체계적으로 처리할 수 있습니다.
- AOP 지원 : 빈으로 관리되는 객체들은 트랜잭션 관리, 로깅, 보안 등의 공통 관심사를 쉽게 적용할 수 있습니다.
- 테스트 용이성 : 빈으로 관리되는 컴포넌트는 모킹(mocking)이나 테스트용 구현체로 쉽게 대체할 수 있어 단위 테스트와 통합 테스트가 용이합니다.
- 설정의 자동화 : 애플리케이션의 구성 요소들을 Bean으로 관리함으로써 설정을 중앙화하고 일관된 방식으로 관리할 수 있습니다.
59. System.out.println을 사용하면 로깅 프레임워크는 사용하지 않아도 되지 않나요?
로그를 출력하는 경우 대기 시간이 발생합니다. 그리고, 로그 또한 데이터이기 때문에 저장 공간을 요구합니다. 따라서, 정말로 필요한 경우에만 로깅을 수행하는 것이 비용 효율적입니다. 하지만, System.out.println은 로그 레벨 설정과 환경 별 필터링을 적용하기 까다롭습니다. 반면, 로깅 프레임워크는 로그 레벨 설정, 필터링 등 로그의 양 조절을 하기 위한 기능을 제공하기 때문에 이를 사용하는 것이 서비스 운영에 유리합니다.
60. 스프링 트랜잭션 AOP 동작 흐름에 대해서 설명해주세요.
@Transactional어노테이션을 사용한 선언적 트랜잭션 관리(Declarative Transaction Management)의 전체 흐름에는 크게 3가지 요소가 등장합니다. 트랜잭션 매니저, 트랜잭션 AOP 프록시, 트랜잭션 동기화 매니저가 이에 해당됩니다.
클라이언트 코드로부터 요청이 들어오면 트랜잭션 AOP 프록시가 트랜잭션 매니저를 획득하고, 트랜잭션을 시작하기 위해서 트랜잭션 매니저에게 요청합니다. 트랜잭션 시작 요청 받은 트랜잭션 매니저는 데이터소스를 통해 커넥션을 받아오고 트랜잭션을 시작합니다. 그리고, 트랜잭션 매니저는 트랜잭션이 시작된 커넥션을 동기화 매니저에 보관합니다. 이후 트랜잭션이 종료되는 경우 트랜잭션 매니저는 트랜잭션 동기화 매니저에 보관한 커넥션을 가져와 트랜잭션을 종료하고 커넥션을 반환하거나 종료합니다.
61. 트랜잭션 매니저와 트랜잭션 동기화 매니저가 무엇인가요?
스프링은 개발자가 트랜잭션에 대한 구현 세부 사항을 신경 쓰지 않도록 트랜잭션 추상화인 PlatformTransactionManager를 제공합니다. 개발자는 상황에 맞게 DataSourceTransactionManager, JpaTransactionManager를 사용할 수 있으며, 이를 트랜잭션 매니저(Transaction Manager) 라고 부릅니다.
서비스 로직에서 여러 서비스 로직을 호출할 수 있고, 데이터 접근 로직을 호출할 수도 있습니다. 이때 트랜잭션을 유지하기 위해서는 해당 트랜잭션을 시작한 커넥션이 여러 코드에 걸쳐 필요하게 됩니다. 트랜잭션 동기화 매니저(Transaction Syncronization Manager) 는 이를 도와줍니다. 만약, 트랜잭션 동기화 매니저가 없다면, 다른 코드의 메서드를 호출할 때마다 커넥션을 인자로 넘겨줘야 하는 문제가 발생합니다.
62. 스프링 트랜잭션 전파 속성에 대해서 설명해주세요.
스프링에서 트랜잭션 전파(Transaction Propagation) 는 트랜잭션의 경계에서 이미 진행 중인 트랜잭션이 있을 때 또는 없을 때 어떻게 동작할 것인가를 결정하는 기능입니다. @Transactional 어노테이션이 존재하는 메서드를 호출했을 때, 기존에 트랜잭션이 존재하면 재사용할지, 예외를 던질지 등 행동을 결정할 수 있습니다.
트랜잭션 전파 속성에는 REQUIRED, REQUIRED_NEW, MANDATORY, SUPPORTS, NOT_SUPPORTED, NESTED, NEVER가 존재하며, @Transactional 어노테이션의 propagation 속성에 값을 설정할 수 있습니다.
트랜잭션 전파 속성
- REQUIRED는 트랜잭션이 존재하는 경우 해당 트랜잭션 사용하고, 트랜잭션이 없는 경우 트랜잭션을 생성합니다.
-
REQUIRED_NEW는 트랜잭션이 존재하는 경우 트랜잭션을 잠시 보류시키고, 신규 트랜잭션을 생성하여 사용합니다.
- MANDATORY는 트랜잭션이 반드시 있어야 합니다. 트랜잭션이 없다면, 예외가 발생합니다. 만약, 트랜잭션이 존재한다면 해당 트랜잭션을 사용합니다.
- SUPPORTS는 트랜잭션이 존재하는 경우 트랜잭션을 사용하고, 트랜잭션이 없다면 트랜잭션 없이 실행합니다.
- NOT_SUPPORTED는 트랜잭션이 존재하는 경우 트랜잭션을 잠시 보류하고, 트랜잭션이 없는 상태로 처리합니다.
-
NESTED는 트랜잭션이 있다면 SAVEPOINT를 남기고 중첩 트랜잭션을 시작합니다. 만약 없는 경우에는 새로운 트랜잭션을 시작합니다.
- NEVER는 트랜잭션이 존재하는 경우 예외를 발생시키고, 트랜잭션이 없다면 생성하지 않습니다.
이 페이지는 면접 준비를 위한 정리 페이지입니다.