day1 class05 어노테이션 기반 설정
1. context 네임스페이스 추가
p 네임스페이스 추가와 마찬가지로 [namespaces] > context 항목 체크하면 다음과 같이 소스가 추가된다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | <!-- 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" xmlns:p="http://www.springframework.org/schema/p" 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.2.xsd"> <context:component-scan base-package="polymorphism"></context:component-scan> <bean class="polymorphism.SonySpeaker"></bean> <!-- <bean id="tv" class="polymorphism.LgTV"></bean> --> </beans> | cs |
2. 컴포넌트 스캔(component-scan) 설정
- <context:component-scan> 엘리먼트를 정의하면 애플리케이션에서 사용할 객체들을 <bean>등록을 하지 않고 자동으로 생성할 수 있다.
- base-package속성값은 해당 경로의 패키지로 시작하는 모든 클래스들이 스캔 대상이 된다.
3. @Component
- 해당 클래스에 기본 생성자가 있어야만 한다.
- 3.1과 3.2의 방법 중 하나를 사용하면 constructor injection이나 setter injection을 이용하지 않아도 된다.
- id나 name 속성 미지정 시 컨테이너가 자동으로 해당 클래스의 첫 글자를 소문자로 변경하여 설정해준다.
3.1 XML 설정
1 | <bean id="tv" class="polymorphism.LgTV"></bean> | cs |
3.2 Annotation 설정
1 2 | @Component("tv") public class LgTV implements TV { | cs |
4. 의존성 주입 어노테이션
4.1 @Autowired
- 주로 변수 위에 설정하여 해당 타입의 객체를 찾아서 자동으로 할당한다.
- 해당 어노테이션을 확인하는 순간 해당 변수의 타입을 체크하고 객체가 메모리에 존재하는지 학인한 후, 그 객체를 변수에 주입한다.
- 객체가 메모리에 없다면 NoSuchBeanDefinitionException을 발생시킨다.
- 4.1.1이나 4.1.2 둘 중 하나의 방법을 선택하여 사용하면 된다.
- SonySpeaker와 AppleSpeaker로 Speaker의 객체가 두개 이상이면 NoUniqueBeanDefinitionException~~~but found 2: apple, sony를 발생시킨다.
4.1.1 XML 설정
4.1.2 Annotation 설정
1 2 3 4 | import org.springframework.stereotype.Component; @Component("sony") public class SonySpeaker implements Speaker { | cs |
4.2 @Qualifier
- 특정 객체의 이름을 이용하여 의존성 주입할 때 사용한다.
- 4.1의 문제 해결을 위해 사용한다.
- 해당 어노테이션으로 Speaker 객체를 지정하여 문제를 해결 할 수 있다.
1 2 3 4 5 6 7 8 9 10 | 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; | cs |
4.3 @Resource
- @Autowired와 @Qualifier의 기능을 결합한 어노테이션이다.
1 2 3 4 5 6 7 8 9 | import javax.annotation.Resource; import org.springframework.stereotype.Component; @Component("tv") public class LgTV implements TV { @Resource(name="apple") private Speaker speaker; | cs |
5. 어노테이션과 XML 설정 병행하여 사용하기
- XML방식은 자바 소스를 수정하지 않고 XML파일의 설정만 변경하여 Speaker을 교체할 수 있다. 유지 보수가 편하지만 XML 설정에 대한 부담이 있고 자바 소스에 의존관계와 관련된 어떤 메타데이터도 없으므로 XML 설정을 해석해야만 무슨 객체가 의존성 주입되는지를 확인할 수 있다.
- 어노테이션 기반 설정은 XML 설정에 부담이 없고 의존관계에 대한 정보가 자바 소스에 드렁있어서 사용하기는 편하지만 의존성 주입할 객체의 이름이 자바 소스에 명시되어야 하므로 소스를 수정해야 한다.
- 위의 두 방법의 장점을 조합하여 사용한다.
- 클라이언트가 요청할 LgTV는 @Component 어노테이션으로 처리하고, 의존성 주입은 @Autowired로 처리한다. 다만, 변경될 Speaker만 스프링 설정 파일에 <bean> 등록함으로써 자바 코드 수정 없이 XML 수정만으로 Speaker를 교체할 수 있다.
- 변경되지 않는 객체는 어노테이션으로 설정하여 사용하고, 변결될 가능성이 있는 객체는 XML 설정으로 사용한다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | package polymorphism; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @Component("tv") public class LgTV implements TV { @Autowired private Speaker speaker; public LgTV() { System.out.println("===> LgTV 객체 생성"); } public void powerOn() { System.out.println("LgTV---powerOn"); } public void powerOff() { System.out.println("LgTV---powerOff"); } public void volumeUp() { speaker.volumeUp(); } public void volumeDown() { speaker.volumeDown(); } } | cs |
- 객체가 자동으로 생성되는것을 차단한다.
1 2 3 4 5 | //@Component("sony") ==> 제거 public class SonySpeaker implements Speaker { //@Component("apple") ==> 제거 public class AppleSpeaker implements Speaker { | cs |
1 2 3 4 5 6 7 8 9 10 11 12 | <?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:p="http://www.springframework.org/schema/p" 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.2.xsd"> <context:component-scan base-package="polymorphism"></context:component-scan> <bean class="polymorphism.SonySpeaker"></bean> <!-- <bean class="polymorphism.AppleSpeaker"></bean> --> </beans> | cs |