Spring

Spring & Spring Boot (50개)

DI(Dependency Injection), IOC(inversion of Control), AOP(Aspect-Oriented Programming) 설명

  1. IoC (Inversion of Control, 제어의 역전)

  • 개념: "내가 할 일을 너에게 맡길게" IoC는 프로그래밍의 거대한 설계 원칙(패러다임)입니다. 전통적인 프로그래밍에서는 개발자가 작성한 코드(객체)가 프로그램의 흐름을 직접 제어했습니다. 즉, 사용할 객체를 직접 new로 생성하고, 어떤 메서드를 호출할지 스스로 결정했죠.

    IoC는 이 제어의 흐름을 거꾸로 뒤집습니다. 객체의 생성, 생명주기 관리, 의존 관계 설정 등 모든 제어권이 개발자의 코드에서 외부의 프레임워크(스프링 컨테이너)로 넘어갑니다. 개발자는 그냥 필요한 부품(객체)들을 만들기만 하면, 프레임워크가 알아서 조립하고 실행해 줍니다.

  • 비유: 컴퓨터 조립

    • 과거 (No IoC): 내가 컴퓨터를 조립하기 위해 용산에 가서 CPU, RAM, 그래픽카드를 직접 고르고 구매(new)해서, 내 방에서 직접 조립(관계 설정)합니다. 모든 제어권은 나에게 있습니다.

    • 현재 (IoC): 나는 조립 업체에 "CPU는 인텔, RAM은 삼성 16GB로 맞춰주세요" 라는 '설정 정보'만 제공합니다. 그러면 조립 업체(스프링 컨테이너)가 부품을 가져와서 조립하고, 테스트까지 마친 완제품 컴퓨터를 나에게 전달해 줍니다. 컴퓨터 조립에 대한 제어권이 나에게서 조립 업체로 역전되었습니다.

  • 결론: IoC는 "누가 누구를 제어하는가?"에 대한 패러다임의 전환입니다. 스프링에서는 ApplicationContext라는 스프링 컨테이너가 이 제어권을 가져갑니다.


  1. DI (Dependency Injection, 의존성 주입)

  • 개념: "필요한 건 외부에서 넣어줄게" DI는 위에서 설명한 IoC라는 거대한 원칙을 실제로 구현하는 핵심적인 기술(디자인 패턴)입니다. 한 클래스가 다른 클래스를 사용(의존)할 때, 필요한 의존 객체를 코드 내부에서 직접 생성하는 것이 아니라, 외부(스프링 컨테이너)에서 생성해서 넣어주는(주입하는) 방식을 말합니다.

  • 효과

    • 스프링 프레임워크는 애플리케이션 시작 시 특정 애너테이션이 붙어 있는 클래스들을 빈으로 등록하고, 의존성이 필요한 곳에 해당 빈을 주입하여 사용합니다. 이렇게 하면 동일한 인스턴스는 한 번만 생성되고 여기 저기서 재사용되기 때문에 인스턴스를 만드는 비용과 메모리를 아낄 수 있습니다. 또 다른 이점으로는 의존성을 주입받아서 사용하는 것에서 객체지향적인 이점이 발생합니다. 애플리케이션을 개발하다 보면 테스트 코드를 작성할 때 특정 의존성의 대역( Stub) 의존성을 주입받아서 사용하고 싶은 경우가 생깁니다 .이런 상황에서 의존성을 주입받아서 사용하는 경우 원래 코드를 수정하지 않고도 아주 손쉽게 테스트할 때 대역 의존성을 주입받아서 사용하고, 실제 애플리케이션이 실행되는 환경에서 실제 동작하는 의존성을 주입받아서 사용할 수 있습니다.

  • 비유: 자동차와 타이어

    • 과거 (No DI): 자동차가 스스로 "나는 한국타이어만 써!" 라고 외치며, 자동차 공장 내부에서 new HankookTire() 코드를 통해 타이어를 직접 생산해서 장착합니다. 이 자동차는 다른 타이어를 쓰려면 자동차 설계 자체를 바꿔야 합니다.

    • 현재 (DI): 자동차는 그냥 "타이어가 들어올 자리"만 비워둡니다. 그리고 외부의 조립 라인(스프링 컨테이너)에서 생산된 한국타이어, 금호타이어, 미쉐린타이어 중 하나를 그 자리에 '주입'해 줍니다. 자동차는 어떤 타이어가 들어오는지 신경 쓰지 않고, 그냥 '굴러간다'는 타이어의 기능(인터페이스)만 사용합니다.

  • 스프링에서의 구현 방법:

    1. 생성자 주입 (Constructor Injection): 가장 권장되는 방식. 생성자를 통해 의존성을 주입받습니다. 객체가 생성될 때 모든 의존성이 보장됩니다.

    2. 수정자 주입 (Setter Injection): setXxx() 메서드를 통해 주입받습니다. 선택적인 의존성에 사용됩니다.

    3. 필드 주입 (Field Injection): @Autowired 어노테이션을 필드에 직접 선언합니다. 코드는 간결하지만 외부에서 변경이 불가능하고 테스트가 어려워 권장되지 않습니다.

  • 결론: DI는 IoC를 실현하는 방법론입니다. 의존성을 외부에서 주입함으로써 클래스 간의 결합도(Coupling)를 극적으로 낮추고, 코드의 유연성과 재사용성을 높입니다.


  1. AOP (Aspect-Oriented Programming, 관점 지향 프로그래밍)

  • 개념: "공통 관심사는 한 곳에 모아서 처리하자" AOP는 애플리케이션의 여러 부분에 공통적으로 나타나는 부가 기능, 즉 횡단 관심사(Cross-Cutting Concerns)를 핵심 비즈니스 로직으로부터 분리하여 모듈화하는 프로그래밍 기법입니다.

    • 핵심 비즈니스 로직: 주문 처리, 상품 등록 등 해당 모듈의 고유한 기능

    • 횡단 관심사: 로깅, 보안, 트랜잭션, 성능 측정 등 여러 비즈니스 로직에 공통적으로 필요한 기능

  • 비유: 모든 은행 창구의 CCTV 녹화

    • 과거 (No AOP): A은행의 '입금 창구', '출금 창구', '대출 창구' 직원이 각자 자신의 업무 매뉴얼에 "1. CCTV 녹화 시작, 2. 입금/출금/대출 처리, 3. CCTV 녹화 종료" 라고 적어두고 일합니다. 모든 창구의 매뉴얼에 중복된 CCTV 관련 내용이 들어갑니다. 만약 CCTV 장비가 바뀌면 모든 창구의 매뉴얼을 수정해야 합니다.

    • 현재 (AOP): 은행의 핵심 업무는 '입금', '출금', '대출' 뿐입니다. 'CCTV 녹화'라는 공통 관심사(Aspect)는 보안팀에서 따로 관리합니다. 그리고 보안팀은 "모든 창구의 업무가 시작되기 전(Before)과 끝난 후(After)에 자동으로 CCTV를 녹화하라"는 규칙을 설정합니다. 이제 창구 직원들은 자신의 핵심 업무에만 집중할 수 있고, CCTV 녹화는 보이지 않는 곳에서 자동으로 적용됩니다.

  • 스프링에서의 구현:

    • 스프링 AOP는 프록시(Proxy) 패턴을 기반으로 동작합니다.

    • 개발자는 Aspect를 정의하고, 어디에(Pointcut) 이 로직을 적용할지, 그리고 언제(Advice: Before, After, Around 등) 적용할지를 설정합니다.

    • 그러면 스프링이 실제 객체 대신 프록시 객체를 만들어서 주입해 줍니다. 이 프록시 객체가 중간에서 요청을 가로채, AOP 로직(부가 기능)을 먼저 수행하고, 그 다음에 실제 객체의 메서드(핵심 기능)를 호출합니다.

  • 결론: AOP를 통해 중복 코드를 제거하고, 개발자는 순수한 비즈니스 로직에만 집중할 수 있게 되어 코드의 가독성과 유지보수성이 향상됩니다.

최종 요약

  • IoC (제어의 역전): "만들고 관리하는 제어권을 프레임워크에게 넘긴다"는 철학.

  • DI (의존성 주입): IoC 철학을 구현하기 위해, 외부에서 의존성을 넣어주는 기술.

  • AOP (관점 지향 프로그래밍): DI를 통해 만들어진 객체들 사이의 관계에, 공통 부가 기능을 깔끔하게 추가하는 기술.

이 세 가지가 유기적으로 결합하여, 개발자가 마치 레고 블록을 조립하듯 각자의 역할에만 충실한 독립적인 객체들을 만들면, 스프링이 알아서 조립(DI)하고, 여기에 필요한 공통 기능(AOP)까지 덧붙여 강력하고 유연한 애플리케이션을 완성해주는 것입니다.

@Controller 애너테이션이 붙은 컨트롤러와 @RestController라는 애너테이션이 붙은 컨트롤러가 있다 둘의 차이는?

@Controller 애너테이션은 MVC 패턴에서 사용되고 각 @RequestMapping들의 반환 값이 JSON이 아닌 뷰(view) 경로가 됩니다. 즉 클라이언트는 뷰를 통해 렌더링된 HTML 페이지를 보게 됩니다. 반면 @RestConroller는 각각의 @Requestmapping에 @ResponseBody 애너테이션이 붙어 있는 것과 동일합니다. 즉 , 뷰가 아니라 JSON을 응답으로 반환합니다.

Spring 컨테이너(ApplicationContext)가 Bean을 생성하고 관리하는 전체 라이프사이클에 대해 설명해주세요.
@Component, @Service, @Repository, @Controller 어노테이션의 차이점은 무엇이며, 기능적으로 동일한데 왜 구분해서 사용해야 할까요?

@Configuration, @Bean, @Component 차이, @Configuration 어노테이션의 proxyBeanMethods 속성은 무엇이며, true와 false일 때 어떤 차이가 있나요?
  1. IoC(Inversion of Control)와 DI(Dependency Injection)의 개념을 설명하고, Spring을 사용함으로써 얻는 이점은 무엇인가요

  2. Bean의 Scope에는 어떤 종류가 있으며, 기본 스코프는 무엇인가요? prototype 스코프의 Bean을 singleton 스코프의 Bean에 주입하면 어떤 문제가 발생할까요?

  3. Spring의 DI 방식 3가지(생성자, 필드, Setter)를 비교하고, 왜 생성자 주입 방식이 권장되는지 설명해주세요.

  4. 순환 참조(Circular Dependency)는 왜 발생하며, Spring은 이를 어떻게 해결(또는 해결하지 못)하나요?

  5. @Transactional 어노테이션의 동작 원리를 AOP(관점 지향 프로그래밍) 관점에서 설명해주세요.

  6. @Transactional(readOnly = true) 옵션을 사용하면 어떤 성능상의 이점이 있으며, 그 이유는 무엇인가요?

  7. Spring의 트랜잭션 전파(Propagation) 옵션에는 어떤 것들이 있으며, REQUIRED와 REQUIRES_NEW의 차이점은 무엇인가요?

  8. JPA 엔티티를 Controller의 응답(Response) DTO로 직접 반환하면 안 되는 이유는 무엇인가요? (최소 3가지 이상)

  9. Spring Boot의 Auto-Configuration(@EnableAutoConfiguration)은 어떤 원리로 동작하나요?

  10. Spring Security의 Filter Chain 구조에 대해 설명하고, 인증(Authentication)과 인가(Authorization)가 어느 단계에서 일어나는지 설명해주세요.

  11. CORS(Cross-Origin Resource Sharing)란 무엇이며, Spring에서 이를 해결하는 방법은 무엇인가요?

  12. DispatcherServlet의 동작 흐름에 대해 설명해주세요. (요청 -> 응답까지)

  13. PSA(Portable Service Abstraction)란 무엇이며, Spring이 이를 통해 개발자에게 제공하는 가치는 무엇인가요?

  14. Filter와 Interceptor의 차이점은 무엇이며, 각각 어떤 용도로 사용해야 할까요?

  15. 영속성 컨텍스트(Persistence Context)란 무엇이며, '더티 체킹(Dirty Checking)'의 원리에 대해 설명해주세요.

  16. OSIV(Open Session In View) 패턴의 장단점에 대해 설명해주세요.

  17. Spring WebFlux와 같은 리액티브 프로그래밍이 기존의 스레드 기반 모델과 비교하여 어떤 장점을 가지나요?

  18. @SpringBootApplication 어노테이션 안에 포함된 3가지 핵심 어노테이션은 무엇이며, 각각의 역할은 무엇인가요?

  19. application.yml(또는 properties) 파일의 설정값이 Bean에 주입되기까지의 과정을 설명해주세요.

  20. Spring Actuator의 역할은 무엇이며, 실무에서 어떻게 활용할 수 있을까요?

  21. @Autowired는 어떻게 동작하나요? 타입으로 먼저 찾나요, 이름으로 먼저 찾나요? 만약 같은 타입의 Bean이 여러 개 있다면 Spring은 어떻게 처리하나요?

  22. AOP(관점 지향 프로그래밍)의 주요 용어(Advice, Pointcut, Join Point, Weaving)에 대해 설명해주세요.

  23. Spring의 테스트 지원 기능(@SpringBootTest, @WebMvcTest, @DataJpaTest)들의 차이점과 각각의 사용 목적을 설명해주세요.

  24. Spring의 RestTemplate과 WebClient의 차이점은 무엇이며, 왜 WebClient 사용이 권장되나요?

  25. Spring Data JPA의 JpaRepository 인터페이스를 선언하기만 했는데 어떻게 구현체가 만들어지고 동작할 수 있는지 설명해주세요.

  26. Spring의 이벤트 발행/구독 모델(ApplicationEventPublisher)에 대해 설명하고, 어떤 경우에 활용할 수 있을까요?

  27. Spring의 Profile(@Profile) 기능은 무엇이며, 어떤 용도로 사용되나요?

  28. Filter에서 예외가 발생하면 @ControllerAdvice에서 처리할 수 있나요? 없다면 그 이유는 무엇이며 어떻게 해결할 수 있을까요?

  29. Spring의 ResponseEntity를 사용하는 이유는 무엇이며, @ResponseBody와 어떤 차이가 있나요?

  30. Spring Batch의 기본 아키텍처(Job, Step, ItemReader, ItemProcessor, ItemWriter)에 대해 설명해주세요.

  31. Spring Cloud가 마이크로서비스 아키텍처에서 해결하고자 하는 문제들은 무엇인가요?

  32. Converter와 Formatter의 차이점은 무엇이며, 각각 어떤 용도로 사용되나요?

  33. Spring MVC의 @ModelAttribute와 @RequestBody는 각각 언제 사용되며, 어떤 차이가 있나요?

  34. Spring에서 정적 리소스(static resources)를 처리하는 방식에 대해 설명해주세요.

  35. Spring의 캐시 추상화(@Cacheable, @CacheEvict)에 대해 설명하고, 어떻게 동작하는지 설명해주세요.

  36. Spring Boot가 내장 웹 서버(Embedded Web Server)를 사용하는 방식의 장단점은 무엇인가요?

  37. Spring의 HandlerMethodArgumentResolver는 무엇이며, 어떻게 커스텀하게 만들 수 있나요?

  38. Spring에서 Bean의 초기화(@PostConstruct)와 소멸(@PreDestroy) 시점에 특정 로직을 실행하는 방법에 대해 설명해주세요.

  39. Spring MVC의 요청 처리 과정에서 ViewResolver의 역할은 무엇인가요?

  40. Spring에서 발생하는 예외들을 어떻게 공통으로 처리할 수 있는지, 그 방법들을 설명해주세요. (@ControllerAdvice)

  41. Spring Security에서 PasswordEncoder의 역할은 무엇이며, 왜 bcrypt가 권장되나요?

  42. Spring Data JPA에서 @Query 어노테이션을 사용하여 JPQL을 작성할 때의 장점은 무엇인가요?

  43. Spring에서 스케줄링 작업(@Scheduled)을 어떻게 구현할 수 있는지 설명해주세요.

  44. Spring Boot의 banner.txt는 어떤 역할을 하며, 어떻게 커스터마이징할 수 있나요?

  45. Servlet이란 무엇이며, Tomcat과 같은 서블릿 컨테이너의 역할은 무엇인가요?

  46. Spring MVC에서 HTTP 요청 파라미터를 받는 여러 가지 방법을 설명해주세요.

  47. Spring에서 AOP를 구현하는 방식(프록시 기반)의 한계점은 무엇인가요?

Last updated