스프링 프레임워크는 XML 설정이 중요합니다.
하지만 XML에 과도한 설정을 피하기 위해 어노테이션 설정을 지원합니다.
applicationContext.xml 파일의 Namespaces를 열고 context에 체크합니다.
컴포넌트 스캔 설정을 하면
애플리케이션에서 사용할 객체들을 스프링 설정 파일에 <bean>으로 등록하지 않고 자동으로 생성합니다.
이 설정 후 스프링 컨테이너는 클래스 패스에 있는 클래스들을 스캔해
@Component가 설정된 클래스들을 자동으로 객체 생성합니다.
위와 같이 스프링 설정 파일과 클래스에 @Component 선언을 동시에 하게 되면 메모리에는 LgTV 객체가 두 개 생성됩니다.
또한 두 설정 모두 해당 클래스에 기본 생성자가 있어야만 컨테이너가 객체를 생성할 수 있습니다.
클라이언트 프로그램에서 LgTV 객체를 요청하기에는 추가 설정이 필요합니다.
클라이언트가 스프링 컨테이너가 생성한 객체를 요청하려면,
요청할 때 사용할 아이디나 이름이 반드시 설정되어야 합니다.
id나 name을 지정하지 않았다면 클래스 이름의 첫 글자를 소문자로 변경해 컨테이너가 자동으로 설정합니다.
applicationContext.xml 의 component-scan 설정과 @Component 어노테이션 설정 후 TVUser 클래스를 실행합니다.
이제 @Autowired를 사용해 의존성 주입을 설정합니다.
대부분 멤버변수 위에 선언하여 사용하며
스프링 컨테이너는 멤버 변수 위에 붙은 @Autowired를 확인하고 해당 변수의 타입을 체크합니다.
그 타입의 객체가 메모리에 존재하는지 확인 후, 그 객체를 변수에 주입합니다.
만약 @Autowired가 붙은 객체가 메모리에 없다면
컨테이너가 NoSuchBeanDefinitionException을 발생시키며
@Autowired 대상 객체가 메모리에 존재하지 않는다는 의미입니다.
package polymorphism;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component("tv")
public class LgTV implements TV {
@Autowired
private Speaker speaker; // Speaker 타입 변수 추가
public LgTV() {
System.out.println("Lg 객체 생성");
}
public void powerOn() {
System.out.println("LgTV 전원 켠다.");
}
public void powerOff() {
System.out.println("LgTV 전원 끈다.");
}
public void volumeUp() {
speaker.volumeUp(); // Speaker 객체 메소드 추가
}
public void volumeDown() {
speaker.volumeDown(); // Speaker 객체 메소드 추가
}
}
현재 작성한 Speaker 클래스는 SonySpeaker이며
해당 Speaker 객체 의존성 주입을 하기 위해선
아래 두 가지 방법 중 한 가지를 사용해야 에러가 발생하지 않습니다.
메모리에 생성된 Speaker 타입의 객체가 두 개 이상일 때 컨테이너는 @Autorwired 로 선언되어 있는 변수에
어떤 객체를 할당할지 판단하지 못 해 에러를 발생시킵니다.
AppleSpeaker에도 @Component 어노테이션을 사용해 TVUser를 실행시켰더니
NoUniqueBeanDefinitionException을 발생시켰습니다.
@Autowired 밑에 @Qualifier를 사용해 AppleSpekaer를 주입해주었습니다.
의존성 주입될 객체의 아이디나 이름을 지정할 수 있습니다.
어노테이션과 XML 설정을 병행하여 사용하면 단점을 보완하여 자바 소스를 변경하지 않고 사용할 수 있게 합니다.
현재 SonySpeaker와 AppleSpeaker에 @Component가 선언되어 있어
LgTV에서 @Autowired로 Speaker 객체를 주입할 때 에러가 났었습니다. (@Qualifier 선언 제거)
SonySpeaker와 AppleSpeaker에 선언된 어노테이션을 지워줍니다.
위 설정대로하면 SonySpeaker가 LgTV의 Speaker에 주입됩니다.
이후 AppleSpeaker로 변경할 때 자바 소스 변경 없이 XML만 수정하면 교체할 수 있습니다.
즉, 클라이언트가 요청할 LgTV는 @Component 어노테이션으로 처리하고 의존성 주입을 @Autowired로 처리합니다.
수정될 가능성이 있는 의존성이 주입될 객체를 스프링 설정 파일(applicationContext.xml)에 <bean> 으로 등록하여
자바 코드 수정 없이 XML 수정만으로 Speaker를 교체할 수 있습니다.
우리가 직접 개발한 클래스는 어노테이션 및 XML을 사용할 수 있지만 라이브러리 형태로 제공되는 클래스(서드 파티)는 반드시 XML 설정을 통해서만 사용이 가능합니다.
프레젠테이션 레이어는 사용자와 커뮤니케이션을 담당하고 (Controller, View)
비즈니스 레이어는 사용자의 요청에 대한 비즈니스 로직 처리를 담당합니다. (Service:ServiceImpl, Repository:DAO)
컨트롤러는 사용자의 요청을 제어하며
ServiceImpl 클래스는 실질적인 비즈니스 로직을 처리하고
DAO는 데이터베이스 연동을 담당합니다.
모든 클래스에 @Component를 할당하게 되면 어떤 클래스가 어떤 역할을 수행하는지 파악하기 어렵습니다.
또한 어노테이션을 나누면 설정된 어노테이션에 따라 특별한 기능이 추가되어 있습니다.
'Spring' 카테고리의 다른 글
1-7. 스프링 setter 주입 활용 회원 정보 관리 컴포넌트 작성 (0) | 2025.01.28 |
---|---|
1-6. 스프링 프로젝트 구조 및 비즈니스 컴포넌트 구현 (0) | 2025.01.26 |
1-4. 스프링 의존성 주입 (0) | 2025.01.24 |
1-3. 스프링 컨테이너 및 설정 파일 (0) | 2025.01.22 |
1-2. 프레임워크 개요 (0) | 2025.01.21 |