728x90


이번장은 전장인 4장 부분의 프로젝트와 연결되어있다. 반드시 참고하길 바란다.


https://github.com/justkukaro/SpringSampleRepository/tree/master/Ch05


github 코드는 위에서 확인할 수 있다.


저번 코드를 다 안다는 가정하에서 시작하겠다.

다시 설명하지만 4장부분을 확인하던가 깃헙 레포지터리를 확인하라.


일단 미리 소개할 애너테이션 들을 보도록 하겠다.


Autowired - 레퍼런스 타입의 주입을 자동으로 해준다.


Qualifier - 특정 객체의 주입을 이름을 사용해서 해준다. Autowired가 모호성을 가질 때 지정해서 사용할 수 있다.


Inject - Autowired와 동일하다.


Resource - Autowired와 Qualifier를 합친 기능.


각각의 기능들을 보도록 하자.

이들을 테스트하기 이전에 새로운 객체들을 보도록 하자.



모든 종목에는 심판이 필요하다. 그래서 우리는 심판 클래스를 따로 만들었다.

그리고 Soccer 클래스에 멤버로 새로운 변수를 추가하였다.


private Judge judge;

위와 같이 코드를 짰을 경우에 의존성을 어떻게 주입할 것인지에 대해서 알아보도록하자.



@Autowired



위처럼 Judge를 상속받는 클래스는 SoccerJudge로 단 한개 밖에 없다.

여기서 모호한 부분은 존재하지 않는다.


package net.theceres.dto;

import org.springframework.stereotype.Component;

@Component("soccer")
public class Soccer implements Game {
private boolean ball;
private int peopleCount;
private Judge judge;

/*어쩌구 저쩌구*/

Soccer 클래스는 Judge라는 래퍼런스 클래스를 가지고 있다.

심판은 interface로 지정하여 줄경우 다행히도 Judge를 상속받는 녀석은 단 한명 밖에 없다.

이 경우 Autowired를 사용하면 손쉽게 해결할 수 있다.



Autowired를 지정하기 위해서는 반드시 component로 지정해서 자동 클래스 로딩되게 하여야한다.


만약 여기서 Component로 지정되지 않아서 확정조차 될수 없는 경우에는 당연히 exception이 일어난다.


package net.theceres.dto;

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

@Component("soccer")
public class Soccer implements Game {
private boolean ball;
private int peopleCount;

@Autowired
private Judge judge;

/*어쩌구 저쩌구*/

위처럼 사용하면 된다.

여기서 Judge는 자동으로 연결되며 그게 soccer-judge로 확정되기 때문에 아무 문제없이 사용할 수 있다.


public void info() {
System.out.println("축구는 " + peopleCount + "명이서 공을" + (ball ? "사용하는 " : "사용하지 않는 ") + "게임입니다.");
judge.alert();
}

Soccer클래스의 info메소드에 judge.alert을 호출해보자. 이제 결과를 보자.



제대로 연결된걸 확인할 수 있다.


@Qualifier




이번에는 Judge가 두개인 경우를 보도록 하자.

이경우 그대로 실행하면 에러가 난다.

왜냐하면 judge가 두명이라서 모호하기 때문이다.



위처럼 실행하면 에러가 나게된다.


이를 위해서 사용하는게 바로 Qualifier이다.


package net.theceres.dto;

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

@Component("soccer")
public class Soccer implements Game {
private boolean ball;
private int peopleCount;
@Autowired
@Qualifier("soccer-judge")
private Judge judge;

이렇게 Qualifier을 붙혀서 정확히 누굴 쓸껀지 지정해 준다.

그러면 하나로 확정되서 사용할 수 있다.


@Inject


만약 Inject를 사용하고싶다면 Autowired 대신 사용할 수 있다.

둘이 기능이 같으므로 사실 사용할 이유는 없다.

그러나 사용하는 방법에 대해서는 알려드리겠다.


@Component("soccer")
public class Soccer implements Game {
private boolean ball;
private int peopleCount;
@Inject
@Qualifier("soccer-judge")
private Judge judge;

일단 사용은 위처럼 Autowired로 사용한다.

대신 maven 의존성으로 Inject를 추가해줘야한다.


<dependency>
<groupId>org.sonatype.sisu</groupId>
<artifactId>sisu-inject-bean</artifactId>
<version>1.4.2</version>
</dependency>

이를 추가하고 사용해주면 된다.


@Resource


여기서보면 Autowired와 Qualifier를 같이 쓰니까 거추장스러울 것이다.

같이 사용하는 법을 보도록 하자.


package net.theceres.dto;

import org.springframework.stereotype.Component;

import javax.annotation.Resource;

@Component("soccer")
public class Soccer implements Game {
private boolean ball;
private int peopleCount;

@Resource(name = "soccer-judge")
private Judge judge;

Resource애너테이션을 쓰면 한줄로 요약해서 쓸 수 있다.

그래서 필자는 왠만해서는 그냥 Resource애너테이션만 쓴다.


xml?? annotation??


여러분은 초기에 xml을 사용했고 그게 귀찮아서 annotation을 사용했다.

여기에 대해서 무엇을 쓰는게 낳은 방식인가에 대해서 논하는 경우가 많다.


물론 둘의 장단점은 있다. xml을 써야 사실 완벽한 의미로의 IoC를 구현할 수 있다.

annotation을 사용한다면 결국에는 자바코드를 수정하는 것이므로 IoC관점에서는 좋지 않다.


그러나 xml양이 너무 늘어나는 단점도 있다...

그래서 적당히 섞어쓰던가 아니면 여러분이 편한데로 쓰면된다.


사실 스프링의 철학인 IoC를 완전히 다 지킬 필요도 없다는게 개인적인 생각이므로 적당히 필요한 선 까지 사용하도록 하자.

+ Recent posts