@Autowired의 사용

2017. 1. 25. 13:22Dev/Spring

반응형


@Autowired


오토와이어링은 스프링이 빈의 요구 사항과 매칭 되는 애플리케이션 컨텍스트상에서 다른 빈을 찾아 빈 간의 의존성을 자동으로 만족시키도록 하는 수단이다. 오토와이어링 수행을 하도록 지정하기 위해서는 다음 스프링의 @Autowired 애너테이션을 사용한다.


보통 필드에 사용하는 방법은 아래와 같다.


필드


package demo;

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

@Component
public class CDPlayer implements MediaPlayer{
	
	@Autowired
	private CompactDisc cd;
	
}

혹은 아래의 2가지 방법(메소드, 생성자)으로도 사용한다.



생성자


package demo;

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

@Component
public class CDPlayer implements MediaPlayer{
	
	//@Autowired
	private CompactDisc cd;
	
	@Autowired 
	public CDPlayer(CompactDisc cd) {
		this.cd = cd;
	}
	
}

생성자로 사용시에는 디폴트 생성자에 주의하자.



메소드


package demo;

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

@Component
public class CDPlayer implements MediaPlayer{
	
	//@Autowired // 생성자, 세터메소드(굳이 setter일 필요는 없음), 필드에 사용 가능하다.
	private CompactDisc cd;
	
	@Autowired // setter 메소드가 아니어도 주입된다.
	public void setCompactDisc(CompactDisc cd){
		this.cd = cd;
	}
	
}


위의 3가지 경우 모두 CompactDisc cd 필드에 스프링 컨텍스트가 만든 빈이 주입된다.


Required가 false 일 때, 스프링은 오토와이어링을 시도 하지만 매칭되는 빈이 없으면 와이어링 되지 않은 상태로 남겨진다. 

@Autowired(required=false)


@Autowired는 스프링에서 정의한 애너테이션이다. 오토와이어링을 위해 스프링 기반의 애너테이션을 사용하기 힘든 경우에는 대신 @Inject 애너테이션 사용을 고려한다. @Inject는 자바 종속객체 정의에 있다.



오토와이어링의 모호성


// 다음과 같은 오토와이어링해야할 빈이 있어 세터메소드를 이용한다고 생각해보자.
@Autowired
public void setDessert(Dessert dessert){
	this.setDessert = dessert;
}


// 아래와 같은 class들이 있다고 가정해보자
@Component
public class Cake implements Dessert {...}

@Component
public class Cookies implements Dessert {...}

@Component
public class IceCream implements Dessert {...}

위와 같은 경우에 스프링은 NoUniqueBeanDefinitionException을 발생 시킨다.




@Primary


@Primary는 중복되는 빈에 대해 대표되는 빈을 지정하는 애노테이션이다.

@Component
@Primary // 기본빈을 설정한다.
public class IceCream implements Dessert {...}

//자바설정을 사용하면 다음과 같이 해결할 수도 있다.
@Configuration
@ComponentScan
public class DessertConfig {
	// 이 때 각 class에 설정된 @Component를 없애야 한다.
	@Bean
	@Primary
	public Dessert iceCream(){
		return new IceCream();
	}
}

//XML 설정을 이용한다면 다음처럼도 가능하다.
<bean id="iceCream" class="com.desserteater.IceCream" primary="true">

중복되는 모호한 빈에 대한 해결책으로 적합해 보이지만 @Primary 역시 여러개 지정이 가능하기에 여전히 문제가 있다. 새로운 모호성이 재기되는 것은 마찬가지 때문이다.



@Qualifier


@Qualifier 애너테이션은 수식자를 사용하는 주된 방법이다. 그것은 주입 대상 빈을 지정할 주입 지점에서 @Autowired나 @Inject와 함께 적용된다.

@Autowired
@Qualifier("iceCream")
public void setDessert(Dessert dessert){
	this.dessert = dessert;
}

@Component로 생성된 모든 빈 id는 해당 빈 클래스명의 첫글자가 소문자로 변형된 id를 가진다. IceCream 클래스는 iceCream을 가진다. 위의 코드에서 @Qualifire 애노테이션에 명시된 문자열이 바로 그것이다. 여기서 문제가 발생할 소지가 있다. 만약 IceCream 이름을 Gelato로 변경하거나 IceCream 클래스를 리팩토링하면 어떻게 될까? @Qualifire 수식자와 bean id가 일치하지 않으면 오토와이어링은 실패한다.



맞춤형 수식자


스프링이 만들어준 빈 id 대신에 개발자가 수식자를 지정한다. @Component와 함께 사용해서 지정한다.

@Component
@Qualifier("cold")
class IceCream implements Dessert {}

// 오토와이어링 시켜줄 코드에는 별도로 명시한 수식자를 넣어준다.
@Autowired
@Qualifier("cold")
public void setDessert(Dessert dessert){
	this.dessert = dessert;
}



반응형

'Dev > Spring' 카테고리의 다른 글

스프링 설정 믹싱  (0) 2017.01.25
util 네임 스페이스  (0) 2017.01.25
스프링 설정 파일  (0) 2017.01.25
Spring - ajax return success on sevlet error  (0) 2016.12.16
스프링 컨트롤러 단위테스트 할 경우  (0) 2016.11.29