티스토리 뷰

컴포넌트 스캔

자동 주입과 함께 사용하는 추가 기능은 컴포넌트 스캔입니다. 컴포넌트 스캔을 사용하면 설정 클래스에서 @Bean을 사용하지 않더라도 원하는 클래스를 빈 객체로 만들수 있습니다.

 

설정 클래스에 다음과 같이 있다고 해봅시다.

package config;

import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

import spring.CachedMemberDao;
import spring.ChangePasswordService;
import spring.FastMemberDao;
import spring.MemberDao;
import spring.MemberRegisterService;
import spring.testPrint;

@Configuration
public class AppCtx {
	
	@Bean
	public MemberDao memberDao1() {
		return new MemberDao();
	}
	@Bean
	public ChangePasswordService changePwdSvc() {
		ChangePasswordService pwdSvc = new ChangePasswordService();
		return pwdSvc;
	}
	
	@Bean
	public MemberRegisterService memberRegSvc() {
		return new MemberRegisterService();
	}
}

MemberDao, ChangePasswordService, MemberRegisterService 클래스에 @Component를 적어준다면 위 코드는 아래와 같이 바뀝니다.

 

package config;

import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

import spring.CachedMemberDao;
import spring.ChangePasswordService;
import spring.FastMemberDao;
import spring.MemberDao;
import spring.MemberRegisterService;
import spring.testPrint;

@Configuration
@ComponentScan(basePackages = {"spring"})
public class AppCtx {
}

 

@ComponentScan에서 @Component 어노테이션을 스캔하기 위해 스캔할 패키지를 적어야합니다. 위 세 클래스 모두 spring 패키지 내에 있으므로 spring만 인자로 전달해주면 됩니다.

 

기본적으로 속성값을 전달하지 않으면 해당클래스의 이름에서 맨 앞글자를 소문자로 바꾼 이름을 빈 객체의 이름으로 사용하게 됩니다.

package spring;

import java.time.LocalDateTime;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;

@Component
public class MemberRegisterService {
	
	@Autowired
	private MemberDao memberDao;
	
    ...
}

이 경우 빈 객체의 이름으로 memberRegisterService가 설정됩니다.

 

@Component와 @ComponentScan설정이 완료되었다면 Main함수에서 빈 객체의 이름을 직접적으로 다루는 $getBean$을 다음과 같이 수정해줍니다.

	private static void processNewCommand(String[] args) {
		MemberRegisterService regSvc = ctx.getBean(MemberRegisterService.class);
        ..
    }
   	private static void processChangeCommand(String[] args) {
		ChangePasswordService pwdSvc= ctx.getBean(ChangePasswordService.class);
		...
	}

빈 객체의 이름을 전달하지 않는 것을 알 수 있습니다.

 

충돌

자동으로 빈을 생성하는 과정에서 크게 두 가지 종류의 충돌이 발생할 수 있습니다. 첫째는 다른 패키지에서 같은 클래스 이름을 사용하는 경우입니다. 이 경우에선 어노테이션 속성을 주어서 구별하는 방식으로 해결 가능합니다. 두 번째는 수동으로 @Bean 어노테이션을 통해 설정 클래스에 빈 객체를 등록하는 것입니다. 이 경우는 충돌이 일어나는 대신 수동으로 등록한 빈 객체가 우선적으로 생성이 됩니다. 이를 해결하기 위해서는 설정 클래스에서 @Bean을 사용하는 함수명을 바꾸는 방식을 통해 해결 가능합니다.

'Books > 스프링5 프로그래밍 입문' 카테고리의 다른 글

[Spring] Proxy 객체  (0) 2021.03.12
[Spring] 빈의 라이프 사이클  (0) 2021.03.10
[Spring] Autowired 어노테이션  (0) 2021.03.08
[Spring] Container의 사용  (0) 2021.03.07
[Spring] Dependency Injection  (0) 2021.03.06
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/02   »
1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28
글 보관함