※ 해당 강의 내용을 필기하고 실습 시 트러블슈팅하는 내용으로 구성됨
※ 강의는 Eclipse 환경이지만, 해당 게시물에선 intelliJ 환경에서 작업
👉 이 섹션에 이용할 GitHub 폴더를 북마크에 추가하세요(이전 섹션과 동일한 폴더).
https://github.com/in28minutes/master-spring-and-spring-boot/tree/main/01-spring
👉 문제 디버깅을 위한 도움말
- 4단계 종료 후 코드 백업: https://github.com/in28minutes/master-spring-and-spring-boot/blob/main/01-spring/02-Step04.md
- 자세한 단계별 변경 사항: https://github.com/in28minutes/master-spring-and-spring-boot/blob/main/01-spring/step-by-step-code-changes/step-by-step-guide.md#section-02
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 쓸 필요 없음)
- Spring team recommends Constructor-based injection as dependencies are automatically set when an object is created!
- 중요한 용어(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 (..): An instance of class will be managed by Spring framework
- @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
- Typical problems:
- You need to help Spring Framework find a match
- 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
- 1: Mark one of them as @Primary
- 1: If no match is found Result: Exception is thrown
- 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!
- Example: Business Layer class talks to a Data Layer class
- 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!
- INSTEAD of FOCUSING on objects, their dependencies and wiring
- 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
- Create classes and interfaces as needed
'스프링부트' 카테고리의 다른 글
[Spring Boot 3 & Spring Framework 6 마스터하기!] SpringFramework 고급 기능 살펴보기(1) (0) | 2025.03.20 |
---|---|
Spring @Component vs @Bean (0) | 2025.03.12 |
[Spring Boot 3 & Spring Framework 6 마스터하기!] Java Spring Framework 시작하기 (0) | 2025.02.23 |
[스피링부트 입문 김영한] javax 및 autowire 에러 발생 (0) | 2024.11.20 |
[스피링부트 입문 김영한] 세팅 (0) | 2024.11.19 |