어노테이션

 

어노테이션 설정 추가시, <bean>에 Context관련 namespace와 schema 문서위치 등록필요

 - namespace에서 context 체크박스 체크

자동 주소 추가됨

 

 

컴포넌트 스캔(component-scan) 설정

 - 사용할 객체들 <bean>에 등록하지 않고, 자동으로 생성할때 필요

 - <context:component-scan.>엘리먼트 정의

 - 설정 추가시, 스프링 컨테이너가 classpath에 있는 클래스 스캔해서, @Component가 설정된 클래스들 자동객체 생성함

 

src/main/resources/applicationContext.xml 

<beans>
	<!-- 해당 경로 클래스 스캔해서, @Component설정된 클래스 자동 객체 생성 -->
	<context:component-scan base-package="polymorphsim"></context:component-scan>
    
    <bean id="tv" class="polymorphsim.LgTV"></bean>
    
 </beans>

 

 

@Component

- 위에 applicationContext에 컴포넌트 스캔 설정했으면, 설정파일에 클래스들을 일일이 <bean>엘리먼트로 등록안해도됨

 - 컴포넌트 어노테이션은 클래스 위에 선언 ("변수")

package polymorphsim;

import org.springframework.stereotype.Component;

@Component("tv")
public class LgTV implements TV{
	public LgTV() {
		System.out.println("===> LgTV 객체 생성");
	}
	public void powerOn() {
		System.out.println("LgTV --전원 켠다.");
	}
	public void powerOff() {
		System.out.println("LgTV --전원 끈다.");
	}
	public void volumeUp() {
		System.out.println("LgTV --소리 올린다.");
	}
	public void volumeDown() {
		System.out.println("LgTV --소리 내린다");
	}
}

 


의존성 주입 어노테이션

스프링에서 의존성 주입을 지원하는 어노테이션 

어노테이션 설명
@Autowired 변수위에 설정해서, 해당타입 객체 찾아서 자동할당
org.springframework.beans.factory.annotation.Autowired
@Qulifier 특정 객체 이름 이용, 의존성 주입시 사용
org.springframework.beans.factory.annotation.Qulifier
@Inject @Autowired와 동일기능 제공
javax.annotation.Resource
@Resource @Autowired + @Qualifier 기능 결합
javax.inject.Inject

 

 

@Autowired 

- 생성자, 메소드, 멤버변수 위에 모두 사용가능 (대부분은 멤버변수위에 선언)|
- 변수의 타입을 기준으로 객체를 검색하여 의존성 주입을 처리

- 스프링 컨테이너가 멤버변수 위에있는 어노테이션 확인하는 순간 변수타입 체크
  > 그 타입의 객체가 메모리 존재여부 확인 > 객체를 변수에 주입

- @Autowired가 붙은 객체가 메모리에 없으면, 컨테이너는 NoSuchBeanDefinitionException 발생시킴

  (=해당 어노테이션 대상 객체가 메모리에 존재하지 않음)

 ** 의존성 관계에 있는경우, 관련있는 객체가 메모리에 없는경우 에러가 발생함 (위 이미지처럼)

   관련있는 객체를 메모리에 생성하려면, applicationContext.xml에 아래 두가지 방법중 하나 

 

(1) <bean id="~" class="~"></bean> 의존관계 클래스를 bean을 명시하거나

(2) 의존관계 있는 클래스에 @Component("sony")처럼  어노테이션 설정해주기 
 > 단 <context:component-scan/>에 해당 패키지명이 명시되어있어야함

 

(예제는 컨테이너가 SonySpeaker객체를 speaker 변수에 자동 할당해준다고 )

 

 

@Qualifier

의존성 주입될 객체의 아이디나 이름을 지정할 수 있음.  

 

NoUniqueBeanDefinitionException ㅣ 의존성 주입대상 되는 Speaker타입 객체가 두개이상일때 문제  발생

SonySpeaker과, AppleSpeaker 객체가 모두 메모리에 생성되어있는 상태라면, 컨테이너는 어떤 객체를 할당할지 스스로 판별할수 없어서 에러발생 

 

 

이런경우, @Autowired되는 대상이 Speaker타입 객체가 AppleSpeaker, SonySpeaker 두개이고, 둘다 메모리에 생성된경우 발생함

해결하기 위해 @Qulifier어노테이션 사용, @AutoWired밑에 명시

 

src/main/java/polymorphsim/LgTV 

package polymorphsim;

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

@Component("tv")
public class LgTV implements TV{
	@Autowired
	@Qualifier("apple")
	private Speaker speaker;
	public LgTV() {
		System.out.println("===> LgTV 객체 생성");
	}
	public void powerOn() {
		System.out.println("LgTV --전원 켠다.");
	}
	public void powerOff() {
		System.out.println("LgTV --전원 끈다.");
	}
	public void volumeUp() {
		speaker.volumeUp();
		//System.out.println("LgTV --소리 올린다.");
	}
	public void volumeDown() {
		speaker.volumeDown();
		//System.out.println("LgTV --소리 내린다");
	}
}

 

실행결과

더보기

INFO : org.springframework.beans.factory.xml.XmlBeanDefinitionReader - Loading XML bean definitions from class path resource [applicationContext.xml]
INFO : org.springframework.beans.factory.support.DefaultListableBeanFactory - Overriding bean definition for bean 'tv' with a different definition: replacing [Generic bean: class [polymorphsim.LgTV]; scope=singleton; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; defined in file [C:\DEV\workspace_spring\BoardWeb\target\classes\polymorphsim\LgTV.class]] with [Generic bean: class [polymorphsim.LgTV]; scope=; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; defined in class path resource [applicationContext.xml]]
INFO : org.springframework.context.support.GenericXmlApplicationContext - Refreshing org.springframework.context.support.GenericXmlApplicationContext@69a10787: startup date [Wed Jan 05 00:52:33 KST 2022]; root of context hierarchy
INFO : org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor - JSR-330 'javax.inject.Inject' annotation found and supported for autowiring
===> AppleSpeaker 객체 생성
===> LgTV 객체 생성
===> SonySpeaker 객체 생성
LgTV --전원 켠다.
AppleSpeaker-- 소리 올린다.
AppleSpeaker-- 소리 내린다.
LgTV --전원 끈다.
INFO : org.springframework.context.support.GenericXmlApplicationContext - Closing org.springframework.context.support.GenericXmlApplicationContext@69a10787: startup date [Wed Jan 05 00:52:33 KST 2022]; root of context hierarchy

 

 

@Resource

- 객체의 이름을 이용하여 의존성 주입을 처리
 - name 속성을 사용, 스프링 컨테이너가 해당 이름으로 객체 검색해서 의존성 주입 처리

- Resource와 같은 기능의 어노테이션 @Inject 둘다 이름기반 의존성 주입

 

src/main/java/polymorphsim/LgTV 

package polymorphsim;

import org.springframework.stereotype.Component;
import javax.annotation.Resource;

@Component("tv")
public class LgTV implements TV{
	
	@Resource(name="apple")
	private Speaker speaker;
	
	public LgTV() {
		System.out.println("===> LgTV 객체 생성");
	}
	public void powerOn() {
		System.out.println("LgTV --전원 켠다.");
	}
	public void powerOff() {
		System.out.println("LgTV --전원 끈다.");
	}
	public void volumeUp() {
		speaker.volumeUp();
		//System.out.println("LgTV --소리 올린다.");
	}
	public void volumeDown() {
		speaker.volumeDown();
		//System.out.println("LgTV --소리 내린다");
	}
}

 >> apple 이름으로 메모리에 생성된 AppleSpeaker객체를 speaker변수에 할당

 

 

Spring 의존성 주입

  XML설정만 사용 Annotation 설정만 사용
장점 java소스 수정하지 않고, xml파일 설정만 변경. 유지보수 편리 - xml 설정에 대한 부담이 없음
- 의존관계에 대한 정보가 java소스에 있어서 사용하기 편리함
단점 - xml설정에 대한 부담감 있음. <bean>등록을 많이 해야함
- 의존관계 설정이 부담스러움
- java 소스에 의존관계와 메타데이터가 없어서, xml설정을 해석해야만 어떤 객체가 의존성 주입되는지 확인가능
- 의존성 주입할 객체의 이름이 자바소스에 명시되어야함.
- 소스 수정 없이 의존성 관계를 변경할 수 없음

** 결론 : 두개를 적절히 섞어서 쓰기

 변경되지 않는 객체는 어노테이션으로 설정하여 사용
 변경될 가능성이 있는 객체는 XML설정으로 사용

 

 

 

 

어노테이션 클래스 파일명 의미
@Service ~ServiceImpl  비즈니스 로직 처리 Service 클래스
@Repository ~DAO DB연동 처리 DAO 클래스
@Controller ~Controller 사용자 요청 제어 Controller 클래스

'IT > SPRING' 카테고리의 다른 글

[Spring Boot]  (0) 2023.06.02
[Spring] Interceptor  (0) 2023.06.02
[SPRING] 의존성 주입  (0) 2022.01.04
[SPRING] 스프링 컨테이너, applicationContext 설정파일  (0) 2022.01.03
[SPRING] 프레임워크 개요  (0) 2022.01.02

+ Recent posts