본문 바로가기
spring

@AutoConfig, @ComponentScan, @Autowired, Filter

by 김선지 2024. 5. 28.

AppConfig에서는 @bean으로직접 설정정보 작성하고 의존관계도 따로 명시해야한다.

AutoConfig (@ComponentScan, @Autowired)를 사용하면 DI를 알아서 해준다

// configure
package hello.core;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;

@Configuration
@ComponentScan(
        excludeFilters = @ComponentScan.Filter(type = FilterType.ANNOTATION, classes = Configuration.class)
)
public class AutoAppConfig {

}

 


// test
package hello.core.scan;

import hello.core.AutoAppConfig;
import hello.core.member.MemberService;
import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.Test;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class AutoApConfigTest {
    @Test
    void basicScan() {
        AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(AutoAppConfig.class);
        MemberService memberService = ac.getBean( MemberService.class);
        // memberServiceImpl 이런 이름으로 Bean 등록 <- class 이름이 MemberServiceImpl이라
        // 이름 따로 설정하고 싶으면 @Component("memberService") <- 이렇게 설정
        Assertions.assertThat(memberService).isInstanceOf(MemberService.class);
    }
}

컴포넌트 스캔을 사용하려면 @ComponentScan을 넣어주면 된다.

이건 @Component 애노테이션이 붙은 클래스를 모두 스캔해서 스프링 빈으로 등록한다. (package 안에서)

다만 @Configuration도 @Component를 상속하므로 @Configuration이 등록된 설정 정보도 등록되어버리기 때문에 여기서는 Configuration.class를 제외함.

스캔의 기본 전략은 타입이 같은 빈을 찾아서 주입한다. (getBean(MemberRepository.class)와 동일 <- interface)

 

그래서 bean으로 설정할 class파일을 모두 @Component를 붙여줘야한다.

Dependency가 필요한 빈은 @Autowired 태그를 붙여준다 (생성자, setter, 등)

그러면 spring이 알아서 @Component 태그가 붙은 빈을 찾아서 DI를 해준다.

ex) service에서 쓰는 repository

 

컴포넌트 스캔의 기본 대상은

@Controller   <= 스프링 MVC 컨트롤러로 인식

@Repository <=  스프링 데이터 접근 계층으로 인식하고, 데이터 계층의 예외를 스프링 예외로 변환해준다.

@Configuration <= 스프링 설정 정보로 인식하고, 스프링 빈이 싱글톤을 유지하도록 처리해준다.

@Service <= 큰 기능은 하지 않고, 핵심 비즈니스 로직이 있다.

@Component인데 Component를 제외한 모든 애노테이션을 ctrl 클릭해보면 Component가 들어있는 걸 알 수 있다.

 

// Spring Boot의 시작 컴포넌트인 @SpirngBootApplication에는 @ComponentScan이 안에 들어있다. 그래서 쓸 필요가 없다.

 

 


빈 중복 등록과 충돌

 

자동 빈등록 vs 자동 빈등록 - 동일한 컴포넌트 이름이 2개 - Exception 반환

수동 빈등록 vs 자동 빈등록 - 수동 빈이 자동 빈을 오버라이딩 해버린다.

- 다만 이 경우에는 오류일 확률이 높기 때문에 스프링 부트로 실행하면 Exception을 반환한다.

 

 

주로 메인 비즈니스 로직에는 자동 등록을 이용하고 db 연결 등의 서브 로직에는 수동 등록 @Bean을 이용하는 경우가 많다고 한다.