리셋 되지 말자

스프링을 통한 의존성 주입-스프링 설정 파일(XML)에서 속성 주입 본문

Java(폐지)/spring 책

스프링을 통한 의존성 주입-스프링 설정 파일(XML)에서 속성 주입

kyeongjun-dev 2020. 8. 12. 12:37

의사 코드 - 점점 현실 세계 반영

운전자가 종합 쇼핑몰에서 자동차 구매를 요청한다.
종합 쇼핑몰은 자동차를 생산한다.
종합 쇼핑몰은 타이어를 생산한다.
종합 쇼핑몰은 자동차에 타이어를 장착한다.
종합 쇼핑몰은 운전자에게 자동차를 전달한다.

자바로 표현

ApplicationContext context = new ClassPathXmlApplicationContext("expert003/expert003.xml");
Car car = context.getBean("car", Car.class);

XML로 표현

<bean id="koreaTire" class="expert003.KoreaTire"></bean>
<bean id ="americaTire" class="expert003.AmericaTire"></bean>
<bean id="car" class="expert003.Car">
    <property name="tire" ref="koreaTire"></property>
</bean>

property라는 새로운 태그를 확인할 수 있다.
자바에서 접근자 및 설정자 메서드를 속성 메서드라고 하는데 영어로 속성은 Property다.
Driver.java에서 car.setTire(tire)라고 하던 부분을 XML 파일의 property 태그를 이용해 대체하는 것이다.

시퀀스 다이어그램 (클래스 다이어그램은 이전과 동일)

소스 코드(Tire.java KoreaTire.java AmericaTire.java Car.java는 바뀌는 부분 없음)

  • Driver.java
package expert003;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Driver {
    public static void main(String[] args) {
        //바뀌지 않은 소스코드
        ApplicationContext context = new ClassPathXmlApplicationContext("expert002/expert002.xml");
        Car car = context.getBean("car", Car.class);
        Tire tire = context.getBean("tire", Tire.class);

        car.setTire(tire);

        System.out.println(car.getTireBrand());

        //바뀐 소스코드
        ApplicationContext context = new ClassPathXmlApplicationContext("expert003/expert003.xml");
        Car car = context.getBean("car", Car.class);
        System.out.println(car.getTireBrand());
    }
}

Tire tire = context.getBean("tire", Tire.class);
car.setTire(tire);
가 사라진 것을 확인할 수 있다.

  • 실행 결과
INFO : org.springframework.context.support.ClassPathXmlApplicationContext - Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@ea30797: startup date [Wed Aug 12 11:09:00 KST 2020]; root of context hierarchy
INFO : org.springframework.beans.factory.xml.XmlBeanDefinitionReader - Loading XML bean definitions from class path resource [expert003/expert003.xml]
INFO : org.springframework.beans.factory.support.DefaultListableBeanFactory - Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@5cc7c2a6: defining beans [koreaTire,americaTire,car]; root of factory hierarchy
장착된 타이어: 코리아 타이어

의존성 주입

1. Car를 구매하는 부분

2. 타이어를 구매하는 부분 - 자바 코드에서 사라짐

3. id="koreaTire"와 ref="koreaTire"를 잇는 코리아 타이어를 자동차의 타이어 속성에 결합하는 부분

4. car의 tire 속성을 설정하는 부분 - 자바 코드에서 사라짐

property 태그의 ref 속성을 americaTire로 변경한 결과

  • 실행 결과
INFO : org.springframework.context.support.ClassPathXmlApplicationContext - Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@ea30797: startup date [Wed Aug 12 11:31:42 KST 2020]; root of context hierarchy
INFO : org.springframework.beans.factory.xml.XmlBeanDefinitionReader - Loading XML bean definitions from class path resource [expert003/expert003.xml]
INFO : org.springframework.beans.factory.support.DefaultListableBeanFactory - Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@5cc7c2a6: defining beans [koreaTire,americaTire,car]; root of factory hierarchy
장착된 타이어: 아메리카 타이어

JUnit 테스트 케이스 - 책에서는 JUnit4인데 저의 버전은 JUnit 5라서 소스코드가 많이 다름

http://wonwoo.ml/index.php/post/1886 좋은 포스팅 감사합니다.

  • dependency 추가
<dependencies>
  <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>5.0.0.RELEASE</version>
  </dependency>
  <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-test</artifactId>
    <version>5.0.0.RELEASE</version>
    <scope>test</scope>
  </dependency>
  <dependency>
    <groupId>org.junit.jupiter</groupId>
    <artifactId>junit-jupiter-engine</artifactId>
    <version>5.0.1</version>
    <scope>test</scope>
  </dependency>
</dependencies>
  • CarTest.java
package expert003;

import static org.junit.jupiter.api.Assertions.*;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit.jupiter.SpringExtension;

@ExtendWith(SpringExtension.class)
@ContextConfiguration("expert003.xml")
class CarTest {
    @Autowired
    Car car;

    @Test
    void test() {
        assertEquals("장착된 타이어: 아메리카 타이어", car.getTireBrand());
    }

}
  • JUnit test 결과

INFO : org.springframework.test.context.support.DefaultTestContextBootstrapper - Loaded default TestExecutionListener class names from location [META-INF/spring.factories]: [org.springframework.test.context.web.ServletTestExecutionListener, org.springframework.test.context.support.DirtiesContextBeforeModesTestExecutionListener, org.springframework.test.context.support.DependencyInjectionTestExecutionListener, org.springframework.test.context.support.DirtiesContextTestExecutionListener, org.springframework.test.context.transaction.TransactionalTestExecutionListener, org.springframework.test.context.jdbc.SqlScriptsTestExecutionListener]
INFO : org.springframework.test.context.support.DefaultTestContextBootstrapper - Could not instantiate TestExecutionListener [org.springframework.test.context.transaction.TransactionalTestExecutionListener]. Specify custom listener classes or make the default listener classes (and their required dependencies) available. Offending class: [org/springframework/transaction/interceptor/TransactionAttributeSource]
INFO : org.springframework.test.context.support.DefaultTestContextBootstrapper - Could not instantiate TestExecutionListener [org.springframework.test.context.jdbc.SqlScriptsTestExecutionListener]. Specify custom listener classes or make the default listener classes (and their required dependencies) available. Offending class: [org/springframework/transaction/interceptor/TransactionAttribute]
INFO : org.springframework.test.context.support.DefaultTestContextBootstrapper - Using TestExecutionListeners: [org.springframework.test.context.web.ServletTestExecutionListener@4f638935, org.springframework.test.context.support.DirtiesContextBeforeModesTestExecutionListener@4387b79e, org.springframework.test.context.support.DependencyInjectionTestExecutionListener@6e75aa0d, org.springframework.test.context.support.DirtiesContextTestExecutionListener@7fc229ab]
INFO : org.springframework.beans.factory.xml.XmlBeanDefinitionReader - Loading XML bean definitions from class path resource [expert003/expert003.xml]
INFO : org.springframework.context.support.GenericApplicationContext - Refreshing org.springframework.context.support.GenericApplicationContext@2ddc8ecb: startup date [Wed Aug 12 12:30:14 KST 2020]; root of context hierarchy
INFO : org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor - JSR-330 'javax.inject.Inject' annotation found and supported for autowiring
INFO : org.springframework.context.support.GenericApplicationContext - Closing org.springframework.context.support.GenericApplicationContext@2ddc8ecb: startup date [Wed Aug 12 12:30:14 KST 2020]; root of context hierarchy
Comments