티스토리 뷰

Spring

04. 어노테이션 기반 설정

rivercity310 2022. 10. 30. 21:48

 

1. 어노테이션 설정 기초

 

스프링 프레임워크에서는 XML 설정이 매우 중요하다.

그만큼 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:p="http://www.springframework.org/schema/p"
       xmlns:context="http://www.springframework.org/schema/context"     // ns 추가
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context                     // schema 추가
       http://www.springframework.org/schema/context/spring-context-4.3.xsd"> // schema 추가

	// 컴포넌트 스캔
    <context:component-scan base-package="polymorphism"></context:component-scan>
/beans>

 

 

- 1. Context 네임스페이스 추가

 어노테이션 설정을 추가하려면 <beans>에 Context 관련 네임스페이스와 스키마 문서의 위치를 등록해야 한다.

 

 

- 2. 컴포넌트 스캔(component-scan) 설정

스프링 설정 파일에서 애플리케이션에 사용할 객체들을 <bean> 등록하지 않고 자동으로 생성하려면 <context:component-scan> 엘리먼트를 정의해야 한다.

 

이 설정을 추가하면 스프링 컨테이너는 클래스 패스에 있는 클래스들을 스캔하여 @Component가 설정된 클래스들을 자동으로 객체 생성한다.

 

 

 

위 설정이 완료되면 클래스들을 스프링 설정 파일에 일일이 <bean> 엘리먼트로 등록할 필요가 없어진다.

@Component("id")만 클래스 선언부 위에 설정하면 끝난다.

id를 생략할 경우 클래스 이름의 첫 글자를 소문자로 변경한 값이 자동으로 설정되며, 이 이름은 클라이언트 요청에 의해 사용된다.

 

 

 


 

 

2. 의존성 주입 어노테이션 설정

@Autowired와 @Qualifier는 스프링에서 제공하지만, @Inject, @Resource는 제공하지 않는다.

 

package polymorphism;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;

@Component("tv")
public class SeungsuTV implements TV {
    /*
    @Autowired
    @Qualifier("apple")
    */
    @Resource(name="apple")
    private Speaker speaker;
    private int price;

    /*
    @Autowired에 의해 필요가 없어졌다.

    public void setSpeaker(Speaker speaker) {
        System.out.println("setSpeaker 호출!");
        this.speaker = speaker;
    }

    public void setPrice(int price) {
        System.out.println("setPrice 호출!");
        this.price = price;
    }
     */
    
    // ...
    
}

 

// SonySpeaker.java
@Component("sony")
public class SonySpeaker implements Speaker {
	// ...
}

// AppleSpeaker.java
@Component("apple")
public class AppleSpeaker implements Speaker {
	// ...
}

 

- 1. @Autowired

주로 멤버변수 위에 선언하여 사용하며, 스프링 컨테이너는 멤버변수 위에 붙은 @Autowired를 확인하는 순간 해당 변수의 타입을 체크한다. 그리고 그 타입의 객체가 메모리에 존재하는지 확인한 후에, 그 객체를 변수에 주입한다.

만약 @Autowired가 붙은 객체가 메모리에 없다면 컨테이너는 NoSuchBeanDefinitionException을 발생시킨다.

 

 

- 2. @Qualifier

만약 의존성 주입 대상이 되는 Speaker 타입의 객체가 두개 이상이라면, 컨테이너는 어떤 객체를 할당할지 판단할 수 없어서 에러가 발생한다. (NoUniqueBeanDefinitionException)

 

@Qualifier 어노테이션은 의존성 주입될 객체의 아이디나 이름을 지정할 수 있다.

이때 Speaker 객체의 이름(sony, apple) 중 하나를 지정하면 간단하게 처리할 수 있다.

 

 

- 3. @Resource, @Inject

@Autowired와 다르게 @Resource는 객체의 이름을 이용하여 의존성 주입을 처리한다.

name 속성을 통해, 스프링 컨테이너가 해당 이름으로 생성된 객체를 검색하여 의존성 주입을 처리한다.

[ @Resource(name="apple") = @Autowired + @Qualifier("apple") ]

 

@Inject 역시 @Resource와 동일한 기능의 어노테이션이다.

 

 

 


 

 

3. 어노테이션과 XML 설정 병행하여 사용하기

 

스프링으로 의존성 주입을 처리할 때, XML 설정과 어노테이션 설정은 장단점이 서로 상충한다.

XML 방식은 자바 코드를 수정하지 않고 XML 파일의 설정만 변경하면 실행되는 Speaker를 교체할 수 있어서 유지보수가 편하다. 하지만 <bean> 등록을 많이 해야하고, 의존관계 설정도 부담스럽다.

그렇다고 어노테이션만 사용하자니 자바 소스를 수정해야 의존관계를 변경할 수 있다.

 

따라서 어노테이션과 XML, 두 방식의 장점을 서로 조합하는 것으로 최상의 결과를 도출할 수 있다.

예를 들면, 변경되지 않는 객체는 어노테이션(TV)을 설정하여 사용하고, 변경될 가능성이 있는 객체(Speaker)는 XML 설정으로 사용하는 것이 바람직하다.

 

또한 라이브러리 형태로 제공되는 클래스는 반드시 XML 설정을 통해서만 사용할 수 있다. (Apache Commons 등)

 

 

 

변경될 가능성이 있는 객체

@Component 어노테이션을 다 지워서 객체가 자동으로 생성되는 것을 막는다.

그리고 XML 설정 파일에 사용할 객체만 <bean> 등록한다.

// SonySpeaker.java
public class SonySpeaker implements Speaker {
	// ...
}

// AppleSpeaker.java
public class AppleSpeaker implements Speaker {
	// ...
}

 

@Autowired 어노테이션만 사용한다.

@Component("tv")
public class SeungsuTV implements TV {
    @Autowired
    private Speaker speaker;
    private int price;

	// ...
}

 

 

 


 

 

4. 추가 어노테이션

 

 

Presentation Layer는 사용자와의 커뮤니케이션을 담당하고, Business Layer는 사용자 요청에 대한 비즈니스 로직 처리를 담당한다.

 

시스템을 구성하는 각기 다른 역할을 하는 모든 클래스에 @Component를 할당하면 어떤 클래스가 어떤 역할을 하는지 파악하기 어렵다는 문제가 있다. 따라서 스프링 프레임워크에서는 이런 클래스들을 분류하기 위해 @Component를 상속하는 다음 세개의 어노테이션을 추가로 제공한다.

 

 

- @Servlce

위치: XXXServiceImpl

의미: 비즈니스 로직을 처리하는 Service 클래스

 

 

- @Repository

위치: XXXDAO

의미: Database 연동을 처리하는 DAO 클래스

 

 

- @Controller

위치: XXXController

의미: 사용자 요청을 제어하는 Controller 클래스

 

 

이처럼 어노테이션을 나눈 이유는 단순 클래스를 분류하기 위해서만은 아니다.

@Controller는 해당 객체를 MVC 아키텍처에서 컨트롤러 객체로 인식하도록 해주고,

@Repository는 DB 연동 과정에서 발생하는 예외를 변환해주는 특별한 기능이 추가되어 있다.

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
TAG
more
«   2025/04   »
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30
글 보관함