Spring XML 설정으로 Bean 구성하기

XML 기반 Bean 설정

Spring 프레임워크에서는 XML 파일을 사용하여 Bean을 구성할 수 있습니다. 먼저 리소스 디렉토리에 XML 파일을 생성하고, 사전에 Spring Context 의존성을 프로젝트에 추가해야 합니다.

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
</dependency>

XML 파일에서 Bean 설정

<?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="memberServiceImpl" class="com.example.service.impl.MemberServiceImpl"></bean>
</beans>

설정 완료 후 Java 클래스에서 Bean을 가져오는 방법은 다음과 같습니다:

public static void main(String[] args) {
    // IOC 컨테이너 생성
    ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
    // Bean 가져오기
    MemberService memberService = (MemberService) context.getBean("memberServiceImpl");
}

Bean 별칭 설정

name 속성을 활용하면 하나의 Bean에 여러 별칭을 부여할 수 있습니다.

정적 팩토리를 이용한 Bean 생성

정적 팩토리 클래스를 먼저 구현합니다:

public class ProductDaoFactory {
    public static ProductDao getProductDao() {
        return new ProductDaoImpl();
    }
}

XML 설정 파일에서 해당 정적 팩토리 메서드를 참조합니다:

<bean
    id="productDao"
    factory-method="getProductDao"
    class="com.example.factory.ProductDaoFactory"/>

FactoryBean 인터페이스를 통한 Bean 생성

public class ArticleDaoFactoryBean implements FactoryBean<ArticleDao> {
    @Override
    public ArticleDao getObject() throws Exception {
        return new ArticleDaoImpl();
    }
    
    @Override
    public Class<?> getObjectType() {
        return ArticleDao.class;
    }
}

XML 설정:

<bean id="articleDao" class="com.example.factory.ArticleDaoFactoryBean"/>

Bean 라이프사이클

컨테이너 초기화 단계:

  1. 객체 생성(메모리 할당)
  2. 생성자 실행
  3. 속성 주입(setter 수행)
  4. Bean 초기화 메서드 실행

Bean 사용 단계:

비즈니스 로직 수행

컨테이너 종료 단계:

  1. Bean 소멸 메서드 실행

Bean 소멸 시점

컨테이너가 닫히기 전에 Bean의 소멸 메서드가 실행됩니다. 컨테이너 종료 방법은 두 가지가 있습니다:

  • ConfigurableApplicationContext 인터페이스의 close() 메서드 호출
  • registerShutdownHook() 메서드를 사용하여 VM 종료 전에 컨테이너를 먼저 종료

의존성 주입 방식

Setter 주입

단순 타입과 참조 타입을 모두 지원합니다. 먼저 엔티티 클래스에서 setter 메서드를 정의합니다:

public class BoardDaoImpl implements BoardDao {
    private int connectionTimeout;
    
    public void setConnectionTimeout(int connectionTimeout) {
        this.connectionTimeout = connectionTimeout;
    }
}

XML 설정 파일에서 property 요소를 사용하여 값을 지정합니다:

<bean id="boardDao" class="com.example.dao.impl.BoardDaoImpl">
    <property name="connectionTimeout" value="300"/>
</bean>

생성자 주입

단순 타입과 참조 타입 모두 동일하게 적용됩니다.

public class BoardDaoImpl implements BoardDao {
    private String databaseName;
    private int maxConnections;
    
    public BoardDaoImpl(String databaseName, int maxConnections) {
        this.databaseName = databaseName;
        this.maxConnections = maxConnections;
    }
}

XML 설정:

<bean id="boardDao" class="com.example.dao.impl.BoardDaoImpl">
    <constructor-arg name="databaseName" value="oracle"/>
    <constructor-arg name="maxConnections" value="50"/>
</bean>

파라미터 이름 대신 타입으로 지정하여 결합도를 낮출 수 있습니다:

<bean id="boardDao" class="com.example.dao.impl.BoardDaoImpl">
    <constructor-arg type="java.lang.String" value="oracle"/>
    <constructor-arg type="int" value="50"/>
</bean>

동일한 타입의 파라미터가 여러 개인 경우 인덱스로 구분합니다:

<bean id="boardDao" class="com.example.dao.impl.BoardDaoImpl">
    <constructor-arg index="0" value="oracle"/>
    <constructor-arg index="1" value="50"/>
</bean>

자동 주입

XML 파일을 통해 자동 주입을 설정할 수 있습니다:

<bean id="boardDao" class="com.example.dao.impl.BoardDaoImpl"/>
<bean id="boardService" class="com.example.service.impl.BoardServiceImpl" autowire="byType"/>

autowire 속성을 사용하여 타입 기반으로 주입합니다.

자동 주입 특성

  • 참조 타입의 의존성 주입에만 사용되며 단순 타입에는 적용 불가
  • byType 방식 사용 시 해당 타입의 Bean이 유일해야 함(권장 방법)
  • byname 방식은 변수명과 설정이 결합되어 있어 권장하지 않음
  • 자동 주입 우선순위는 setter 주입과 생성자 주입보다 낮음

컬렉션 주입

엔티티 클래스에서 컬렉션 타입의 의존성을 선언합니다:

public class BoardDaoImpl implements BoardDao {
    private int[] numbers;
    private List<String> categories;
    private Map<String, String> config;
    private Properties settings;
    
    public void setNumbers(int[] numbers) {
        this.numbers = numbers;
    }
}

XML에서 배열 설정:

<bean id="boardDao" class="com.example.dao.impl.BoardDaoImpl">
  <property name="numbers">
       <array>
              <value>10</value>
              <value>20</value>
       </array>
     </property>  
</bean>

List 컬렉션 설정:

<bean id="boardDao" class="com.example.dao.impl.BoardDaoImpl">
  <property name="categories">
       <list>
              <value>notice</value>
              <value>free</value>
       </list>
     </property>  
</bean>

Map 컬렉션 설정:

<bean id="boardDao" class="com.example.dao.impl.BoardDaoImpl">
  <property name="config">
           <map>
                    <entry key="db" value="mysql"/>
           </map>
     </property>  
</bean>

Properties 설정:

<bean id="boardDao" class="com.example.dao.impl.BoardDaoImpl">
  <property name="settings">
         <props>
             <prop key="author">admin</prop>
         </props>
     </property>  
</bean>

외부 Properties 파일 로딩

Spring에서 외부 properties 파일을 로드하려면 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:context="http://www.springframework.org/schema/context"
      xsi:schemaLocation="http://www.springframework.org/schema/beans
                          http://www.springframework.org/schema/beans/spring-beans.xsd
                          http://www.springframework.org/schema/context
                          http://www.springframework.org/schema/context/spring-context.xsd">

properties 파일 로딩:

<context:property-placeholder location="classpath:database.properties"/>

파일 내 속성 사용:

<bean class="com.example.config.DatabaseConfig">
    <property name="driver" value="${jdbc.driver}"/>
    <property name="url" value="${jdbc.url}"/>
</bean>

여러 properties 파일 로딩:

<context:property-placeholder location="classpath:*.properties" system-properties-mode="NEVER"/>
<context:property-placeholder location="classpath*:*.properties" system-properties-mode="NEVER"/>

system-properties-mode 속성은 시스템 속성 로딩 여부를 지정합니다.

컨테이너 클래스 계층 구조

BeanFactory가 생성된 후에는 모든 Bean이 지연 로드됩니다.

태그: Spring xml-configuration bean dependency-injection ioc-container

6월 19일 00:11에 게시됨