-
SpringFramework Annotation 을 이용한 의존성 주입(DI)Spring Boot&Framework 2020. 1. 21. 23:03
저번 게시글에서는 Construct Injection , Set Injection 으로
의존성을 주입시키는 방법을 알아봤다.
이제 더 편하고 새로운 방식인 Annotation 을 이용해보자.
Annotation 이란 자바 소스코드 안에 추가하여 사용할 수 있는
메타데이터의 일종인데, 자세한 내용은
https://elfinlas.github.io/2017/12/14/java-annotation/ 를 참고하자.
저번 예제를 이용하여 Annotation 을 사용해보자.
먼저 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: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 https://www.springframework.org/schema/context/spring-context.xsd"> <context:component-scan base-package="com.yopy.annotation"/> </beans>
<context:component-scan base-package="com.yopy.annotation"/>
라인이 xml 에 추가되었는데 , base-package 는 com.yopy.annotation 패키지로
시작하는 모든 패키지를 스캔하여 BeanPostProcessor , Autowired 등
기능을 수행할 수 있게 설정한 것이다.
package com.yopy.annotation; import org.springframework.stereotype.Component; @Component("tv") //<bean id ="tv" class="com.yopy.annotation.LgTv"></bean> 와 같은 의미이다. public class LgTv implements TV { public LgTv() { System.out.println("LG TV Constructor Created"); } public void powerOn() { System.out.println("LG TV PowerON"); } public void powerOff() { System.out.println("LG TV PowerOff"); } public void volumeUp() { System.out.println("LG TV VolumeUp"); } public void volumeDown() { System.out.println("LG TV VolumeDown"); } }
전 게시글에선 xml 에 가서 직접 빈을 설정하고 클래스를 매핑하였지만 이제는
그 과정이 @Component 한줄로 끝난것이다.
package com.yopy.annotation; public interface TV { void powerOn(); void powerOff(); void volumeUp(); void volumeDown(); }
TV 클래스는 전 게시글과 같다.
package com.yopy.annotation; import org.springframework.context.ApplicationContext; import org.springframework.context.support.GenericXmlApplicationContext; public class TVUser { public static void main(String[] args) { ApplicationContext factory = new GenericXmlApplicationContext("spring/rootContext.xml"); TV tv = (TV)factory.getBean("tv"); tv.powerOn(); tv.volumeUp(); tv.volumeDown(); tv.powerOff(); } }
실행하여 결과를 확인해보자.
그리고 이제 스피커를 소니 스피커로 바꿔보자.
package com.yopy.annotation; public interface Speaker { void volumeDown(); void volumeUp(); }
스피커 공통 속성이 담긴 인터페이스를 생성하자.
package com.yopy.annotation; import org.springframework.stereotype.Component; @Component("sony") public class SonySpeaker implements Speaker { public SonySpeaker() { System.out.println("SonySpeaker Constructor Created"); } public void volumeDown() { System.out.println("SonySpeaker Volume Down"); } public void volumeUp() { System.out.println("SonySpeaker Volume Up"); } }
여기서도 역시 sony 라는 이름으로 컴포넌트 어노테이션이 사용되었다.
빈에 자동으로 등록된다.
package com.yopy.annotation; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Component; @Component("tv") //<bean id ="tv" class="com.yopy.annotation.LgTv"></bean> 와 같은 의미이다. public class LgTv implements TV { @Autowired private Speaker speaker; public LgTv(Speaker speaker) { System.out.println("LG TV 객체 생성"); this.speaker = speaker; } public LgTv() { System.out.println("LG TV Constructor Created"); } public void powerOn() { System.out.println("LG TV PowerON"); } public void powerOff() { System.out.println("LG TV PowerOff"); } public void volumeUp() { speaker.volumeUp(); } public void volumeDown() { speaker.volumeDown(); } }
여기서 멤버변수 위에 @Autowired 가 사용되었는데,
이것은 자동으로 Speaker 타입의 객체를 연결시켜준다.
TVUser 클래스는 수정하지 않아도 된다.
내용을 실행해보면 스피커가 소니스피커로 바뀐 모습을 볼 수 있다.
그런데 이번에는 소니 스피커에서 애플 스피커로 바꾸고싶다.
기존에 소니 스피커를 버릴순 없으니 유지시키고 어노테이션을 이용하여
애플 스피커로 교체해보자.
package com.yopy.annotation; import org.springframework.stereotype.Component; @Component("apple") public class AppleSpeaker implements Speaker { public AppleSpeaker() { System.out.println("Apple Speaker Constructor Created"); } public void volumeDown() { System.out.println("Apple Speaker Volume Down"); } public void volumeUp() { System.out.println("Apple Speaker Volume Up"); } }
AppleSpeaker 클래스를 만들고 컴포넌트를 생성했다.
그런데 사실 @Autowired 는 사용자가 소니스피커를
원하는지 애플 스피커를 원하는지 알 수 없다.
그래서 우리는 @Qualifier 을 사용하여 티비에서 애플스피커를
쓰라고 알려줄 것이다.
package com.yopy.annotation; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Component; @Component("tv") //<bean id ="tv" class="com.yopy.annotation.LgTv"></bean> 와 같은 의미이다. public class LgTv implements TV { @Autowired @Qualifier("apple") private Speaker speaker; public LgTv(Speaker speaker) { System.out.println("LG TV 객체 생성"); this.speaker = speaker; } public LgTv() { System.out.println("LG TV Constructor Created"); } public void powerOn() { System.out.println("LG TV PowerON"); } public void powerOff() { System.out.println("LG TV PowerOff"); } public void volumeUp() { speaker.volumeUp(); } public void volumeDown() { speaker.volumeDown(); } }
@Qualifier 에 방금 만든 애플 컴포넌트 이름이 들어갔다.
이렇게 되면 정상적으로 애플 스피커로 인식하여 작동하게 된다.
'Spring Boot&Framework' 카테고리의 다른 글
Spring Framework DI (Dependency Injection) (1) 2020.01.19