04. DI
728x90

DI(Dependency Injection): 의존성 주입

클래스가 다른 클래스의 메서드를 사용하는 것

ex) MemberRegisterService 클래스가 selectByEmail() 메서드를 사용하기 위해 MemberDao 클래스에 의존

 

생성자 방식

public class MemberRegisterService {
	private MemberDao memberDao;
    
    // 캐시 적용 Dao
    // MemberDao를 상속받음
    // public class CachedMemberDao extends MemberDao {
    private MemberDao memberDao = new CachedMemberDao();
    
    // 생성자를 통해 의존 객체를 주입받음
    public MemberRegisterService(MemberDao memberDao) {
    	// 주입받은 객체를 필드에 할당
    	this.memberDao = memberDao;
    }
    
    public Long regist(RegisterRequest req) {
    	// 주입받은 의존 객체의 메서드를 사용
        Member member = memberDao.selectByEmail(req.getEmail());
        ...
        memberDao.insert(newMember);
        return newMember.getId();
    }
}

세터 메서드 방식

 - 의존 객체를 주입받는 코드를 세터 메서드로 작성

 - 의존을 주입하는 설정 코드를 import받는 클래스에 추가

 

범위 설명
singleton 스프링 컨테이너당 하나의 인스턴스 빈만 생성(default)
prototype 컨테이너에 빈을 요청할 때마다 새로운 인스턴스 생성
request HTTP Request별로 새로운 인스턴스 생성
session HTTP Session별로 새로운 인스턴스 생성
//Service

import org.springframework.stereotype.Component;

@Component("service")
@Scope("singleton")
public class ServiceImpl implements Service {
	
    @Override
    public int test(Dto dto) {
    	return 0;
    }
	
}

 

@Bean 설정

XML

 - XML문서 형태로 빈의 설정 메타 정보를 기술

 - 단순하며 사용하기 쉬움

 - <bean> 태그를 이용해 세밀한 제어 가능

 - 사용하지 않음

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

	<bean id="service" class="com.test.service" scope="prototype" init-method="init">
		<property name="dao" ref="dao"/>
	</bean>
    
    // 위와 아래의 코드가 같음
    
	<bean id="service" class="com.test.service" scope="prototype" init-method="init" p:dao-ref="d"/>

</beans>

Annotation

 - 애플리케이션의 규모가 커지고 빈의 개수가 많아질 경우 XML 파일을 관리하는 것이 번거로움

 - 빈으로 사용될 클래스에 특별한 annotation을 부여해 주면 자동으로 빈 등록 가능

 - "오브젝트 빈 스캐너"로 "빈 스캐닝"을 통해 자동 등록

 >> 빈 스캐너는 기본적으로 클래스 이름의 첫 글자만 소문자로 바꾼 것을 사용

 - 무조건 Annotation 사용

@Component
public class ServiceImpl implements Service {

    @Autowired
	private TestDao dao;
    
	@Override
    public int test(Dto dto) {
    	return dao.test(dto);
    }
}

 - 반드시 component-scan을 설정해야 한다

//application.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"
	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-4.3.xsd">

	<context:component-scan base-package="com.test.*"></context:component-scan>

</beans>

 

Stereotype annotation 종류

 - 빈 자동등록에 사용할 수 있는 annotation

 >> 계층별로 빈의 특성이나 종류를 구분

 >> AOP Pointcut 표현식을 사용하면 특정 annotation이 달린 클래스만 설정 가능

 >> 특정 계층의 빈에 부가기능을 부여

Stereotype 적용 대상
@Repository Data Access Layer의 DAO 또는 Repository 클래스에 사용
DataAccessException 자동변환과 같은 AOP의 적용 대상을 선정하기 위해 사용
@Service Service Layer의 클래스에 사용
@Controller Presentation Layer의 MVC Controller에 사용
스프링 웹 서블릿에 의해 웹 요청을 처리하는 컨트롤러 빈으로 설정
@Component 위의 Layer 구분을 적용하기 어려운 일반적인 경우에 설정

 

@Bean 의존 관계 설정

 - 멤버변수에 직정 정의하는 경우 setter method를 만들지 않아도 됨

annotation 설명
@Resource Spring 2.5부터 지원
멤버변수, setter method에 사용 가능
타입에 맞춰서 연결
@Autowired Spring 2.5부터 지원
Spring에서만 사용 가능
Required 속성을 통해 DI여부 조정
멤버변수, setter, constructor, 일반 method 사용 가능
타입에 맞춰서 연결
@Inject Spring 3.0부터 지원
Frameword에 종속적이지 않음
Javax.inject-x.x.x.jar 필요
멤버변수, sette, constructor, 일반 method 사용 가능
이름으로 연결

@Resource

 - 멤버 변수

 - setter method

//멤버 변수에 @Resource

@Component
public class ServiceImpl implements Service {

    @Resource(name="tdao") // 동일한 타입의 빈이 여러 개일 경우 name을 통하여 구분
	private TestDao dao;
    
	@Override
    public int test(Dto dto) {
    	return dao.test(dto);
    }
}

// setter method에 @Resource
@Component
public class ServiceImpl implements Service {

    private TestDao dao;
    
    @Resource(name="tdao")
    public void setDao(Dao dao) {
    	this.dao = dao;
    }
    
    @Override
    public int test(Dto dto) {
    	return dao.test(dto);
    }
}

@Autowired

 - 생성자

 - constructor

 - 일반 method

 - 스프링 자동 주입 기능
 - 해당 타입의 빈을 찾아서 필드에 할당

//생성자에 @Autowired

@Component
public class ServiceImpl implements Service {

	TestDao testDao;
    AdminDao adminDao;
    
    public ServiceImpl() {}
    
    @Autowired //생성자가 여러개일 경우에는 하나만 사용 가능
    //동일한 타입의 bean이 여러개일 경우에는 @Qualifier("name")으로 식별한다
    public ServiceImpl(@Qualifier("tdao") TestDao testDao,
    					@Qualifier("adao") AdminDao adminDao) {
    	super();
    	this.testDao = testDao;
    	this.adminDao = adminDao;
    }
    
    @Override
    public int test(TestDto testDto) {
    	return testDao.test(testDto);
    }
}

//constructor에 @Autowired
@Component
public class ServiceImpl implements Service {
	
    @Autowired
    @Qualifier("tdao")//동일 타입이 여러개일 경우
    TestDao testDao;
    
    @Autowired
    @Qualifier("adao")
    AdminDao adminDao;
    
    public ServiceImpl() {}

    @Override
    public int test(TestDto testDto) {
    	return testDao.test(testDto);
    }
}

//일반 method에 @Autowired

@Component
public class ServiceImpl implements Service {

	TestDao testDao;
    AdminDao adminDao;
    
    public ServiceImpl() {}
    
    @Autowired //생성자가 여러개일 경우에는 하나만 사용 가능
    //동일한 타입의 bean이 여러개일 경우에는 @Qualifier("name")으로 식별한다
    public void initService(@Qualifier("tdao") TestDao testDao,
    					@Qualifier("adao") AdminDao adminDao) {
    	this.testDao = testDao;
    	this.adminDao = adminDao;
    }
    
    @Override
    public int test(TestDto testDto) {
    	return testDao.test(testDto);
    }
}

 

@Autowired

 - 의존 자동 주입

 - 생성자 방식과 set 메서드 방식 둘 다 @Autowired를 붙일 수 있다

 - 설정 클래스에서 세터 메서드를 이용해 의존을 주입해도, 해당 세터 메서드에 @Autowired 애노테이션이 붙어 있으면 자동 주입을 통해 일치하는 빈을 주입한다

@Qualifier("printer")

 - 자동 주입 가능한 빈이 두 개 이상일 때 사용

 - 해당 빈의 한정 값으로 "printer"를 지정

 - 지정한 한정 갑은 @Autowired 애노테이션에서 자동 주입할 빈을 한정할 때 사용

@Nullable

 - 일치하는 빈이 존재하지 않을 때 null을 인자로 준다

 - 일치하는 빈이 존재하지 않을 때 값 할당 자체를 하지 않는 @Autowired(required = false)와 다름

728x90

'프로그래밍 > SPRING' 카테고리의 다른 글

06. AOP  (0) 2022.04.26
05. DI 적용  (0) 2022.04.24
03. Spring Framework  (0) 2022.04.23
02. IoC & Container  (0) 2022.04.17
01. Spring  (0) 2022.04.12