의존?

한 클래스가 다른 클래스의 메서드를 실행하는 것을 의존 이라고 한다. 의존은 변경에 의해 영향을 받는 관계를 의미한다.

아래는 의존 관계가 있는 객체를 직접 생성하고 실행하는 예제이다.

public class TestService {

    // 의존 객체를 직접 생성
    private TestDao testDao = new TestDao();

    public void test(){
        testDao.something(); // 의존 객체 실행
    }
}

DI(Dependency Injection, 의존 주입)

DI(의존 주입)은 의존 관계가 있는 의존 객체를 클래스 내에서 생성하지 않고 본인 객체가 생성 시에 이미 생성된 의존 객체를 전달해 주는 것을 뜻한다. 의존 주입을 사용하지 않고 직접 생성하는 방식에서, 의존 객체가 수정이 있고 이를 생성하기 위한 인터페이스가 변경된다면 해당 의존 객체를 직접 생성하는 모든 클래스에서 수정이 일어나야 한다. 객체 지향 설계를 고려한다면 의존 주입은 의존 객체 변경의 유연함을 보장하는 개발 방식이라고 할 수 있다.

아래는 의존 관계가 있는 객체에 수동으로 DI(의존 주입)을 진행하는 예제이다.

/**
* TestService.java
*/
public class TestService {
    private TestDao testDao;
    public TestService(TestDao testDao){
        this.testDao = testDao; // 의존 주입
    }
    public void test{
        testDao.something(); // 의존 객체 실행
    }
}
/**
* Main.java
*/
public class Main {
    public static void main(String[] args){
        TestDao testDao = new TestDao();
        TestService testService = new TestService(testDao);
        testService.test();
    }
}

Spring 의 DI 설정 앞서 설명한 DI 설정은 Spring 기능을 사용하지 않고 수동으로 DI 를 진행한 경우이다. Spring 은 각 객체를 싱글톤 형태의 Bean(빈)으로 관리하기에 각 Bean 을 생성 할 시에, 의존 주입을 진행해야 한다. Spring 에서 Bean 을 관리하는 방법은 여러가지이나 두 가지 예제로 알아보겠다.


Spring 의 DI 설정(XML)

<!-- 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"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    <bean id="testDao" class="hotsse.TestDao">
    </bean>
    <bean id="testService" class="hotsse.TestService">
        <constructor-arg ref="testDao">
    </bean>
</beans>
import org.psringframework.context.support.GenericXmlApplicationContext;
/**
* Main.java
*/
public class Main {
    public static void main(String[] args){
        GenericXmlApplicationContext ctx = 
            new GenericXmlApplicationContext("classpath:applicationContext.xml");
        TestService testService = ctx.getBean("testService", TestService.class);
        testService.test();
        ctx.close();
    }
}

Spring 의 DI 설정(Annotation) - 의존 자동 주입 XML 방식은 모든 객체 간의 의존 관계를 Context.xml 에 기재해야 해서, Java Code의 비즈니스 로직과 분리되어 있어 관리가 복잡해 질 수 있다. 어노테이션은 Java Code 내에 @예약어 형태로 기입하는 것으로 해당 클래스의 의존 관계를 바로 지정할 수 있는 기능을 제공한다 (어노테이션에 대한 자세한 정보는 따로 정리하도록 하겠다)

우선 어떠한 의존 주입도 하지 않은 채 Bean 만 생성해 놓는다고 가정하자.

<!-- 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"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="testDao" class="hotsse.TestDao">
    </bean>

    <bean id="testService" class="hotsse.TestService">
    </bean>
</beans>
  • @Autowired @Autowired 는 생성된 Bean 객체 중에서 타입을 기반으로 가장 적합한 Bean 객체를 선정하여 자동으로 주입해 주는 기능을 한다.
import org.springframework.beans.factory.annotation.Autowired;

public class TestService {

    @Autowired
    private TestDao testDao; // Bean 내에 있는 TestDao 형의 객체를 자동으로 주입

    public void test(){
        testDao.something();
    }
}