DEVLOG

의존객체 선택 본문

Spring

의존객체 선택

BINTHEWORLD 2022. 6. 7. 11:39

의존객체 선택이란?

다수의 빈(Bean) 객체 중 의존 객체의 대상이 되는 객체를 선택하는 방법

 

만약 스프링 컨테이너에 동일한 데이터타입의 객체가 2개 이상 있다면 자동 주입 대상 객체를 판단하지 못해서 Exception을 발생시킨다. 아래 코드들은 자동 주입 대상 객체를 판단하지 못하는 예시이다.

appCtxUseAutowired.xml

  • 어노테이션 사용을 위해 <context:annotation-config /> 코드를 사용한다. 
  •  동일한 데이터타입(WordDao) 객체 3개가 있으므로 이러한 객체를 @Autowired 어노테이션으로 주입할 때 에러가 발생할 것임을 예측할 수 있다.
<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans 
 		http://www.springframework.org/schema/beans/spring-beans.xsd 
 		http://www.springframework.org/schema/context 
 		http://www.springframework.org/schema/context/spring-context.xsd">

	<context:annotation-config /> <!-- 어노테이션 사용 -->

	<bean id="wordDao1" class="com.word.dao.WordDao" />
	<bean id="wordDao2" class="com.word.dao.WordDao" />
	<bean id="wordDao3" class="com.word.dao.WordDao" />
	
	<bean id="registerService" class="com.word.service.WordRegisterServiceUseAutowired" />
	
	<bean id="searchService" class="com.word.service.WordSearchServiceUseAutowired" />
	
</beans>

WordRegisterServiceUseAutowired.java 

public class WordRegisterServiceUseAutowired {

	@Autowired
	private WordDao wordDao;
	
	public WordRegisterServiceUseAutowired() {
		
	}
	
	public WordRegisterServiceUseAutowired(WordDao wordDao) {
		this.wordDao = wordDao;
	}
	
	public void register(WordSet wordSet) {
		String wordKey = wordSet.getWordKey();
		if(verify(wordKey)) {
			wordDao.insert(wordSet);
		} else {
			System.out.println("The word has already registered.");
		}
	}
	
	public boolean verify(String wordKey){
		WordSet wordSet = wordDao.select(wordKey);
		return wordSet == null ? true : false;
	}
	
	public void setWordDao(WordDao wordDao) {
		this.wordDao = wordDao;
	}
	
}

MainClassUseAutowired.java를 실행해보면 아래와 같은 에러메세지가 뜬다. 해석해보면 3개의 객체를 찾았으나, 적합한(정확한) 주입 객체를 찾지 못했다는 뜻이다.

에러메세지

 

이 때 <qualifier> 태그를 통해 동일한 데이터타입 객체 중 자동 주입 대상 객체를 찾아낼 수 있다.

아래는 위 해결방법으로 수정한 코드들이다.

appCtxUseAutowired.xml

  • <qualifier> 태그를 주고 value값을 설정한다.
<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans 
 		http://www.springframework.org/schema/beans/spring-beans.xsd 
 		http://www.springframework.org/schema/context 
 		http://www.springframework.org/schema/context/spring-context.xsd">

	<context:annotation-config />

	<bean id="wordDao1" class="com.word.dao.WordDao" >
		<qualifier value="usedDao"/> <!-- qualifier 태그의 속성으로 value값 설정 -->
	</bean>
	<bean id="wordDao2" class="com.word.dao.WordDao" />
	<bean id="wordDao3" class="com.word.dao.WordDao" />
	
	<bean id="registerService" class="com.word.service.WordRegisterServiceUseAutowired" />
	
	<bean id="searchService" class="com.word.service.WordSearchServiceUseAutowired" />
	
</beans>

WordRegisterServiceUseAutowired.java

  • 프로퍼티에 @Qualifier("qualifier태그의 value") 어노테이션을 주면 동일한 데이터타입이 2개 이상 있더라도 어노테이션 괄호 안의 값과 <qualifier> 태그의 value값이 동일한 객체만을 찾아내어 주입할 수 있다. 
public class WordRegisterServiceUseAutowired {

	@Autowired
	@Qualifier("usedDao") // qualfier value="usedDao"인 객체를 찾아 자동주입한다.
	private WordDao wordDao;
	
	public WordRegisterServiceUseAutowired() {
		
	}
	
	public WordRegisterServiceUseAutowired(WordDao wordDao) {
		this.wordDao = wordDao;
	}
	
	public void register(WordSet wordSet) {
		String wordKey = wordSet.getWordKey();
		if(verify(wordKey)) {
			wordDao.insert(wordSet);
		} else {
			System.out.println("The word has already registered.");
		}
	}
	
	public boolean verify(String wordKey){
		WordSet wordSet = wordDao.select(wordKey);
		return wordSet == null ? true : false;
	}
	
	public void setWordDao(WordDao wordDao) {
		this.wordDao = wordDao;
	}
	
}

이렇게 수정을 마치고, MainClassUseAutowired.java를 실행해보면 Exception이 발생하지 않음을 알 수 있다. 

@inject

@Autowired와 거의 비슷하게 @inject 어노테이션을 이용해서 의존 객체를 자동으로 주입할 수 있다.

@Autowired와 차이점이라면 @Autowired의 경우 required 속성을 이용해서 의존 대상 객체가 없어도 익셉션을 피할 수 있지만, @inject의 경우 required 속성을 지원하지 않는다. 

하지만 required 속성을 이용하는 경우는 희박하므로 실질적으로 @Autowired와 유사하다고 볼 수 있고, 둘 중 @Autowired가 실무에서 더 많이 사용된다.

 

@inject를 사용할 때, 만약 스프링 컨테이너에 동일한 데이터타입을 가진 빈(Bean) 객체가 2개 이상 있다면 특정 객체를 선택하기 위해 @Named(value="bean의 id") 어노테이션을 사용하면 된다.

appCtxUseInject.xml

  •  동일한 데이터타입(WordDao) 객체 2개가 있으므로 이러한 객체를 @inject 어노테이션으로 주입할 때 에러가 발생할 것임을 예측할 수 있다.
<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans 
 		http://www.springframework.org/schema/beans/spring-beans.xsd 
 		http://www.springframework.org/schema/context 
 		http://www.springframework.org/schema/context/spring-context.xsd">

	<context:annotation-config /> <!-- 어노테이션 사용 -->

	<bean id="wordDao1" class="com.word.dao.WordDao" />
	<bean id="wordDao2" class="com.word.dao.WordDao" />
	
	<bean id="registerService" class="com.word.service.WordRegisterServiceUseInject" />
	
	<bean id="searchService" class="com.word.service.WordSearchServiceUseInject" />
	
</beans>

WordSearchServiceUseInject.java

@Named(value="bean의 id") 어노테이션을 줘서 특정 객체를 선택할 수 있게 한다.

public class WordSearchServiceUseInject {
	
	@Inject
	@Named(value="wordDao1")
	private WordDao wordDao;
	
	public WordSearchServiceUseInject() {
		
	}
	
	public WordSearchServiceUseInject(WordDao wordDao) {
		this.wordDao = wordDao;
	}
	
	public WordSet searchWord(String wordKey) {
		if(verify(wordKey)) {
			return wordDao.select(wordKey);
		} else {
			System.out.println("WordKey information is available.");
		}
		
		return null;
	}
	
	public boolean verify(String wordKey){
		WordSet wordSet = wordDao.select(wordKey);
		return wordSet != null ? true : false;
	}
	
	public void setWordDao(WordDao wordDao) {
		this.wordDao = wordDao;
	}
	
}

* @Resource 어노테이션과 @Inject 어노테이션에서 에러가 발생하여 구글링해보니 pom.xml의 <dependencies> 태그에 아래 코드들을 추가해서 해결되었다. 

	<dependency>
		<groupId>javax.annotation</groupId>
		<artifactId>javax.annotation-api</artifactId>
		<version>1.3.2</version>
	</dependency>
	<dependency>
   		<groupId>javax.inject</groupId>
  		<artifactId>javax.inject</artifactId>
            	<version>1</version>
	</dependency>

 

출처

https://mvnrepository.com/artifact/javax.inject/javax.inject/1

 

Maven Repository: javax.inject » javax.inject » 1

javax.inject javax.inject 1 // https://mvnrepository.com/artifact/javax.inject/javax.inject implementation group: 'javax.inject', name: 'javax.inject', version: '1' // https://mvnrepository.com/artifact/javax.inject/javax.inject implementation 'javax.injec

mvnrepository.com

https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-%ED%94%84%EB%A0%88%EC%9E%84%EC%9B%8C%ED%81%AC_renew 

 

자바 스프링 프레임워크(renew ver.) - 신입 프로그래머를 위한 강좌 - 인프런 | 강의

스프링 프레임워크 기본부터 실전 사용법까지! 충실하고 폭넓은 설명과 예제를 통해 현장에 바로 투입되어 활약하는 개발자로 거듭나세요., - 강의 소개 | 인프런...

www.inflearn.com

'Spring' 카테고리의 다른 글

어노테이션을 이용한 스프링 설정 - 1  (0) 2022.06.08
생명주기(Life Cycle)  (0) 2022.06.07
의존객체 자동 주입  (0) 2022.06.07
스프링 설정 파일 분리  (0) 2022.06.06
다양한 의존 객체 주입 방법  (0) 2022.06.06
Comments