스프링부트

[Spring Boot 3 & Spring Framework 6 마스터하기!] Spring Framework를 사용하여 Java 객체를 생성하고 관리하기

jinaenya 2025. 2. 23. 21:57

※ 해당 강의 내용을 필기하고 실습 시 트러블슈팅하는 내용으로 구성됨

※ 강의는 Eclipse 환경이지만, 해당 게시물에선 intelliJ 환경에서 작업

👉 이 섹션에 이용할 GitHub 폴더를 북마크에 추가하세요(이전 섹션과 동일한 폴더).

https://github.com/in28minutes/master-spring-and-spring-boot/tree/main/01-spring

 

👉 문제 디버깅을 위한 도움말

Java 객체의 생성/관리를 위한 Spring Framework에 대한 이해

  • Bean을 수동으로 만들 필요 없이, Spring Framework가 Bean을 생성해준다면 그 방법은?
    • Configuration 파일과 App 파일을 합침
    • Spring이 Bean을 자동 생성하려면(해당되는 class의 인스턴스 생성을 Spring에 요청하려면) @Component 를 추가하면 됨.
      • Spring이 관리하게 되는 요소.
      • Annotated class가 Component
      • Anntation based Configuration&Classpath scanning을 사용할 때, auto detection(자동 감지)에 대한 후보로 간주함 
    • Spring은 객체 관리, auto-wiring 수행만이 아니라, '객체를 생성해줌'
      • @Component와 @ComponentScan을 바탕으로! 
  • 만약 잘 실행되지 않는다면 @ComponentScan을 제대로 설정했는지 먼저 확인
    ComponentScan에 지정된 경로로 이동해서, @Component가 있는지 확인하면 됨.
  • 만약 여러 게임 클래스들에 @Component를 지정한다면?
    • 에러 발생(.UnsatisfiedDependencyException)
    • Spring Framework가 GamingConsole interface의 구현을 찾는 중인데, GamingConsole Interface의 구현을 2개나 발견하게 된 것임(MarioGame, PacmanGame)
    • 해결방법
      • @Primary 사용하기
      • @Qualifier 사용하기
  • @Primary vs @QUalifier - Which one to use?
    • @Primary - A bean should be given preference when multiple candidates are qualified
    • @Qualifier - A specific bean should be auto-wired (name of the bean can be used as qualifier)
    • ALWAYS think from the perspective of the class using the SortingAlgorithm:
      • 1: Just @Autowired: Give me (preferred) SortingAlgorithm
      • 2: @Autowired + @Qualifier: I only want to use specific SortingAlgorithm - RadixSort
      • (REMEMBER) @Qualifier has higher priority then @Primary
@Component @Primary
class QuickSort implement SortingAlgorithm {}

@Component
class BubbleSort implement SortingAlgorithm {}

@Component @Qualifier("RadixSortQualifier")
class RadixSort implement SortingAlgorithm {}

@Component
class ComplexAlgorithm
	@Autowired
	private SortingAlgorithm algorithm;

@Component
class AnotherComplexAlgorithm
	@Autowired @Qualifier("RadixSortQualifier")
	private SortingAlgorithm iWantToUseRadixSortOnly;
  • 의존성 주입(Dependency Injection) 유형
    • Constructor-based(생성자 기반) : Dependencies are set by creating the Bean using its Constructor
    • Setter-based(수정자 기반) : Dependencies are set by calling setter methods on your beans
    • Field(필드): No setter or constructor. Dependency is injected using reflection.
    • Question: Which one should you use?
      • Spring team recommends Constructor-based injection as dependencies are automatically set when an object is created!
        • 즉, 하나의 메소드에 모든 초기화가 발생하기 때문임. 초기화 완료 시 Bean을 사용할 준비가 되는 거니까!
        • 의존성 정의해서 생성자 만들기만 하면 됨(@Autowired 쓸 필요 없음)

필드 의존성 주입
수정자 기반 의존성 주입

 

생성자 기반의 의존성 주입(@Autowired 주석처리해도 알아서 생성자 사용해서 객체 만듦)

 

 

  • 중요한 용어(Terminology) 정리
    • @Component (..): An instance of class will be managed by Spring framework
      • 이걸 추가할 때마다 특정 클래스가 컴포넌트 스캔에 있다면, 해당 클래스의 인스턴스(Spring Bean)이 생성되고 Springframework에서 그걸 관리하게 됨
    • Dependency: GameRunner needs GamingConsole impl!(GamingConsole의 구현)
      • GamingConsole Impl (Ex: MarioGame) is a dependency of GameRunner
    • Component Scan: How does Spring Framework find component classes?
      It scans packages! (@ComponentScan("com.in28minutes"))
    • Dependency Injection: Identify beans, their dependencies and wire them together (provides IOC - Inversion of Control, 제어 반전)
      • 제어권이 [프로그래머/명시적인 코드 작성]에서 SpringFramework로 넘어갔으니 IOC
      • Spring Beans: An object managed by Spring Framework
      • IoC container: Manages the lifecycle of beans and dependencies
        • Types: ApplicationContext (complex), BeanFactory (simpler features - rarely used)
      • Autowiring: Process of wiring in dependencies for a Spring Bean
  • @Component vs @Bean
    • Bean 생성 전에 수행해야하는 비즈니스 로직이 많거나, Spring Security 같은 제 3자 라이브러리에 대한 Bean을 인스턴스화(Instantiating) 하고 있다면, @Bean 사용을 추천함

  • auto-wiring에 대한 이해( When a dependency needs to be @Autowired, IOC container looks for matches/candidates (by name and/or type) )
    • 1: If no match is found Result: Exception is thrown
      • You need to help Spring Framework find a match
        • Typical problems:
          • @Component (or ..) missing
          • Class not in component scan
    • 2: One match is found
      • Result: Autowiring is successful
    • 3: Multiple candidates
      • Result: Exception is thrown
      • You need to help Spring Framework choose between the candidates
        • 1: Mark one of them as @Primary
          • If only one of the candidates is marked @Primary, it becomes the auto-wired value
        • 2: Use @Qualifier - Example: @Qualifier("myQualifierName")
          • Provides more specific control
          • Can be used on a class, member variables and method parameters
  • Why do we have a lot of Dependencies?
    • In Game Runner Hello World App, we have very few classes
    • BUT Real World applications are much more complex:
      • Multiple Layers (Web, Business, Data etc)
      • Each layer is dependent on the layer below it!
        • Example: Business Layer class talks to a Data Layer class
          • Data Layer class is a dependency of Business Layer class
        • There are thousands of such dependencies in every application!
    • With Spring Framework:
      • INSTEAD of FOCUSING on objects, their dependencies and wiring
        • You can focus on the business logic of your application!
      • Spring Framework manages the lifecycle of objects:
        • Mark components using annotations: @Component (and others..)
        • Mark dependencies using @Autowired
        • Allow Spring Framework to do its magic!
    • Ex: BusinessCalculationService
      • Create classes and interfaces as needed
        • Use constructor injection to inject dependencies
        • Make MongoDbDataService as primary
        • Create a Spring Context
          • Prefer annotations
          • Retrieve BusinessCalculationService bean and run findMax method