ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 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

    댓글

Designed by Tistory.