포스트

Xml 파일을 이용한 설정(1)

xml파일을 이용한 설정(1)

들어가기 전에


Spring의 IoC / DI 컨테이너에 대한 동작을 확인하기 위해 Maven을 이용해 프로젝트를 생성한 후, XML 형식의 설정 파일을 만들어 IoC와 DI가 잘 동작하는지 확인해 보도록 한다.

학습 목표


  1. Maven을 이용해 스프링 프레임워크를 사용하는 프로젝트를 생성할 수 있다.
  2. Bean이 무엇인지 이해한다.
  3. XML형식의 스프링 설정파일의 내용을 이해한다.

핵심 개념


  • Bean
  • ApplicationContext
  • DI

Maven으로 Java프로젝트 만들기


  • 메이븐 프로젝트 생성

    이미지

  • 지금 사용하고 있는 Workspace 경로를 사용할 것이므로 그대로 둔다.

    이미지

  • maven archetype plugin - 템플릿에서 메이븐 프로젝트 생성하기
    • 사용자가 template 로부터 maven project를 생성할 수 있게 해주는 plugin이다. 미리 정의된 maven project template는 archetype이라고 불린다.
    • 즉, archetype은 메이븐 프로젝트에서 제공해주는 템플릿으로 어떤 것을 지정하는 것에 따라 프로젝트 구조가 달라진다.

    이미지

    이미지

    • GroupId
      • 프로젝트를 생성하는 조직의 고유한 식별자 정보로 com.google처럼 일반적으로 회사의 도메인 이름을 거꾸로 사용한다.
    • ArtifactId
      • 진행하는 프로젝트의 이름으로 같은 Group 내의 프로젝트를 구분하는데 사용한다.
      • 소문자로만 작성하고 특수문자를 사용하지 않는다.
      • 버전 정보를 생략한 jar 파일의 이름이 된다.
    • Pacakge
      • 소스 코드의 패키지 이름으로 groupId.artifactId 형식을 권장한다.
  • pom.xml 파일에 JDK를 사용하기 위한 플러그인 설정을 추가한다.
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
31
32
33
34
35
36
37
38
39
40
41
42
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>kr.or.connect</groupId>
  <artifactId>diexam01</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>jar</packaging>

  <name>diexam01</name>
  <url>http://maven.apache.org</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>

  <dependencies>
    <!-- 단위 테스트할 수 있는 도구 -->
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
  
    <!-- build 엘리먼트 추가 -->
    <build>
     <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.6.1</version>
            <configuration>
                <source>1.8</source>
                <target>1.8</target>
            </configuration>
        </plugin>
    </plugins>
  </build>
</project>

  • 프로젝트를 선택하고, Maven -> Update Project를 선택한다. 업데이트가 되면서 오류메시지가 사라진다.

    이미지

  • 메이븐 프로젝트를 생성할 때 기본적으로 사용되는 자바 버전은 설정 및 환경에 따라 다를 수 있다. 일반적으로 메이븐 프로젝트를 생성할 때 메이븐 플러그인의 설정에 따라 기본적으로 사용되는 자바 버전이 설정된다.

    이미지

  • 메이븐은 프로젝트의 pom.xml 파일에 프로젝트의 설정을 정의한다. 이 파일에는 프로젝트의 의존성, 빌드 설정 및 컴파일러 설정이 포함될 수 있다. 메이븐 프로젝트를 생성할 때 자바 버전이 명시적으로 지정되지 않으면, 일반적으로 시스템 환경에 따라 기본 버전이 선택된다. 다음과 같이 pom.xml 파일에 자바 버전을 명시적으로 지정할 수 있다.

    1
    2
    3
    4
    
      <!-- 자바 버전을 1.8로 설정하고 있다. 이렇게 설정함으로써 메이븐은 해당 버전의 자바 컴파일러를 사용하여 프로젝트를 빌드하게 된다. -->
      <properties>
          <java.version>1.8</java.version>
      </properties>
    
  • GroupId와 ArtifactId로 넣었던 부분이 패키지명으로 만들어져서 나와있는 것을 확인할 수 있다.

이미지

App.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
package kr.or.connect.diexam01;

/**
 * Hello world!
 *
 */
public class App 
{
    public static void main( String[] args )
    {
        System.out.println( "Hello World!" );
    }
}

AppTest.java

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
31
32
33
34
35
36
37
38
39
package kr.or.connect.diexam01;

import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;

/**
 * Unit test for simple App.
 */
public class AppTest 
    extends TestCase
{
    /**
     * Create the test case
     *
     * @param testName name of the test case
     */
    public AppTest( String testName )
    {
        super( testName );
    }

    /**
     * @return the suite of tests being tested
     */
    public static Test suite()
    {
        return new TestSuite( AppTest.class );
    }

    /**
     * Rigourous Test :-)
     */
    public void testApp()
    {
        assertTrue( true );
    }
}

  • 프로젝트 동작 확인
    • AppTest.java 를 선택한 후 우측버튼을 클릭하고 Run As -> JUnit Test 메뉴를 선택한다. 하단의 JUnit 뷰에 하나의 테스트가 성공했다는 메시지와 함께 녹색 막대가 보여진다.

이미지

  • Bean class란?
    • 예전에는 Visual 한 컴포넌트를 Bean이라고 불렀지만, 근래 들어서는 일반적인 Java클래스를 Bean클래스라고 보통 말한다.
    • Bean클래스의 3가지 특징은 다음과 같다.
      1. 기본생성자를 가지고 있다.
      2. 필드는 private하게 선언한다.
      3. getter, setter 메소드를 가진다. getName() setName() 메소드를 name 프로퍼티(property)라고 한다.

UserBean.java

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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
package kr.or.connect.diexam01;

// 빈클래스
public class UserBean {
	
	// 필드는 private 하다.
	private String name;
	private int age;
	private boolean male;
	
	// 기본생성자를 반드시 가지고 있어야 한다.
	// 자바 클래스에 생성자가 하나라도 명시적으로 정의되어 있는 경우, 컴파일러는 해당 클래스에 기본 생성자(default constructor)를 자동으로 추가하지 않는다.
	public UserBean() {
	}
	
	public UserBean(String name, int age, boolean male) {
		this.name = name;
		this.age = age;
		this.male = male;
	}

	// setter, getter메소드는 프로퍼티라고 한다.
	public void setName(String name) {
		this.name = name;
	}

	public String getName() {
		return name;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	public boolean isMale() {
		return male;
	}

	public void setMale(boolean male) {
		this.male = male;
	}

}

Spring Bean Factory를 이용하여 Bean객체 이용하기

1) pom.xml 파일을 다음과 같이 수정한다.

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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>kr.or.connect</groupId>
  <artifactId>diexam01</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>jar</packaging>

  <name>diexam01</name>
  <url>http://maven.apache.org</url>
  
  <!-- 프로퍼티에 포함된 값들은 상수처럼 사용할 수 있다. 이러한 값들은 일반적으로 설정 파일이나 외부 구성 파일에 저장되어 있으며, 애플리케이션의 동작에 필요한 여러 설정 값들을 포함하고 있다.-->
  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <!-- Spring Version-->
    <spring.version> 4.3.14.RELEASE</spring.version>
  </properties>

  <dependencies>
	<!-- Spring -->
	<dependency>
		<groupId>org.springframework</groupId>
		<artifactId>spring-context</artifactId>
		<version>${spring.version}</version>
	</dependency>
	
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
  
    <build>
     <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.6.1</version>
            <configuration>
                <source>1.8</source>
                <target>1.8</target>
            </configuration>
        </plugin>
    </plugins>
  </build>
</project>

2) 추가된 라이브러리 확인한다.

이미지

3) resources 소스 폴더를 생성한다.

  • 일반적으로 소스 코드와 설정 파일을 분리하여 관리하는 것이 좋다. 이를 통해 프로젝트의 구조를 보다 체계적으로 유지할 수 있고, 유지보수가 용이해진다. 일반적으로 자바 프로젝트에서는 소스 코드와 설정 파일을 분리하기 위해 src/main/resources 폴더를 사용한다. 폴더는 소스 코드와는 별도로 컴파일되지 않으며, 프로젝트의 클래스패스에 포함되어 런타임 시에 애플리케이션에서 리소스를 로드할 수 있도록 한다.
  • 프로젝트를 선택하고, 오른쪽 버튼을 클릭한 후 New -> Folder를 선택한다.

이미지

이미지

4) resources 소스 폴더에 xml 파일을 작성한다.

  • 해당 폴더를 선택하고, 우측버튼을 클릭하여 New – File을 선택한다. src/main/resources 폴더를 선택한 후 File name에 applicationContext.xml 을 입력하고 Finish 버튼을 클릭한다.

이미지

applicationContext.xml

1
2
3
4
5
6
7
8
<?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="userBean" class="kr.or.connect.diexam01.UserBean"></bean>

</beans>
  • bean 태그를 하나 입력했는데, 위의 태그는 다음과 같은 의미를 가진다.

    UserBean userBean - new UserBean();

  • 스프링 설정 파일에 빈(bean)을 등록하여 스프링 컨테이너에게 해당 객체를 생성하고 관리하도록 지시할 수 있다. 일반적으로 XML 또는 JavaConfig 형식으로 스프링 설정 파일을 작성한다.
  • 빈을 등록할 때는 <bean> 엘리먼트를 사용하며, 해당 빈의 속성으로는 id, class 등이 있다.
    • id: 객체를 식별할 수 있는 고유한 이름을 지정한다. 이 이름을 사용하여 스프링 컨테이너에서 빈을 검색하거나 참조할 수 있다.
    • class: 빈이 생성될 클래스의 풀 패키지 경로를 지정한다. 이 클래스는 실제로 사용자가 정의한 일반적인 자바 클래스이다.
    • 예를 들어, 패키지명이 com.example이고 해당 패키지 안에 UserBean 클래스가 있을 경우, 스프링 설정 파일에 빈을 등록하는 방법은 다음과 같다.
    1
    
      <bean id="userBean" class="com.example.UserBean"/>
    
    • 이렇게 빈을 등록하면 스프링 컨테이너는 해당 클래스의 인스턴스를 생성하고, 이를 싱글톤으로 관리한다. 따라서 스프링 컨테이너 내에서는 이 빈의 객체가 단 하나만 생성되어 모든 요청에 대해 동일한 객체를 반환하게 된다.
    • 이와 같이 스프링 설정 파일에 빈을 등록함으로써 스프링 컨테이너가 객체의 생성과 생명주기 관리를 담당하게 된다. 이는 싱글톤 패턴과 비슷한 개념으로, 스프링의 핵심적인 기능 중 하나이다.

ApplicationContext를 이용해서 설정파일을 읽어들여 실행하기

이미지

ApplicationContextExam01

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
package kr.or.connect.diexam01;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class ApplicationContextExam01 {

	public static void main(String[] args) {
		ApplicationContext ac = new ClassPathXmlApplicationContext( 
				"classpath:applicationContext.xml"); 
		System.out.println("초기화 완료.");
		
		UserBean userBean = (UserBean)ac.getBean("userBean");
		userBean.setName("kim");
		System.out.println(userBean.getName());
		
		UserBean userBean2 = (UserBean)ac.getBean("userBean");
		if(userBean == userBean2) {
			System.out.println("같은 인스턴스이다.");
		}
		
	}
}

이미지

  1. ApplicationContext 인터페이스와 다양한 컨테이너: ApplicationContext는 인터페이스이며, 이를 구현한 다양한 컨테이너가 존재한다.
  2. ClassPathXmlApplicationContext: ApplicationContext 인터페이스를 구현한 컨테이너 중 하나로, 클래스패스(classpath)에서 XML 파일을 읽어들여서 사용하는 객체이다.
  3. ClassPathXmlApplicationContext와 resources 폴더: resources 폴더는 main 소스 폴더 내에 위치하며, 자동으로 클래스패스로 지정된다. 따라서 resources 폴더에 생성된 XML 파일은 자동으로 클래스패스에 포함된다.
  4. bean 설정 파일의 위치: java 디렉토리에서 생성된 클래스와 마찬가지로, bean 설정 파일은 bin 디렉토리에 생성됩니다. 그렇기 때문에 ClassPathXmlApplicationContext를 사용하여 설정 파일을 읽어들일 수 있다.
  5. ClassPathXmlApplicationContext의 역할: ClassPathXmlApplicationContext 인스턴스가 생성될 때, 설정 파일을 읽어들인 후 그 안에 선언된 모든 빈(bean)들을 메모리에 올린다. 이때 설정 파일에 등록된 bean의 정보를 모두 읽어들여 객체를 생성하고 메모리에 올린다.
  6. getBean() 메서드와 빈의 레퍼런스 반환: ApplicationContext는 getBean() 메서드를 제공하여 설정 파일에 등록된 빈의 레퍼런스를 반환한다. 이때 getBean() 메서드의 파라미터로는 빈의 id 값을 넣어주어야 한다. 스프링 설정 파일에 등록된 객체들은 다양한 객체일 수 있으므로 getBean()은 Object 타입으로 반환하며, 필요에 따라 형변환을 해서 사용해야 한다.
  7. getBean() 메서드와 동일한 ID로 빈 조회: getBean() 메서드를 사용하여 동일한 ID로 빈을 조회할 때, 첫 번째 요청과 두 번째 요청에서 받은 객체가 동일한 것임을 확인할 수 있다. 이는 스프링 컨테이너가 빈을 싱글톤 패턴으로 관리하기 때문이다.
  8. IOC (Inversion of Control, 제어의 역전): IOC는 객체의 생성과 생명주기 관리를 프레임워크나 컨테이너에게 위임하여 개발자가 직접 관리하지 않고도 객체를 사용할 수 있도록 하는 기능이다. 스프링이 IOC를 제공함으로써 개발자는 객체를 직접 생성하거나 관리하지 않고도 스프링 컨테이너에 의해 객체가 생성되고 관리되며, 필요할 때 주입받아 사용할 수 있다.
  9. 싱글톤 패턴: 스프링 컨테이너는 기본적으로 싱글톤 패턴을 이용하여 빈을 생성하고 관리한다. 따라서 동일한 ID로 빈을 조회할 때마다 항상 동일한 객체를 반환하게 된다. 이를 통해 메모리를 절약하고 객체의 일관성을 유지할 수 있다.
  10. IOC의 장점: IOC는 객체의 생성과 생명주기를 컨테이너에 위임함으로써 코드의 결합도를 낮추고 유연성을 높여준다. 또한 싱글톤 패턴을 통해 메모리를 효율적으로 사용하고 객체의 일관성을 유지할 수 있다.
  • 스프링 프레임워크를 사용할 때는 메이븐(Maven)이나 그레이들(Gradle)과 같은 의존성 관리 도구를 사용하여 스프링 라이브러리를 프로젝트에 추가하는 것이 좋다.
  • 스프링 프레임워크는 메이븐 중앙 저장소(Maven Central Repository)에 호스팅되어 있으며, 메이븐 또는 그레이들을 사용하여 스프링 라이브러리를 손쉽게 프로젝트에 추가할 수 있다.
    1. 먼저, 웹 브라우저에서 Maven Central Repository나 스프링 공식 문서에서 현재 사용하고자 하는 스프링 버전에 대한 의존성을 찾는다.
    2. 메이븐 또는 그레이들 프로젝트의 pom.xml 또는 build.gradle 파일에 해당 스프링 라이브러리에 대한 의존성을 추가한다. 이때, 버전 번호는 현재 사용하고자 하는 스프링 버전에 맞게 지정해야 한다.

    예를 들어, Spring Context 모듈에 대한 메이븐 의존성을 추가할 때는 다음과 같이 pom.xml 파일에 추가할 수 있다.

    1
    2
    3
    4
    5
    
      <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-context</artifactId>
          <version>버전번호</version> <!-- 현재 사용하는 스프링 버전에 맞게 버전 번호를 지정 -->
      </dependency>
    

    의존성을 추가한 후에는 메이븐이나 그레이들을 통해 프로젝트를 빌드하면 설정한 스프링 라이브러리가 자동으로 다운로드되어 프로젝트에 추가된다. 이러한 방식으로 개별적으로 라이브러리를 다운로드하고 lib 디렉토리에 수동으로 추가할 필요가 없다. 메이븐이나 그레이들이 모든 종속성을 관리해주기 때문에 편리하게 사용할 수 있다.

이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.