3. 스프링 DI(Dependency Injection) #5 두 개 이상의 설정 파일 사용하기

2021. 7. 6. 23:37JAVA/Spring

본 글은 최범균 저자의 초보 웹 개발자를 위한 스프링5 프로그래밍 입문의 내용을 복습하기 위해 작성된 글입니다.

8. 두 개 이상의 설정 파일 사용하기

스프링을 이용해서 어플리케이션을 개발하다보면 적게는 수십 개에서 많게는 수백여 개 이상의 빈을 설정하게 된다. 설정하는 빈의 개수가 증가하면 한 개의 클래스 파일에 설정하는 것보다 영역별로 설정 파일을 나누면 관리하기가 편해진다.

 

@Autowired를 이용한 두 개이상의 설정 파일 사용

스프링은 한 개 이상의 설정 파일을 이용해서 컨테이너를 생성할 수 있다. 아래의 두 설정 클래스 파일은 이전에 작성한 AppCtx.java의 빈 설정을 나누어서 설정한 것이다.

AppConf1.java

@Configuration
public class AppConf1 {
	@Bean
	public MemberDao memberDao()
	{
		return new MemberDao();
	}
	
	@Bean
	public MemberPrinter memberPrinter()
	{
		return new MemberPrinter();
	}
}

AppConf2.java

@Configuration
public class AppConf2 {
	@Autowired
	private MemberDao memberDao;
	@Autowired
	private MemberPrinter memberPrinter;
	
	@Bean
	public MemberRegisterService memberRegSvc()
	{
		return new MemberRegisterService(memberDao);
	}
	
	public ChangePasswordService changePwdSvc()
	{
		ChangePasswordService pwdSvc = new ChangePasswordService();
		pwdSvc.setMemberDao(memberDao);
		return pwdSvc;
	}
	
	@Bean
	public MemberListPrinter listPrinter()
	{
		return new MemberListPrinter(memberDao, memberPrinter);
	}
	
	@Bean
	public MemberInfoPrinter infoPrinter()
	{
		MemberInfoPrinter infoPrinter = new MemberInfoPrinter();
		infoPrinter.setMemDao(memberDao);
		infoPrinter.setPrinter(memberPrinter);
		return infoPrinter;
	}
	
	@Bean
	public VersionPrinter versionPrinter()
	{
		VersionPrinter versionPrinter = new VersionPrinter();
		versionPrinter.setMajorVersion(5);
		versionPrinter.setMinorVersion(0);
		return versionPrinter;
	}
}

 

@Autowired
private MemberDao memberDao;

위의 @Autowrited 애노테이션은 스프링의 자동 주입 기능을 위한 것이다. 스프링 설정 클래스의 필드에 @Autowired 애노테이션을 붙이면 해당 타입의 빈을 찾아서 필드에 할당한다. 

위 설정의 경우 스프링 컨테이너는 MemberDao 타입의 빈을 memberDao 필드에 할당한다. AppConf1 클래스에 MemberDao 타입의 빈을 설정했으므로 AppConf2 클래스의 memberDao 필드에는 AppConf1 클래스에서 설정한 빈이 할당된다.

 

두 개 이상의 설정 클래스를 가진 스프링 컨테이너 생성 예시

ctx = new AnnotationConfigApplicationContext(AppConf1.class, AppConf2.class);

AnnotationConfigApplicationContext의 생성자는 가변 인자이기 때문에 설정 클래스의 목록을 콤바로 구분해서 전달이 가능하다.

 

8.1 @Configuration 애노테이션, 빈, @Autowired 애노테이션

@Autowired 애노테이션이란?

  • 스프링 빈에 의존하는 다른 빈을 자동으로 주입하고 싶을 때 사용한다.

@Autowired 애노테이션 활용

MemberInfoPrinter 클래스에 @Autowired 애노테이션을 사용

public class MemberInfoPrinter {
	@Autowired
	private MemberDao memDao;
	@Autowired
	private MemberPrinter printer;
	
	public void printMemberInfo(String email)
	{
		Member member = memDao.selectByEmail(email);
		if(member==null)
		{
			System.out.println("데이터 없음\n");
			return;
		}
		printer.print(member);
		System.out.println();
	}
	
	public void setMemDao(MemberDao memDao) {
		this.memDao = memDao;
	}
	public void setPrinter(MemberPrinter printer) {
		this.printer = printer;
	}
	
	
}

두 필드에 @Autowired 애노테이션을 붙였다. 이렇게 @Autowired 애노테이션을 의존 주입 대상에 붙이면 다음 코드처럼 스프링 설정 클래스의 @Bean 메서드에서 의존 주입을 위한 코드를 작성하지 않아도 된다.

@Bean
public MemberInfoPrinter infoPrinter()
{
	MemberInfoPrinter infoPrinter = new MemberInfoPrinter();
	//생략 가능
	//세터 메서드를 사용해서 의존주입을 하지 않아도
	//스프링 컨테이너가 @Autowired를 붙인 필드에
	//자동으로 해당 타입의 빈 객체를 주입
	//infoPrinter.setMemDao(memberDao);
	//infoPrinter.setPrinter(memberPrinter);
	return infoPrinter;
}

 

설정 클래스에 @Autowired 애노테이션 사용

@Configuration
public class AppConf2 {
	@Autowired
	private MemberDao memberDao;
	@Autowired
	private MemberPrinter memberPrinter;

스프링 컨테이너는 설정 클래스에서 사용한 @Autowired에 대해서도 자동 주입을 처리한다. 실제로 스프링은 @Configuration 애노테이션이 붙은 설정 클래스를 내부적으로 스프링 빈으로 등록한다. 그리고 다른 빈과 마찬가지로 @Autowired가 붙은 대상에 대해 알자은 빈을 자동으로 주입한다.

 

즉 스프링 컨테이너는 AppConf2 객체를 빈으로 등록하고, @Autowired 애노테이션이 붙은 두 필드-memberDao와 memberPrinter에 해당 타입의 빈 객체를 주입한다.

 

8.2 @Import 애노테이션 사용

두 개 이상의 설정 파일을 사용하는 또 다른 방법은 @Import 애노테이션을 사용하는 것이다. @Import 애노테이션은 함께 사용할 설정 클래스를 지정하면 된다.

 

 

@Import 애노테이션 사용

@Configuration
@Import(AppConf2.class)
public class AppConfImport {
	@Bean
	public MemberDao memberDao()
	{
		return new MemberDao();
	}
	
	@Bean
	public MemberPrinter memberPrinter()
	{
		return new MemberPrinter();
	}
}

AppConfImport 설정 클래스를 사용하면, @Import 애노테이션으로 지정할 AppConf2 설정 클래스도 함께 사용하기 때문에 스프링 컨테이너를 사용할 때 AppConf2 설정 클래스를 지정할 필요가 없다.

public class MainForSpring {
	private static ApplicationContext ctx = null;
	
	public static void main(String args[]) throws IOException
	{
		ctx = new AnnotationConfigApplicationContext(AppConfImport.class);
		...생략
	}
    
    ...생략
}

 

@Import 애노테이션, 두 개 이상의 설정 클래스 지정

@Configuration
@Import({AppConf1.class, AppConf2.class})
public class AppConfImport{

}

References

초보 웹 개발자를 위한 스프링5 프로그래밍 입문, 최범균 저