기존의 new와 같은 키워드를 통해 직접 의존하는 객체를 명시해서 생성 하는 방식은
시간이 지날수록 객체의 생성 시간은 느려지고 객체는 자신과 관련없는 로직까지도 알아야하는 부담이 증가한다.
이러한 클래스는 유지보수와 단위,통합 테스트가 어렵다는 단점이 있다.
위와같은 방식은 결합도가 높은 방식이며 결합도를 낮추기 위해 DI를 사용한다.
DI는 말 그대로 객체의 생성자에 의존 관계를 주입한다는 뜻이다.
방식으로는 생성자 기반 DI, setter기반 DI, annotation기반 DI가 있다.
1. Constructor Injection
- 생성자 기반 DI는 말 그대로 객체의 생성자에 의존 관계를 주입하는 방식이다.
1.User.java
package com.exam;
public class User {
private String name;
private int age;
User(String name, int age){
this.name=name;
this.age=age;
}
}
2.beans.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation=" http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="user" class="com.exam.User" >
<constructor-arg value="test" />
<constructor-arg value="20"/>
</bean>
</beans>
2. Setter Injection
- setter기반 DI는 의존관계 주입시 setter 메소드를 사용한다.
setter,getter method의 정의 규칙은
setUserName이라는 method가 있는 경우 userName이라는 property에 값을 넣는 동작을 한다.
property명은 set이나 get을 뺀뒤 첫번째 문자를 소문자로 변환해서 정의한다.
package com.exam;
public class User{
private String name;
public void setName(String name){
this.name = name;
}
public String getName(){
return name;
}
}
3. Annotation Injection
- 어노테이션 기반 DI를 사용하면 의존성 주입을 위해 생성자에 인자를 넣지 않아도 되고 setter 메소드를 사용하지 않아도 된다.
단지 의존 관계를 담을 필드를 클래스에 정의하고 이 필드에 annotation을 붙여 의존관계를 명시하기만 하면 된다.
Spring에서는 @Autowired, @Resource, @Inject annotation을 사용해 의존성을 주입한다.
위 annotation중 Autowired는 Spring에서 정의한것이고 나머지는 자바표준 annotation이다.
package com.exam.dao;
import org.apache.ibatis.session.SqlSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
@Repository
public class GuestDAOService implements GuestDAO {
@Autowired
private SqlSession sqlSession;
@Override
public void exam(String a) {
Mapper mapper = sqlSession.getMapper(mapper.class);
mapper.insertExam(a);
}
위와같이 Autowired를 사용해 의존성을 주입 할 수 있다.
메소드와 생성자에 @Autowired와 @Inject를 넣어 의존 관계를 지정할 수 있고, 메소드와 생성자의 인자 개수와는
상관없이 의존 관계 지정이 가능하다.
스프링은 인터페이스 기반 DI를 지원하지 않기 때문에 특정 인터페이스에 어떤 구현체를 주입할지 지정해야 한다.