본문 바로가기
Spring

2022-11-25 IoC(제어의 역전), DI(의존관계 주입) - annotation을 이용해 객체 생성하기 리뷰

by HTT 2022. 11. 26.

이제까지 힘겹게 힘들게 객체를 만들었다면 ... 이제 코드 단 몇 줄로 이 모든 걸 대체할 수 있게 됐다. 이것을 위한 빌드업이었을까..? 하지만 위험성이 좀 있어서 디폴트로 사용하지 못하는 게 좀 슬프다 ............

 

Spring관련 annotation

 

@Component

: 기본 빈으로 정의하고 등록할 때 사용. 어떤 id로 빈을 등록할지 설정할 수 있음. @Component("id")

빈의 이름을 등록하지 않으면 클래스명 첫 글자를 소문자로 바꾼 이름으로 등록됨

 

@Autowired

: 해당 타입의 빈이 있으면 자동으로 연결.

 

@Qualifier

: @Autowired를 하는 경우, 해당 타입의 빈이 두 개 이상 있을 때 정확하게 어떤 빈을 매칭할 것인지 @Qualifier이용해 명시. @Qualifier("빈의 이름")

 

 

이제 annotation이 있는 클래스를 찾아서 빈을 등록하는 코드를 써보자.

<?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.2.xsd">
	<!-- 스프링컨테이너가 생성되면 basic.annotation패키지의 모든 빈을 생성해서 내부메모리에 등록 
		@comtponent : 기본 빈으로 정의하고 등록할 때
		@Service : 서비스역할을 하는 빈을 등록
		@Repository : db연동을 위한 빈
		@Controller : 스프링 웹 MVC에서 사용하는 컨트롤러로 등록할 때
		-->
	<context:component-scan base-package="exam01"/>
	<context:component-scan base-package="annotation"/>
</beans>

=> 패키지의 이름이 exam01인 모든 클래스의 @comtponent를 읽어 빈으로 등록해주는 기능이다.

아래의 예시는 패키지 이름이 "annotation"으로 시작하는 모든 패키지가 해당하게 된다.

 

 

**정리

객체로 등록하고 싶은 클래스에 @Component를 적고 <context:component-scan>을 이용해 빈을 등록해준다. 필요 시 @Autowired, @Qualifier사용

 

 


 

사용 예시

 

메인메소드와 각각 상위 인터페이스를 구현하고 있는 클래스들이 있고, WriteArticleMgr클래스에서 IArticleDAO타입 객체를 생성한다.

package annotation.di.exam03;

public class TestMain {

	public static void main(String[] args) {
		ApplicationContext factory = new GenericXmlApplicationContext("/config/annotation.xml");
		ArticleDTO dto = new ArticleDTO("고양이", "귀엽다", "정말귀여워", "오늘");
		IWriteArticleMgr writemgr = (IWriteArticleMgr)factory.getBean("write");
		writemgr.write(dto);
	}

}

=> 메인메소드에서 IoC컨테이너를 생성해 원하는 객체를 불러온다(WriteArticleMgr의 조상인 IWriteArticleMgr타입의 참조변수를 가짐 - 형변환).

 

 

package annotation.di.exam03;

@Component("write")
public class WriteArticleMgr implements IWriteArticleMgr{
	@Autowired
	@Qualifier("oracle")
	IArticleDAO articleDAO;

	@Override
	public void write(ArticleDTO article) {
		articleDAO.insert(article);
	}
	
}

=> 빈으로 등록하기 위해 @Component("write") 해주기.

WriteArticleMgr클래스에서 또 다른 객체인 IArticleDAO타입 객체를 생성하고 있으므로 자동주입될 수 있도록 @Autowired를 써주고 인터페이스 IArticleDAO를 상속받는 자손타입의 객체가 2개 이상이므로 @Qualifier를 써서 어떤 객체를 생성할지 지정해준다.

 

 

@Component("mysql")
public class MysqlIArticleDAO implements IArticleDAO
@Component("oracle")
public class OracleIArticleDAO implements IArticleDAO

=> 두 클래스의 객체를 생성해야 하므로 @Component를 사용해 빈을 등록해준다.

 

 

- 결과화면

세번 굴린 주사위의 합:15

댓글