132. XML 기반 빈 관리 컨테이너 (2)
2. 스프링 빈 컨테이너 ClassPathXmlApplicationContext 사용
build.gradle 파일에서 스프링 라이브러리를 가져오는 부분을 dependencies 블록에서 더 직관적으로 표현했다.
plugins {
id 'org.springframework.boot' version '2.3.1.RELEASE'
id 'io.spring.dependency-management' version '1.0.9.RELEASE'
id 'java'
}
group = 'com.example'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '1.8'
configurations {
compileOnly {
extendsFrom annotationProcessor
}
}
repositories {
mavenCentral()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-jdbc'
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-oauth2-client'
implementation 'org.springframework.boot:spring-boot-starter-security'
//스프링 라이브러리
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
implementation 'org.springframework.kafka:spring-kafka'
compileOnly 'org.projectlombok:lombok'
runtimeOnly 'com.h2database:h2'
runtimeOnly 'mysql:mysql-connector-java'
annotationProcessor 'org.projectlombok:lombok'
testImplementation('org.springframework.boot:spring-boot-starter-test') {
exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
}
testImplementation 'org.springframework.kafka:spring-kafka-test'
testImplementation 'org.springframework.security:spring-security-test'
}
test {
useJUnitPlatform()
}
참고링크 : https://linkeverything.github.io/study/springboot/add-library/
Gradle 프로젝트에 라이브러리 추가하기
프로그래밍을 하는 데 있어서 라이브러리 라는 용어를 자주 사용하게 됩니다. 라이브러리는 “도서관” 이라는 의미겠지만, coding 에서 의미는 조금 상이합니다. 이번 내용은 Spring boot에 국한되
linkeverything.github.io
- 실습 패키지 생성
실습에 사용할 자바 패키지 exam.test01를 생성한다. Gradle 프로젝트의 기본 자바 소스 폴더는 src/main/java 이다. 이 폴더 아래에 패키지 폴더를 생성한다(그림 1).
- Score 클래스 정의
빈 컨테이너에서 관리할 클래스를 준비한다. 학생의 국어, 영어, 수학 점수를 보관하는 클래스이다. 이렇게 값을 보관하는 용도로 사용하는 클래스를 '값 객체(Value Object)'라고 부른다.
exam.test01 패키지에 Score 클래스를 생성한 뒤 내용은 다음과 같이 작성한다.
package exam.test01;
public class Score {
String name;
float kor;
float eng;
float math;
public Score() {}
public Score(String name, float kor, float eng, float math) {
this.name = name;
this.kor = kor;
this.eng = eng;
this.math = math;
}
public float average() {
return sum() / (float)3;
}
public float sum() {
return kor + eng + math;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public float getKor() {
return kor;
}
public void setKor(float kor) {
this.kor = kor;
}
public float getEng() {
return eng;
}
public void setEng(float eng) {
this.eng = eng;
}
public float getMath() {
return math;
}
public void setMath(float math) {
this.math = math;
}
}
- 빈 설정 XML 파일 준비
애플리케이션에서 사용할 객체는 빈 설정 파일에 선언한다. 스프링 IoC 컨테이너는 빈 설정 파일에 선언된 대로 빈을 생성한다.
exam.test01 패키지에 beans.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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="score" class="exam.test01.Score"/>
</beans>
<beans> ... </beans>
빈 설정 파일은 스프링에서 정의한 규칙에 따라 XML 태그를 작성해야 한다. XML 선언을 제외하고 빈 설정 파일에서 제일 먼저 등장하는 태그는 beans이다.
<beans xmlns="http://www.springframework.org/schema/beans">
</beans>
beans 태그는 http://www.springframework.org/schema/beans 네임스페이스에 소속되어 있기 때문에 XML 파서가 이해할 수 있도록 네임스페이스를 밝혀야 한다. 자바 클래스를 사용하기 전에 import를 선언하는 것과 비슷하다.
<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">
</beans>
그리고 네임스페이스를 정의한 XML 스키마 파일의 위치를 지정한다.
<bean id="score" class="exam.test01.Score"/>
▶ 자바 코드로 표현하면?
new exam.test01.Score();
스프링 IoC 컨테이너가 생성할 자바 빈에 대한 정보는 <bean> 태그로 선언한다. class 속성에는 클래스 이름을 지정한다. 반드시 패키지 이름을 포함한 클래스 이름(fully qualified name)이어야 한다. id 속성은 객체의 식별자이다. 빈 컨테이너에서 객체를 꺼낼 때 이 식별자를 사용한다.
- 스프링 IoC 컨테이너 사용
ClassPathXmlApplicationContext 클래스를 사용하여 IoC 컨테이너를 준비한다. IoC 컨테이너는 빈 설정 파일에 선언된 대로 인스턴스를 생성하여 객체 풀(pool)에 보관한다.
exam.test01 패키지에 Test 클래스를 생성하여 다음과 같이 작성한다.
package exam.test01;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test {
public static void main(String[] args) {
//IoC 컨테이너 준비하여 빈 생성
ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("exam/test01/beans.xml");
//빈 꺼내기
Score score = (Score)ctx.getBean("score");
System.out.println("합계:" + score.sum());
System.out.println("평균:" + score.average());
}
}
//IoC 컨테이너 준비하여 빈 생성
ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("exam/test01/beans.xml");
ClassPathXmlApplicationContext 클래스의 인스턴스를 생성할 때 생성자에 빈 설정 파일의 경로를 넘긴다. ClassPathXmlApplicationContext 클래스는 자바 클래스 경로에서 exam/test01 폴더를 찾는다. 그리고 beans.xml 파일을 로딩한다. 빈 설정 파일에 선언된 빈을 생성하여 객체 풀(pool)에 보관한다. 현재 예제에서는 Score 객체를 한 개 생성할 것이다(그림 2).
//빈 꺼내기
Score score = (Score)ctx.getBean("score");
빈 컨테이너가 준비되었으면 getBean() 메서드를 호출하여 빈을 꺼낸다. getBean() 메서드를 호출할 때 넘겨주는 매개변수 값은 빈 아이디이다(그림 3). 빈 아이디는 빈 설정 파일에 선언되어 있다. getBean() 메서드의 반환 타입은 Object이기 때문에 반환된 객체를 제대로 사용하려면 실제 타입으로 형변환해야 한다.
- 실행 결과
실행 결과를 확인해 보면 아무런 오류 없이 합계와 평균 값이 출력된다. 정상적으로 Score 객체를 찾아 sum() 메서드와 average() 메서드를 호출하였다. 단 score 객체에 대해 국어, 영어, 수학 점수를 할당하지 않아서 출력 결과가 0.0이 되었다(그림 4).
참고도서 : https://freelec.co.kr/book/1674/
[열혈강의] 자바 웹 개발 워크북
[열혈강의] 자바 웹 개발 워크북
freelec.co.kr