스프링 빈 등록 방법

2024. 2. 25. 18:18SPRING

스프링 빈 등록 방법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