[Spring] 의존 객체 자동 주입_1

2023. 10. 7. 01:50학부 강의/웹프로그래밍 (Spring)


0. 출처

 

아직 배우고 있는 중이라 부정확한 정보가 포함되어 있을 수 있습니다!
주의하세요!

 

 

올인원 스프링 프레임워크 참고.

 

 

올인원 스프링 프레임워크 : 네이버 도서

네이버 도서 상세정보를 제공합니다.

search.shopping.naver.com

 


1. 스마트폰 연락처

 

전화번호를 저장, 출력하는 프로그램이다.

  • 연락처 3개를 샘플로 저장한다.
  • 전체 연락처를 출력한다.
  • 특정 인물의 연락처를 출력한다.

 


2. 클래스

 

 

해당 프로젝트의 클래스 다이어그램이다.

 

의존 관계를 확인할 수 있다.

 


가. ContactSet

package ch05_pjt_01.contact;

public class ContactSet {

    private String name;
    private String phoneNumber;

    public ContactSet(String name, String phoneNumber) {
        this.name = name;
        this.phoneNumber = phoneNumber;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getPhoneNumber() {
        return phoneNumber;
    }

    public void setPhoneNumber(String phoneNumber) {
        this.phoneNumber = phoneNumber;
    }
}

하나의 연락처는 이름과 전화번호를 저장한다.

 


나. ContactDao

package ch05_pjt_01.contact.dao;

import java.util.HashMap;
import java.util.Map;

import ch05_pjt_01.contact.ContactSet;

public class ContactDao {

    private Map<String, ContactSet> contactDB = new HashMap<String, ContactSet>();

    public void insert(ContactSet contactSet) {
        contactDB.put(contactSet.getName(), contactSet);
    }

    public ContactSet select(String name) {
        return contactDB.get(name);
    }

    public Map<String, ContactSet> getContactDB(){
        return contactDB;
    }
}
  • private Map<String, ContactSet> contactDB = new HashMap<String, ContactSet>();
    : 실습에선 실제 DB를 사용하진 않고 HashMap으로 구현했다.
  • insert() : 이름으로 ContactSet 추가.
  • select() : 이름으로 ContactSet 조회.
  • getContactDB() : contactDB 반환.

 


다. ContactRegisterService

package ch05_pjt_01.contact.service;

import ch05_pjt_01.contact.ContactSet;
import ch05_pjt_01.contact.dao.ContactDao;

public class ContactRegisterService {

    private ContactDao contactDao;

    public ContactRegisterService(ContactDao contactDao) {
        this.contactDao = contactDao;
    }

    public void register(ContactSet contactSet) {
        String name = contactSet.getName();
        if(verify(name)){
            contactDao.insert(contactSet);
        }else {
            System.out.println("The name has already regiseterd.");
        }
    }

    public boolean verify(String name){
        ContactSet contactSet = contactDao.select(name);
        return contactSet == null ? true : false;
    }

    public void SetWordDao(ContactDao contactDao) {
        this.contactDao = contactDao;
    }
}

ContactRegisterServicecontactDao를 필요로 함.

  • verify() : 같은 이름의 연락처가 중복인지 확인. 있으면 false, 없으면 true 반환.
  • register() : 새로운 연락처 생성. 같은 이름의 사람이 있으면 연락처 등록할 수 없음.

 


라. ContactSearchService

package ch05_pjt_01.contact.service;

import ch05_pjt_01.contact.ContactSet;
import ch05_pjt_01.contact.dao.ContactDao;

public class ContactSearchService {

    private ContactDao contactDao;

    public ContactSearchService(ContactDao contactDao) {
        this.contactDao = contactDao;
    }

    public ContactSet searchContact(String name) {
        if(verify(name)) {
            return contactDao.select(name);
        }else {
            System.out.println("Contact information is not available.");
        }

        return null;
    }

    public boolean verify(String name) {
        ContactSet contactSet = contactDao.select(name);
        return contactSet != null ? true : false;
    }

    public void setContactDao(ContactDao contactDao) {
        this.contactDao = contactDao;

}

ContactSearchrServicecontactDao를 필요로 함.

  • verify() : 찾는 이름의 연락처가 있는지 확인. 있으면 true, 없으면 false 반환.
  • SearchContact() : 이름으로 연락처 검색.

 


마. InitSampleData

package ch05_pjt_01.contact.utils;

public class InitSampleData {

    private String[] names;
    private String[] phoneNumbers;

    public String[] getNames() {
        return names;
    }
    public void setNames(String[] names) {
        this.names = names;
    }
    public String[] getPhoneNumbers() {
        return phoneNumbers;
    }
    public void setPhoneNumbers(String[] phoneNumbers) {
        this.phoneNumbers = phoneNumbers;
    }
}

샘플 데이터의 값은 appCtx.xml에서 주입.

 


3. appCtx.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="initSampleData" class="ch05_pjt_01.contact.utils.InitSampleData">
        <property name="names">
            <array>
                <value>류현진</value>
                <value>손흥민</value>
                <value>김연경</value>
            </array>
        </property>
        <property name="phoneNumbers">
            <array>
                <value>010-0000-1111</value>
                <value>010-0000-2222</value>
                <value>010-0000-3333</value>
            </array>
        </property>
    </bean>

    <bean id="contactDao" class="ch05_pjt_01.contact.dao.ContactDao" />
    <bean id="registerService" class="ch05_pjt_01.contact.service.ContactRegisterService">
        <constructor-arg ref="contactDao"/>
    </bean>
    <bean id="searchService" class="ch05_pjt_01.contact.service.ContactSearchService">
        <constructor-arg ref="contactDao"/>
    </bean>

</beans>

<constructor-arg ref="contactDao"/> 반복되어서 불편함.

 

이와 같이 매번 반복되는 <constructor-arg /><property>자동으로 입력하는 방법에 대하여 알아보자.

 


가. 의존 객체 자동 주입

 

Bean 중에서 registerServicesearchService는 생성자로 contactDao를 주입받는다.

 

반복되는 코드를 줄이기 위해서 스프링의 ‘의존 객체 자동 주입’ 기능을 활용한다.

 


1) context 네임스페이스와 스키마 추가

<?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.xsd">

...

 

2) <context:annotation-config/> 추가

<?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.xsd">

    <context:annotation-config/>

    ...

 

3) <constructor-arg> 제거

<bean id="contactDao" class="ch05_pjt_01.contact.dao.ContactDao" />
<bean id="registerService" class="ch05_pjt_01.contact.service.ContactRegisterService"/>
<bean id="searchService" class="ch05_pjt_01.contact.service.ContactSearchService"/>

 


4. MainClass

package ch05_pjt_01.contact;

import org.springframework.context.support.GenericXmlApplicationContext;

import ch05_pjt_01.contact.service.ContactRegisterService;
import ch05_pjt_01.contact.service.ContactSearchService;
import ch05_pjt_01.contact.utils.InitSampleData;

public class MainClass {

    public static void main(String[] args) {

        //IoC 컨테이너 생성
        GenericXmlApplicationContext ctx = new GenericXmlApplicationContext("classpath:appCtx.xml");

        //샘플 데이터
        InitSampleData initSampleData = ctx.getBean("initSampleData", InitSampleData.class);
        String[] names = initSampleData.getNames();
        String[] phoneNumbers = initSampleData.getPhoneNumbers();

        //데이터 등록
        ContactRegisterService registerService = ctx.getBean("registerService", ContactRegisterService.class);
        for(int i=0; i<names.length; i++) {
            ContactSet contactSet = new ContactSet(names[i], phoneNumbers[i]);
            registerService.register(contactSet);
        }

        //데이터 조회
        ContactSearchService searchService = ctx.getBean("searchService", ContactSearchService.class);

        ContactSet contactSet = searchService.searchContact("류현진");
        System.out.println("name: " + contactSet.getName());
        System.out.println("phone number: " + contactSet.getPhoneNumber());
        System.out.println("---------------------------------------------");

        contactSet = searchService.searchContact("손흥민");
        System.out.println("name: " + contactSet.getName());
        System.out.println("phone number: " + contactSet.getPhoneNumber());
        System.out.println("---------------------------------------------");

        contactSet = searchService.searchContact("김연경");
        System.out.println("name: " + contactSet.getName());
        System.out.println("phone number: " + contactSet.getPhoneNumber());
        System.out.println("---------------------------------------------");

        ctx.close();
    }
}
name: 류현진
phone number: 010-0000-1111
---------------------------------------------
name: 손흥민
phone number: 010-0000-2222
---------------------------------------------
name: 김연경
phone number: 010-0000-3333
---------------------------------------------