2024. 2. 25. 18:18ㆍSPRING
스프링 빈 등록 방법1. 컴포넌트 스캔
이전 글에서 프로그램을 실행하면
스프링 프레임워크가 특정 범위에 있는 특별한 표식을 읽어 '스프링 빈'을 생성하고, 컨테이너에 등록한다고 했다.
이전 글에서 특별한 표식의 예로
@Controller , @Service , @Repository 등으로 들었는데
이 애노테이션을 거꾸러 거슬러 올라가 보면
@Component 애노테이션을 발견할 수 있다.
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Repository {
@AliasFor(
annotation = Component.class
)
String value() default "";
}
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Service {
@AliasFor(
annotation = Component.class
)
String value() default "";
}
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Controller {
@AliasFor(
annotation = Component.class
)
String value() default "";
}
즉. 프로그램 실행 시, 스프링 프레임워크가 하는 탐색 행위를 '컴포넌트 스캔' 이라고 한다.
이를 통해 스프링 빈 등록이 가능하다.
음? 그럼 @Component(@Repository , @Controller, @Service) 애노테이션만 붙이면 뭐든 등록 가능?
아니다. 드넓은 우주 속에서 캬라멜 팝콘 하나 찾는 것도 아니고, 탐색이라는 행위의 효율화를 위해 당연스럽게도
'탐색 범위'가 존재한다.
컴포넌트 기본 탐색 범위
@SpringBootApplication <- 시작점이다. 이 시작점이 존재하는 패키지의 '하위 패키지'까지 컴포넌트 스캔이 진행된다.
예시)
아래 예시에서는
com.start.spring.java.dp1.dp2 등은 탐색 범위이나
com.start.spring.java 와 같이 시작점과 동일 선상 혹은
com.start.spring.noway 와 같이 다른 패키지에 있다면 스캔이 진행되지 않으니 주의하자.
package com.start.spring.java;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class JavaApplication {
public static void main(String[] args) {
SpringApplication.run(JavaApplication.class, args);
}
}
왜 저기(@SpringBootApplicaiotn)가 시작점이냐고?
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(
excludeFilters = {@Filter(
type = FilterType.CUSTOM,
classes = {TypeExcludeFilter.class}
), @Filter(
type = FilterType.CUSTOM,
classes = {AutoConfigurationExcludeFilter.class}
)}
)
public @interface SpringBootApplication {
거슬러 올라가 보면 @ComponentScan이 저 안에 들어가 있다.
스프링 빈 등록 방법2. 스프링 빈 직접 등록(Java Configuration)
컴포넌트 스캔 범위 내에서,
클래스, 혹은 메서드 단위에
@Configuration, @Bean 을 사용하면 클래스는 인스턴스 생성 후 등록, 메서드는 메서드 실행 결과값을 등록한다.
따라 쳐보면서 학습 해보자.
현재 Bean 직접 등록에 대해 학습하기 위해 기존에 작성했던 MemberService , MemberRepository 클래스에서 @Component 가 포함된 애노테이션@Repository, @Service 를 제거 했다.
@Configuration
public class SpringConfig {
@Bean
public MemberService memberService() {
return new MemberService(memberRepository());
}
@Bean
public MemberRepository memberRepository() {
return new MemoryMemberRepository();
}
}
각 방식의 장단점
DI(의존 주입) 방식
1. 필드 선언 단계에서의 초기화를 통한 주입
2. setter 를 통한 주입
3. 생성자를 통한 주입
필드를 통한 주입
한번 코드를 작성하고 나면 더 이상의 조작이 불가하다.
@Autowired private final MemberService memberService;
setter 를 통한 주입
setter 를 통해 다른 객체가 주입될 수 있다.
private MemberService memberService;
@Autowired
public void setMemberController(MemberService memberService) {
this.memberService = memberService;
}
생성자를 통한 주입
프로그램 시작 시
1. 컴포넌트 스캔
2. 빈 등록
3. 의존주입(조립)
이 진행됨.
private final 을 통해 변경까지 막으면, 프로그램 동작에서 불필요한 동작을 막을 수 있음.
@Controller
public class MemberController {
private final MemberService memberService;
@Autowired
public MemberController(MemberService memberService) {
this.memberService = memberService;
}
}
의존 관계가 프로그램 실행 중 동적으로 변하는 경우는 없으므로, 생성자 주입이 권장된다.
'SPRING' 카테고리의 다른 글
| spring-boot-devtools (0) | 2024.08.03 |
|---|---|
| 테스트_@Transactional (0) | 2024.02.27 |
| 의존 주입 (0) | 2024.02.25 |
| 테스트 코드 작성 시의 에로사항 (0) | 2024.02.24 |
| 웹 개발 방식_API (0) | 2024.02.21 |