ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 6. Annotation으로 의존성 주입하기
    Back-end Developer/Spring Framework, 설정 및 실습 2018. 12. 16. 14:47

    이제까지 Annotation도 활용해 봤고, DI도 해봤으니 이젠 DI를 annotation을 통해 실시해볼게요.



    실습


    시작하기전에 조금 기억을 더듬어 볼게요. animal.xml에서 bean 태그로 등록을 했었고, 어떤 값을 받아오는지 기록했습니다.

    일반 변수의 경우엔 property 태그를 생성자의 경우엔 contructor 태그를 이용했습니다.

    그리고 등록된 bean을 통해 PetOwner class에서 생성자를 통해 dog 또는 cat을 필드에 주입했었죠.

    결과적으로 그 값을 통해 결과를 출력 할 수 있었구요!!

    이제 여기에서 쓰였던 코드를 조금 바꿔볼게요~



    Context 항목 추가


    이 생성자를 받아오는 일을 annotation으로 처리해보려고 해요.

    우선 xml 과 PetOwner에서 생성자에 관련한 코드를 모두 지워주세요.


    animal.xml

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    <?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="dog" class="kr.ac.snut.spring.di.Dog">
            <property name = "dogName" value = "poodle"></property>
        </bean>
     
        <bean id="cat" class="kr.ac.snut.spring.di.Cat">
            <property name = "catName" value = "siam"></property>
        </bean>
     
        <bean id = "petOwner" class = "kr.ac.snut.spring.di.PetOwner">
        </bean>
        
    </beans>
     
    cs


    PetOwner.java

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    package kr.ac.snut.spring.di;
     
    public class PetOwner {
        
        private AnimalType animal;
        
        public void play() {
            animal.sound();
        }
    }
     
    cs


    그리고 animal.xml에서 namespace 탭을 선택하고, context를 체크해주세요.
    'OK'를 누르면 context 창이 활성화 됩니다.

    context 탭에 beans에서 마우스 오른쪽 버튼 누르고 annotation 항목을 선택해 주세요.


    여기까지 하고 xml 코드가 변경된 것을 확인해볼게요.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    <?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 http://www.springframework.org/schema/context/spring-context-4.2.xsd">
     
        <context:annotation-config></context:annotation-config>
        
        <bean id="dog" class="kr.ac.snut.spring.di.Dog">
            <property name = "dogName" value = "poodle"></property>
        </bean>
     
        <bean id="cat" class="kr.ac.snut.spring.di.Cat">
            <property name = "catName" value = "siam"></property>
        </bean>
     
        <bean id = "petOwner" class = "kr.ac.snut.spring.di.PetOwner">
        </bean>
        
    </beans>
     
    cs



    annotation 태그도 붙었고, 

    맨 위의 beans 태그 내부에 context와 schemeLocation에 context 관련 경로가 추가되었네요.



    Annotation 이용하기

    설정의 거의 끝난 것 같으니 PetOwner class로 가셔서, '@Autowired'를 추가해주세요.



    @Autowired?


    • 의존성 주입을 처리해주는 annotation
    • wiring by type, method, 생성자에도 사용이 가능함.
    Error가 발생하는 경우
    1. 해당 bean 객체가 존재하지 않는 경우
    2. 해당 bean 객체가 두개이상 존재하는 경우

    1의 경우엔 Autowired의 required 속성을 false로 지정해준다. @Autowired(required = false)
    2의 경우엔 Qualifier annotation을 추가해준다. @Qualifier(value = "해당 객체 값")


    자주 사용하고, 무의식적으로 많이 쓰게되는 annotation입니다. 더 자세한 내용을 찾아보시면 좋을 것 같아요. ^___^/

    그래서 이렇게 코드를 추가하고 실행하면? 될까요? 안되겠죠?

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    package kr.ac.snut.spring.di;
     
    import org.springframework.beans.factory.annotation.Autowired;
     
    public class PetOwner {
        
        @Autowired
        private AnimalType animal;
        
        public void play() {
            animal.sound();
        }
    }
     
    cs


    분명 에러가 발생할 것입니다. 왜일까요? 정답은 제가 위에 써둔 내용에 있습니다.

    보세요. 저기 AnimalType에 Autowired를 해두었는데,

    우리가 사용하는 AnimalType에 해당하는 bean은 두개죠? 바로 Cat, Dog 따라서 그대로 실행하면 에러가 발생합니다.

    1
    2
    3
    Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException
    No qualifying bean of type [kr.ac.snut.spring.di.AnimalType] is defined: 
    expected single matching bean but found 2: dog,cat
    cs


    맞죠? 단일 매칭이 필요한데 dog, cat 두개가 발견되었다 라고 쓰여있네요.

    Container 입장에선 어떤 bean을 주입해야할지 모르니 이렇게 에러가 발생했습니다.


    이제 위에 써둔것 처럼 Qualifier annotation을 통해 bean을 명시적으로 지시해줄게요.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    package kr.ac.snut.spring.di;
     
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.beans.factory.annotation.Qualifier;
     
    public class PetOwner {
        
        @Autowired
        @Qualifier(value = "qf_cat")
        private AnimalType animal;
        
        public void play() {
            animal.sound();
        }
    }
     
    cs


    이렇게 임의로 하나 적어주세요. 저는 Cat  bean을 이용하려고 이렇게 썼습니다.

    다들 현명하시니 알겠지만, 저렇게만 한다고 정상적으로 작동하진 않겠죠? 후후 저 value를 지정해 볼게요.


    animal.xml -> beans -> dog, cat 각각 오른쪽 마우스 클릭 -> beans 항목 -> Qualifier 선택


    그리고 오른쪽 창에 각 bean에 맞게 각각 value 값을 넣어주세요. (qf_dog, qf_cat)

    animal.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
    <?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 http://www.springframework.org/schema/context/spring-context-4.2.xsd">
     
        <context:annotation-config></context:annotation-config>
        
        <bean id="dog" class="kr.ac.snut.spring.di.Dog">
            <property name = "dogName" value = "poodle"></property>
            <qualifier value="qf_dog"></qualifier>
        </bean>
     
        <bean id="cat" class="kr.ac.snut.spring.di.Cat">
            <property name = "catName" value = "siam"></property>
            <qualifier value="qf_cat"></qualifier>
        </bean>
     
        <bean id = "petOwner" class = "kr.ac.snut.spring.di.PetOwner">
        </bean>
        
    </beans>
     
    cs



    결과 확인


     


    저번처럼 잘 실행이 되네요. ㅎㅎ

    이번 내용은 간단하니 5번과 같이 보시면서 한번에 해보는게 좋을거 같아요!!

    반응형

    댓글

Designed by minchoba.