<
의존성 주입
>
🌠다음 포스팅🌠

디자인 패턴 - 데코레이터 패턴
☄이전 포스팅☄

Gradle 과 Maven 차이

INDEX

목차
스프링 없이
생성자를 통한 의존성 주입
속성 통한 의존성 주입
스프링을 사용하여
XML 파일 사용 JAVA 코드에서 속성 주입
XML 파일 사용 XML 파일에서 속성 주입
Autowire 사용

스프링 없이

생성자를 통한 의존성 주입

자바를 기초로 만든 가장 기본적인 방식이 아닐까 생각한다.

Driver 클래스에서 Car객체를 생성하고 그 내부에서 필요한 객체를 생성하여 주입하는 방식인데

생각해본다면 코드의 유연성이 떨어지는 코드라고 생각한다. 즉, 필요에 따라 객체의 핵심을 손봐야하는 문제가 발생하는 것이다.

public class Car {
	Tire tire;

	public Car() {
		tire = new KoreaTire();
		// tire = new AmericaTire();
	}

	public String getTireBrand() {
		return "장착된 타이어: " + tire.getBrand();
	}
}

public class Driver {
    public static void main(String[] args) {
        Car car = new Car();

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

그렇다면 다음과 같이 리팩토링하면 어떨까?

public class Car {
	Tire tire;

	public Car(Tire tire) {
	    //TODO: 여기 바뀜
		This.tire = tire;
	}

	public String getTireBrand() {
		return "장착된 타이어: " + tire.getBrand();
	}
}

public class Driver {
    public static void main(String[] args) {
        Tiretire = new KoreaTire();
        //Tire tire = new AmericaTire();

        //TODO: 여기 바뀜
        Car car = new Car(tire);

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

생성자를 통해 의존성을 주입하는 것에 문제는 최초 객체를 생성하게 되면 타이어의 종류 즉, 생성자를 바꿀수 없는 것이 문제이다.

속성 통한 의존성 주입

OOP 프로그래머 답게 현실적으로 생각해 보자

최소 생성된 객체가 가지는 생성자를 바꿀수 없다면 그것이 현실적인 것일까? 우리는 타이어를 바꾸고 핸드폰을 바꾸는 것이 조금더 현실적이라고 생각한다.

여기서 등장한 개념이 속성(Property)을 통한 의존성 주입인것이다.

자바에서의 속성(Property)는 다음과 같다.

public class Person extends Object{ 
  String name; // 속성
  int age; // 1 
  
  void sleep(){ } // 메소드
}

기존 JAVA에서 속성 주입은 Set 메소드를 사용하여 이루어졌다.

public class Car {
	Tire tire;

	public Tire getTire() {
		return tire;
	}
    
	//TODO: Set 메소드 사용
	public void setTire(Tire tire) {
		this.tire = tire;
	}

	public String getTireBrand() {
		return "장착된 타이어: " + tire.getBrand();
	}
}

public class Driver {
    public static void main(String[] args) {
        Tire tire = new KoreaTire();
        
        //TODO: 여기를 보세요.
        Car car = new Car();
        car.setTire(tire);

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

스프링을 사용하여

스프링 의존성 주입 또한 생성자 / 속성 주입으로 나누어 지는데 실무에서 가장 많이 사용되는 속성 주입 방법만 설명한다.

XML파일은 스프링 프레임워크가 무엇인지 알수 있는 핵심이기도 하다.

그 말은 우리가 사용하고자 하는 객체를 스프링에 Bean으로 등록하여 개발자가 필요할때 사용한다는 말이며 Bean의 등록과 사용 그리고 관리가 스프링 프레임워크의 핵심이기도하기에 이해하고 넘어 가야만한다.

XML 파일 사용 JAVA 코드에서 속성 주입

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="tire" class="expert002.KoreaTire"></bean>

	<bean id="americaTire" class="expert002.AmericaTire"></bean>

	<bean id="car" class="expert002.Car"></bean>

</beans>
public class Car {
	Tire tire;

	public Tire getTire() {
		return tire;
	}

	public void setTire(Tire tire) {
		this.tire = tire;
	}

	public String getTireBrand() {
		return "장착된 타이어: " + tire.getBrand();
	}
}

public class Driver {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("XML파일위치 / **.xml");

        // Car car = (Car)context.getBean("car");
        Car car = context.getBean("car", Car.class);

        // Tire tire = (Tire)context.getBean("tire");
        Tire tire = context.getBean("tire", Tire.class);

        car.setTire(tire);

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

여기서 알아야 할 부분은 객체를 관리하는데 있어어 우리는 JAVA코드를 수정하지 않고 XML파일만 봐주면 된다는 것이다.

개인적으로 코드를 이해하는데 있어서 가독성과 직관성의 향상이 XML파일 사용에 큰 장점이라고 생각한다.

XML 파일 사용 XML 파일에서 속성 주입

속성 주입에 있어서 JAVA 코드를 수정하지 않고 사용할 수는 없을까?

물론 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="koreaTire" class="expert003.KoreaTire"></bean>

	<bean id="americaTire" class="expert003.AmericaTire"></bean>

	<bean id="car" class="expert003.Car">
		<property name="tire" ref="koreaTire"></property>
		<!--  
		<property name="tire" ref="americaTire"></property>
		-->
	</bean>
	
</beans>
public class Driver {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("XML파일위치 / **.xml");

        Car car = context.getBean("car", Car.class);

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

XML파일 내부에서 속성을 주입 해주었기 때문에 Driver클래스에서 Set메소드를 사용할 필요가 없어졌다.

Autowire 사용

기존의 속성 주입이라고 한다면 XML파일의 속성 주입순수 JAVA를 사용한 Set메소드 주입이 있었다.

그러면 정말 단순한 주입 방법은 없는 것일까?

Spring에서는 속성 주입을 위한 어노테이선 @Autowire을 제공하고 있다.

이 어노테이션은 별도의 설정자 메소드를 이용하지 않고도 스프링 프레임워크가 설정 파일을 통해 설정자 메소드 대신 속성을 주입해 준다.

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

	<context:annotation-config />

	<bean id="tire" class="expert004.KoreaTire"></bean>

	<bean id="wheel" class="expert004.AmericaTire"></bean>

	<bean id="car" class="expert004.Car"></bean>
</beans>
public class Car {
    // TODO: 속성 자동 주입
	@Autowired
	Tire tire;

	public String getTireBrand() {
		return "장착된 타이어: " + tire.getBrand();
	}
}

@AUtowire 어노테이션을 정의한다면 스프링 설정 파일을 보고 자동으로 속성의 설정자 메서드에 해당하는 역할을 해주겠다는 의미인것이다. 때문에 XML파일 자체에서 태그를 사용할 필요가 없었졌다.

Reference

Top
Foot