본문 바로가기
Spring

230131 Spring 의존객체 자동주입 @Autowired, @Qualifier

의존객체 자동 주입

스프링 설정 파일에서 의존객체를 주입할 때 <constructor-arg>또는 <property>태그로
의존 대상 객체를 명시하지 않아도 스프링 컨테이너가 자동으로 필요한 의존 대상 객체를 찾아서 의존 대상 객체가 필요한 객체에
주입해 주는 기능이다.

구현 방법은 @Autowired와 @Resource 어노테이션을 이용해서 쉽게 구현할 수 있다.
어노테이션은 자바 문서에서 사용한다.
어노테이션은 인터페이스다.


DI자동 주입 설정 방법

xmlns-속성값은 네임스페이스로 태그를 식별하기 이름
xmlns:xsi - XML정보를 가르키는 주소
xsi:schemaLocation -두개의 값이 공백으로 구분 됨
첫번째는 사용할 네임스페이스, 두번째는 참조할 네임스페이스 위치

xmlns="~~~/beans":beans를 기본 태그로 사용하겠다.
xmlns:context="~~/context":context라는 이름으로 사용하겠다.

 

  • @Autowired(required=false)  스프링에서 제공
    -타입을 기준으로 의존성을 주입(이름으로 찾는다)
    -같은 타입 빈이 두 개 이상 있을 경우 변수이름으로 빈을 찾음
    -Spring 어노테이션
  • @Resource  자바 자체에 있는 어노테이션, 자바 버전에 따라 있을수도, 없을수도
    -name을 속성을 이용하여 빈의 이름을 직접 지정(타입으로 찾는다)
    -JavaSE의 어노테이션(JDK9에는 포함되어 있지 않음)
  • @Injection
    -자바의 어노테이션, 오래되었다.
    -@Autowired 어노테이션을 사용하는 것과 같다.

spring bean configuration file을 만들고
콘솔창 위의 Namespaces를 누르면 여러 모듈들이 있다.(다운받은 것) 여기서 context를 체크하고 저장


@Autowired
반드시 있어야 하는 것

Spring Bean Configuration file에서

<context:annotation-config/>

 

+)만약, xmlns:context="~~context"가 xmlns:aaa="~~~context"면 <aaa:annotation-config/>로 사용한다.


bean만 만들어주면, 어노테이션을 통해 맞는 타입을 찾아 자동으로 주입해준다!
부합하는 타입이 없으면 bean의 이름으로 찾는다.

@Autowired는 생성자, setter, 멤버변수에 사용할 수 있다.
단, setter나 멤버변수에 넣으면 bean에서 오류가 난다. =>기본생성자가 있어야 한다!

 

  • @Resource
    JDK9버전이라 확인불가. 현재 11버전 사용 중.
  • @Injection도 마찬가지, 구버전 JDK에서 제공한다.



@Qualifier
-빈의 이름으로 의존성 주입
-강제 연결. 같은 타입 빈이 여러개가 있을 수 있다. 이때 Autowired를 사용하면 에러 발생. Qualifier를 사용하여 강제로 특정 빈을 집어넣으라고 강제 연결이 가능
-@Autowired와 같이 사용
-Spring 어노테이션
->단, Autowired는 우선 타입으로 찾고 다음으로 이름으로 찾기 때문에,
같은 타입 빈이 여러개고 정확하게 똑같은 이름이 없을 때(이 경우 Autowired에러는 found 여러개 로 발생) Qualifier를 사용
 
 
Qualifier는 Autowired와 같이 사용한다.
사용시 ctrl+space에서 Qualifier중 가장 위쪽의 것을 사용.
 
@Autowired
@Qualifier(value="doc1")
 이런 식으로 사용.
 
이걸 사용하면, 기본생성자, 생성자, getter setter가 없어도 bean을 주입할 수 있다.

 


Document.java

package ex05;

public class Document {
	public String data="내용...";
}

 

 

Printer.java

package ex05;

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

public class Printer {
	
	/*
	 * @Autowired-타입으로 빈을 주입->이름으로 찾아서 빈을 주입
	 * - 생성자, 세터, 멤버변수(세터 or 멤버변수는 반드시 기본생성자가 필요)
	 * 
	 * @Resource -이름으로 빈을 주입->타입으로 찾아서 빈을 주입
	 * 
	 * @Qualifier - 빈 이름의 강제 연결
	 * 컨테이너에 동일한 객체가 여러개 있을 떄 어느 객체를 주입할지
	 * 선택해주는 어노테이션
	 * 
	 */
	
	
	@Autowired
	@Qualifier(value="doc1")
	private Document doc;
	
	//기본생성자
	public Printer() {
		
	}
	//생성자
	public Printer(Document doc) {
		this.doc = doc;
	}

	//getter, setter
	public Document getDoc() {
		return doc;
	}

	public void setDoc(Document doc) {
		this.doc = doc;
	}
	
	
}

@Autowired는 setter나 멤버변수에 사용할 땐 기본생성자를 만들어줘야 한다.

 

 

autowired-context.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:context="http://www.springframework.org/schema/context"
	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-4.3.xsd">

	<!-- 자동주입 명령-context의 모듈의 특정 기능이 필요로 한다. -->
	<context:annotation-config/>
	
	
	<bean id="doc1" class="ex05.Document"/>
	<bean id="doc2" class="ex05.Document"/>
	
	<bean id="printer" class="ex05.Printer"/>
	
	
	
	
	
	
</beans>

Document클래스를 가져오는 bean이 두개, 따라서 Printer.java에서 @Qualifier(value="doc1")로 선택해줌. 

 

 

MainClass.java

package ex05;

import org.springframework.context.support.GenericXmlApplicationContext;

public class MainClass {
	public static void main(String[] args) {

		GenericXmlApplicationContext ctx=
				new GenericXmlApplicationContext("autowired-context.xml");


		Printer pt=ctx.getBean("printer",Printer.class);

		System.out.println(pt.getDoc().data);	




	}
}

 

콘솔출력창

1월 31, 2023 6:32:29 오후 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
INFO: Loading XML bean definitions from class path resource [autowired-context.xml]
1월 31, 2023 6:32:30 오후 org.springframework.context.support.AbstractApplicationContext prepareRefresh
INFO: Refreshing org.springframework.context.support.GenericXmlApplicationContext@402a079c: startup date [Tue Jan 31 18:32:30 KST 2023]; root of context hierarchy
내용...