어노테이션 설정 추가시, <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>
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설정으로 사용
INFO : org.springframework.beans.factory.xml.XmlBeanDefinitionReader - Loading XML bean definitions from class path resource [applicationContext.xml] INFO : org.springframework.context.support.GenericXmlApplicationContext - Refreshing org.springframework.context.support.GenericXmlApplicationContext@290dbf45: startup date [Tue Jan 04 00:06:47 KST 2022]; root of context hierarchy ===> SonySpeaker 객체 생성 ===> SamsungTV(3) 객체생성 SamsungTv --전원 켠다. (가격: 2000000) SonySpeaker---소리 울린다. SonySpeaker---소리 내린다. SamsungTv --전원 끈다. INFO : org.springframework.context.support.GenericXmlApplicationContext - Closing org.springframework.context.support.GenericXmlApplicationContext@290dbf45: startup date [Tue Jan 04 00:06:47 KST 2022]; root of context hierarchy
객체 생성할때, 기본생성자가 아닌, 세번째 SaumsungTV(Speaker speakr, int price) 생성자가 사용됨.
bean등록 순서대로 객체를 처리하는데, 생성자 인젝션으로 의존성 주입될 SonySpeaker가 먼저 객체생성SonySpeaker 객체를 매개변수로 받아들이는 생성자를 호출하여 객체 생성
<constructor-arg>엘리먼트의 인자로 전달될 데이터가 <bean>인 다른 객체인경우 ref속성, 고정 문자열/정수인경우는 value
생성자 여러개 오버로딩 된 경우, index속성 통해 어떤값이 몇번째 매개변수로 매핑되는지 지정가능. 0부터시작
이클립스 자동 인터페이스 생성
생성할 인터페이스의 자식 열고 > alt + shift + T > Extract Interface> 생성할 인터페이스 이름/메소드 선택후 OK
* 체크박스 전체해제
src/main/resources/applicationContext.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"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id ="tv" class="polymorphsim.SamsungTV">
<constructor-arg index="0" ref="apple"></constructor-arg>
<constructor-arg index="1" value="2000000"></constructor-arg>
</bean>
<bean id = "sony" class="polymorphsim.SonySpeaker"></bean>
<bean id = "apple" class="polymorphsim.AppleSpeaker"></bean>
</beans>
자바코드 수정없이, <constructor-arg 의 ref를 "sony"대신 "apple"로 변경하여 AppleSpeaker호출가능
<추가 생성/수정한 파일>
(interface) Speaker.java
(class) SonySpeaker.java
(class) AppleSpeaker.java
(class)SamsungTV.java >> 매개변수/멤버변수를 SonySpeaker대신, Speaker로 변경
Setter Injection
- Setter메소드 호출해서 의존성 주입을 처리
- 대부분 생성자 주입 보다 setter 주입 사용
- Setter메소드는 스프링 컨테이너가 자동으로 호출, 호출시점은 <bean> 객체 생성 직후 Setter인젝션 동작하려면, Setter메소드 뿐만 아니라, 기본 생성자도 반드시 필요
INFO : org.springframework.beans.factory.xml.XmlBeanDefinitionReader - Loading XML bean definitions from class path resource [applicationContext.xml] INFO : org.springframework.context.support.GenericXmlApplicationContext - Refreshing org.springframework.context.support.GenericXmlApplicationContext@69a10787: startup date [Tue Jan 04 00:37:45 KST 2022]; root of context hierarchy ===> SamsungTV(1) 객체생성 ===> AppleSpeaker 객체 생성 ===> setSpeaker() 호출 ===> setPrice() 호출 ===> SonySpeaker 객체 생성 SamsungTv --전원 켠다. (가격: 2000000) AppleSpeaker-- 소리 올린다. AppleSpeaker-- 소리 내린다. SamsungTv --전원 끈다. INFO : org.springframework.context.support.GenericXmlApplicationContext - Closing org.springframework.context.support.GenericXmlApplicationContext@69a10787: startup date [Tue Jan 04 00:37:45 KST 2022]; root of context hierarchy