본문 바로가기
교재 실습/자바 웹 개발 워크북

133. XML 기반 빈 관리 컨테이너 (3)

by Jint 2022. 10. 17.

3. name 속성으로 빈 이름 지정하기

<bean> 태그를 사용하여 자바 빈을 선언할 때 id 속성 대신 name 속성에 빈 이름을 지정할 수 있다. id 속성과 name 속성의 차이점은 다음 테이블에 정리하였다.

항목 id 속성 name 속성
용도 빈 식별자를 지정한다. 중복되어선 안된다. 인스턴스의 별명을 추가할 때 사용한다. id와 마찬가지로 중복되어선 안된다.
여러 개의 이름 지정 불가! 콤마(,), 세미콜론(;) 또는 공백을 사용하여 여러 개의 이름을 지정할 수 있다. 첫 번째 이름은 컨테이너에 빈을 보관할 때 사용되고, 나머지 이름은 빈의 별명이 된다.
빈 이름 작성 규칙 스프링 프레임워크 3.1 이전 버전은 이름에 문자, 숫자, 밑줄(_), 하이픈(-), 점(.)을 사용할 수 있었다. 이름 시작은 문자나 밑줄만 가능했다. 3.1 부터는 제약 없다. 제약 없다.

 

- 실습 패키지 생성

exam 패키지 아래에 test02 패키지를 생성한다. test01 패키지의 모든 파일을 test02 패키지에 복사한다.

 

- beans.xml 빈 설정 파일

exam/test02/beans.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"
 	xsi:schemaLocation="http://www.springframework.org/schema/beans
						http://www.springframework.org/schema/beans/spring-beans.xsd">

	<bean name="score" class="exam.test02.Score"/>
	<bean name="score2,score3,score4" class="exam.test02.Score"/>
	<!-- <bean name="score2 score3 score4" class="exam.test02.Score"/> -->
	<!-- <bean name="score2 score3 score4" class="exam.test02.Score"/> -->
	<bean name="score-ok!" class="exam.test02.Score"/>

</beans>
<bean name="score" class="exam.test02.Score"/>

id 대신 name 속성에 인스턴스 이름을 지정할 수 있다. exam.test02.Score 클래스의 인스턴스를 생성한 후 빈 컨테이너에 보관할 때 'score'라는 이름을 붙인다.

<bean name="score2,score3,score4" class="exam.test02.Score"/>
<bean name="score2 score3 score4" class="exam.test02.Score"/>
<bean name="score2 score3 score4" class="exam.test02.Score"/>

구분자를 이용하면 인스턴스에 대해 여러 개의 이름을 붙일 수 있다. 구분자로는 콤마(,)나 세미콜론(;), 공백을 사용할 수 있다. name 속성의 첫 번째 이름은 빈의 이름으로 사용되고 나머지는 빈의 별명이 된다. 예제의 경우 exam.test02.Score 클래스의 인스턴스를 생성한 후 score2 이름으로 빈을 보관한다. 나머지 이름 score3, score4는 빈의 별명이 될 것이다.

<bean name="score-ok!" class="exam.test02.Score"/>

빈의 이름에 느낌표(!)와 같은 특수 문자를 사용할 수 있다.

 

- 빈 컨테이너 테스트

빈 컨테이너를 테스트할 exam.test02.Test 클래스를 다음과 같이 편집한다.

package exam.test02;

import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Test {
	
	public static void main(String[] args) {
		//IoC 컨테이너 준비하여 빈 생성
		ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("exam/test02/beans.xml");
		
		System.out.println("[컨테이너에 보관된 객체의 이름 출력]");
		for(String name : ctx.getBeanDefinitionNames()) {//getBeanDefinitionNames() 메서드 반환 타입 : String 배열(String[])
			System.out.println(name);
		}
		
		System.out.println("[score2의 별명 출력]");
		for(String alias : ctx.getAliases("score2")) {//getAliases() 메서드 반환 타입 : String 배열(String[])
			System.out.println(alias);
		}
		
		//name="score"
		Score score = (Score)ctx.getBean("score");
		
		//name="score2,score3,score4" 
		Score score2 = (Score)ctx.getBean("score2");
		Score score3 = (Score)ctx.getBean("score3");
		Score score4 = (Score)ctx.getBean("score4");
		
		//name="score-ok!"
		Score scoreOk = (Score)ctx.getBean("score-ok!");
		
		System.out.println("[빈 꺼내기]");
		if(score != null) System.out.println("score 찾았음.");
		if(score2 != null) System.out.println("score2 찾았음.");
		if(score3 != null) System.out.println("score3 찾았음.");
		if(score3 != null) System.out.println("score4 찾았음.");
		if(scoreOk != null) System.out.println("score-ok! 찾았음.");
		
		System.out.println("[생성된 빈 비교]");
		if(score == score2) System.out.println("score == score2");
		if(score2 == score3) System.out.println("score2 == score3");
		if(score3 == score4) System.out.println("score3 == score4");
		if(score4 == scoreOk) System.out.println("score4 == scoreOk");
	}
	
}
[예 1]
for(String name : ctx.getBeanDefinitionNames()) {//getBeanDefinitionNames() 메서드 반환 타입 : String 배열(String[])
    System.out.println(name);
}

그림 1 ([예 1] 실행 결과)

getBeanDefinitionNames() 메서드는 빈 컨테이너에 보관된 빈의 이름들을 알고 싶을 때 사용한다. 이 메서드의 반환 타입은 String 배열(String[])이다. 출력 결과에 score3, score4가 보이지 않는 이유는 score2의 별명이기 때문이다.

[예 2]
for(String alias : ctx.getAliases("score2")) {//getAliases() 메서드 반환 타입 : String 배열(String[])
    System.out.println(alias);
}

그림 2 ([예 2] 실행 결과)

빈의 별명을 알고 싶다면 getAliases() 메서드를 호출한다. 이 메서드의 매개변수 값으로 빈의 이름을 주면 해당 빈의 별명을 String 배열로 반환한다. score2의 별명을 확인해 보니 score3과 score4가 출력되는 것을 알 수 있다.

빈을 꺼낼 때는 id와 마찬가지로 getBean() 메서드의 매개변수로 name 속성값을 넘긴다.

[예 3]
//name="score"
Score score = (Score)ctx.getBean("score");

//name="score2,score3,score4" 
Score score2 = (Score)ctx.getBean("score2");
Score score3 = (Score)ctx.getBean("score3");
Score score4 = (Score)ctx.getBean("score4");

//name="score-ok!"
Score scoreOk = (Score)ctx.getBean("score-ok!");

그림 3 ([예 3] 실행 결과)

getBean() 메서드는 아이디(id 속성), 이름(name 속성), 별명(name 속성)으로 빈을 찾아준다. 출력 결과에 score-ok!를 찾았다는 문구를 보니 빈의 이름에 느낌표(!)와 같은 특수 문자를 사용할 수 있다.

[예 4]
if(score == score2) System.out.println("score == score2");
if(score2 == score3) System.out.println("score2 == score3");
if(score3 == score4) System.out.println("score3 == score4");
if(score4 == scoreOk) System.out.println("score4 == scoreOk");

그림 4 ([예 4] 실행 결과)

getBean() 메서드가 반환한 인스턴스를 비교해 보면 score2와 score3, score4가 같은 객체임을 확인할 수 있다. score3과 score4는 score2의 별명이기 때문이다.

 

참고도서 : https://freelec.co.kr/book/1674/

 

[열혈강의] 자바 웹 개발 워크북

[열혈강의] 자바 웹 개발 워크북

freelec.co.kr

댓글