5.1 어노테이션 설정 기초
"1-4까지는 .xml 파일에 <bean></bean> 또는 <ref></ref> 엘리먼트를 통해서 객체 생성 및 의존성 주입을 했다. 1-5부터는 .xml 파일이 아닌 클래스에 '@:어노테이션'을 직접 설정하여, 객체 생성 및 의존성 주입을 할 것이다."
5.1.1 컴포넌트 스캔(component-scan) 설정
: .xml 파일에 컴포넌트 스캔을 지정하면, 스프링 컨테이너는 해당 스캔 경로 내의 @Component가 지정된 클래스들의 객체를 자동으로 생성한다."
".xml 파일에 컴포넌트 스캔을 지정하면서, 그간 설정했던 <bean></bean> 라인은 삭제해야한다.
또한, <context:component-scan>의 base-package이 지정한 모든 패키지들이 스캔 대상에 해당 된다... 여기서 스캔 대상이라 함은 해당 대상 내의 모든 클래스들이 Component를 통해서 자동 객체 생성이 되는것을 의미한다. 아래 예시를 보자"
#첨부자료 1 : component-scan base-package 통해서 패키지들을 스캔하고 있다.
<?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"
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
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd">
<!-- 스프링 컨테이너 / IOC는 결국 클래스로부터 객체를 자동으로 생성하는 것이다. -->
<!-- <bean id="tv" class="polymorhism_inter.Samsung" init-method="initMethod"/>-->
<!-- <bean id="tv" class="polymorhism_inter.Samsung" destroy-method="destoyMethod"/> -->
<!-- <bean id="tv" class="polymorhism_inter.Samsung" scope="singleton"/>-->
<!-- <bean id="tv" class="polymorhism_inter.Samsung" scope="prototype"/>-->
<!-- <bean id="tv" class="polymorhism_inter.Samsung"/> -->
<context:component-scan base-package="com"></context:component-scan>
<context:component-scan base-package="polymorhism_inter"></context:component-scan>
<context:component-scan base-package="polymorphism"></context:component-scan>
<context:component-scan base-package="polymorphism_dependency"></context:component-scan>
</beans>
# 첨부자료 2 : 아래 빨간 사각형 안에 있는 패키지들이 위의 .xml의 스캔 범위이다.
즉, 해당 스캔 범위 내의 Component 어노테이션 클래스들은 모두 스프링 컨테이너가 객체를 자동으로 생성해준다.
5.1.2 @Component
".xml에 스캔 범위 지정이 끝났다면, 자동 객체 생성을 원하는 클래스에 @Component 들을 지정해보자..
사실 클래스 위에 @Component를 지정해야, 스프링 설정 파일이 객체를 생성해준다...ㅠ"
# 첨부자료 3 : XML 설정과 ~ @Annotation의 비교( * 물론 결과는 동일하다)
<!-- XML 설정 -->
<bean id="tv" class="polymorphism.LGTV"></bean>
<!-- Annotation 설정 -->
package polymorhism_inter;
import org.springframework.stereotype.Component;
/* TV는 LG로 형변환 가능, 자료형은 TV가 되지만 참조는 LG객체를 참조한다.
* alt + shift + s 통해서, 구체 메소드 구현 가능
* */
@Component("tv")
public class LG implements TV {
@Override
public void powerOn() {
System.out.println("엘지 --- 전원킨다.");
}
@Override
public void powerOff() {
System.out.println("엘지 --- 전원끈다.");
}
@Override
public void volumeUp() {
System.out.println("엘지 --- 소리 올리다.");
}
@Override
public void volumeDown() {
System.out.println("엘지 --- 소리 내린다.");
}
}
5.2 의존성 주입 설정
5.2.1 의존성 주입 어노테이션
" 5.1.1에 스프링 컨테이너의 중요한 기능중 하나인 객체의 생성에 대해서 알아보았다. 이제는 의존성 주입을 어노테이션을 통해서 진행해보자, 스프링 컨테이너가 파악할 수 있는 의존성 관련 어노테이션은 아래 4개이다. "
- @Autowired : 주로 변수 위에 설정하여 해당 타입 객체를 찾아서 자동으로 할당
- @Qualifier : 특정 객체의 이름을 이용하여 의존성 주입할 때 사용한다.
- @inject : @Autowired와 동일한 기능을 제공
- @Resource : @Autowired + @Qualifier의 기능을 결합안 어노테이션
5.2.2 @Autowired
"보통 의존성 주입 어노테이션은 멤버변수 위에 사용한다. 스프링 컨테이너는 변수위에 @Autowired 어노테이션을 확인 한다. 그 후에 그 객체를 변수(*멤버 변수)에 주입한다."
# 첨부자료 4 : @Autowired를 활용한 의존성 주입
package polymorphism_dependency;
import org.springframework.stereotype.Component;
@Component("sony")
public class SonySpeaker implements Speaker {
public SonySpeaker(){
System.out.println("SonySpeaker 객체 생성");
}
public void volumeUp(){
System.out.println("SonySpeaker---소리 올린다.");
}
public void volumeDown(){
System.out.println("SonySpeaker---소리 내린다.");
}
}
package polymorhism_inter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import polymorphism_dependency.Speaker;
/* TV는 LG로 형변환 가능, 자료형은 TV가 되지만 참조는 LG객체를 참조한다.
* alt + shift + s 통해서, 구체 메소드 구현 가능
* */
@Component("tv")
public class LG implements TV {
@Autowired
private Speaker speaker;
@Override
public void powerOn() {
System.out.println("엘지 --- 전원킨다.");
}
@Override
public void powerOff() {
System.out.println("엘지 --- 전원끈다.");
}
@Override
public void volumeUp() {
// System.out.println("엘지 --- 소리 올리다.");
speaker.volumeUp();
}
@Override
public void volumeDown() {
// System.out.println("엘지 --- 소리 내린다.");
speaker.volumeDown();
}
}
"@Autowired 어노테이션을 사용해서 의존성 주입을 하면, .xml 스프링설정 파일에 생성자 주입이나 Setter 주입을 할 필요가 없다. "
5.2.3 @Qualifier
: 앞서, Speaker를 자료형으로 가지고 있는 클래스는 크게 2가지 소니스피커, 애플스피커 이다. 이 상황에서 @Autowired 어노테이션으로 의존성 주입을 시도한다면, 스프링 컨테이너 입장에서는 소니 스피커, 애플 스피커 중 어떤 스피커를 의존성 주입해야할지 혼란스러울 것이다. 이때 사용하는 어노테이션이 @Qualifier 이다.
#참고자료 5 : 소니스피커 / 애플스피커 의존성 주입 겹칠 경우(*컨솔 에러 창)
"스프링 컨테이너가 apple, sony 중 의존성 주입을 해야 할 대상을 못찾는 경우"
#참고자료6 : @Qualifier 어노테이션을 사용하여, 의존성 주입될 객체의 자료형과 ID, 이름 활용
package polymorhism_inter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
import polymorphism_dependency.Speaker;
/* TV는 LG로 형변환 가능, 자료형은 TV가 되지만 참조는 LG객체를 참조한다.
* alt + shift + s 통해서, 구체 메소드 구현 가능
* */
@Component("tv")
public class LG implements TV {
/*클래스 ID : apple를 활용하여 의존성 주입을 하고 있다.*/
@Autowired
@Qualifier("apple")
private Speaker speaker;
@Override
public void powerOn() {
System.out.println("엘지 --- 전원킨다.");
}
@Override
public void powerOff() {
System.out.println("엘지 --- 전원끈다.");
}
@Override
public void volumeUp() {
// System.out.println("엘지 --- 소리 올리다.");
speaker.volumeUp();
}
@Override
public void volumeDown() {
// System.out.println("엘지 --- 소리 내린다.");
speaker.volumeDown();
}
}
"동일한 Speaker 자료형을 가지고 있는 클래스(소니, 애플)들 중 클래스 ID(apple)를 활용하여 의존성 주입 함"
package polymorphism_dependency;
import org.springframework.stereotype.Component;
/*클래스 ID : sony*/
@Component("sony")
public class SonySpeaker implements Speaker {
public SonySpeaker(){
System.out.println("SonySpeaker 객체 생성");
}
public void volumeUp(){
System.out.println("SonySpeaker---소리 올린다.");
}
public void volumeDown(){
System.out.println("SonySpeaker---소리 내린다.");
}
}
package polymorphism_dependency;
import org.springframework.stereotype.Component;
/*클래스 ID : apple*/
@Component("apple")
public class AppleSpeaker implements Speaker {
public AppleSpeaker(){
System.out.println("===> AppleSpeaker 객체 생성");
}
@Override
public void volumeUp() {
// TODO Auto-generated method stub
System.out.println("AppleSpeaker --- 소리 올린다.");
}
@Override
public void volumeDown() {
// TODO Auto-generated method stub
System.out.println("AppleSpeaker --- 소리 내린다.");
}
}
5.2.4 @Resource을 활용하여 의존성 주입
"앞 선 @Autowired / @Qualifier 은 변수타입으로 객체의 의존성 주입을 처리했다. 하지만, @Resource는 스프링 컨테이너로 하여금 name 속성을 사용하여 생성된 객체를 검색한 후, 의존성 주입을 처리한다."
#참고자료6 : @Qualifier 어노테이션을 사용하여, 의존성 주입될 객체의 ID, 이름 활용
package polymorhism_inter;
import javax.annotation.Resource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
import polymorphism_dependency.Speaker;
/* TV는 LG로 형변환 가능, 자료형은 TV가 되지만 참조는 LG객체를 참조한다.
* alt + shift + s 통해서, 구체 메소드 구현 가능
* */
@Component("tv")
public class LG implements TV {
/*@Autowired
@Qualifier("apple")*/
@Resource(name="apple")
private Speaker speaker;
@Override
public void powerOn() {
System.out.println("엘지 --- 전원킨다.");
}
@Override
public void powerOff() {
System.out.println("엘지 --- 전원끈다.");
}
@Override
public void volumeUp() {
// System.out.println("엘지 --- 소리 올리다.");
speaker.volumeUp();
}
@Override
public void volumeDown() {
// System.out.println("엘지 --- 소리 내린다.");
speaker.volumeDown();
}
}
package polymorphism_dependency;
import org.springframework.stereotype.Component;
/*클래스 ID : apple*/
@Component("apple")
public class AppleSpeaker implements Speaker {
public AppleSpeaker(){
System.out.println("===> AppleSpeaker 객체 생성");
}
@Override
public void volumeUp() {
// TODO Auto-generated method stub
System.out.println("AppleSpeaker --- 소리 올린다.");
}
@Override
public void volumeDown() {
// TODO Auto-generated method stub
System.out.println("AppleSpeaker --- 소리 내린다.");
}
}
5.2.5 어노테이션과 XML 설정 병행하여 사용하기
"앞서 어노테이션과 .xml 설정을 통해 스프링 컨테이너를 활용해보았다..;; 그렇다면 어떠할 경우에 어노테이션을 사용해야하고, 어떠할 경우에 .xml 설정을 사용해야 할까? "
[결론]
1) 어노테이션 : 변하지 않는 객체
2) .xml(설정파일) : 변하는 객체 또는 라이브러리로 제공하는 Class
5.3 추가 어노테이션
" 스프링 프레임 워크를 공부하는 가장 큰 이유는 결국에는 웹 프로그래밍 제작이다. 아래 대략적으로 프로그램이 돌아가는 원리를 작성한다."
# 첨부자료 7. 프리젠테이션 레이어 ~ 비지니스 레이어 연동관계
-Controller : 클라이언트의 요청을 처리하는 역할
-ServiceImpl : 실질적인 비지니스 로직을 처리
-DAO : 데이터베이스 연동 처리
"객체를 생성할 시에는 @Component 어노테이션으로 진행을 한다. 하지만. 위의 Controller, ServiceImpl, DAO의 모든 객체들을 @Component들로 생성을 하면, 클래스의 역할을 구분 하기가 쉽지 않다. 이를 위해 @Component들을 역할에 따라 크게 3가지 어노테이션으로 구분한다."
#첨부자료8. 역할에 따라 분리한 @Component 어노테이션
어노테이션 | 위치 | 의미 |
@Service | XXXServiceImpl | 비지니스 로직을 처리하는 Service 클래스 |
@Repository | XXXDAO | 데이터베이스 연동처리하는 DAO클래스 |
@Controller | XXXController | 사용자 요청을 제어하는 Controller 클래스 |
'자바 > SpringFrameWork' 카테고리의 다른 글
[스프링퀵스타트2-2] : 스프링 AOP (P. 157 ~ ) (0) | 2020.05.30 |
---|---|
[스프링퀵스타트2-1] : 스프링 AOP (P. 143 ~ ) (0) | 2020.05.29 |
[스프링퀵스타트1-4] : 의존성 주입-(4) (0) | 2020.05.22 |
[스프링퀵스타트1-4] : 의존성 주입-(3) (0) | 2020.05.22 |
[스프링퀵스타트1-4] : 의존성 주입-(2) (0) | 2020.05.22 |