By zmzizi

제가 프로젝트 진행하면서 사용하고 있는 여러 프레임워크들 가운데 Spring 이 편리함에 있어서는 최고 압권이더군요. 그래서 Spring 에서 제가 사용하고 있는 여러 기능들 중 간단하고 널리 쓰일만한 부분들을 소개해드릴까 합니다. 잘못된 것도 있을지 모르니 여러 검토 부탁드립니당... =ㅂ=;;;

Chapter 1. applicationContext.xml 등록하여 사용하기#

  1. 웹어플리케이션에서 사용할 경우
      web.xml 파일에
       <context-param>
          <param-name>contextConfigLocation</param-name>
          <param-value>/WEB-INF/classes/applicationContext.xml</param-value>
        </context-param>
        
        <listener>
          <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
        </listener>

    를 추가해주신 이후, jsp 혹은 Struts Action 에서 servletContext 를 가져와서
    WebApplicationContext wac = WebApplicationContextUtils.getRequiredWebApplicationContext(servletContext); 라고 하면, Spring 설정 파일의 내용을 가지고 있는 WebApplicationContext 를 얻을 수 있습니다.
    이후, 이 wac 에서 getBean("beanName") 하시면 해당 bean 을 얻어오실 수 있습니다.
  2. 일반 어플리케이션에서 사용할 경우
    String filePath = 프로젝트 루트로부터의 경로 (ex) conf/applicationContext.xml 등
    ApplicationContext ctx = new FileSystemXmlApplicationContext(String filePath); 로 context 를 초기화하신 이후, getBean("beanName") 하시면 해당 bean 을 얻어오실 수 있습니다.

Chapter 2. applicationContext.xml 파일 여러개 사용하기#

여러 개의 프로젝트를 통합하거나 context 를 따로 관리해야 할 필요가 있을 경우, applicationContext.xml 파일을 여러개로 만들어서 관리할 수 있습니다.
예를 들어, applicationContext_server.xml, applicationContext_client.xml, applicationContext_common.xml 이라는 세 개의 파일로 나누어 설정을 관리할 수가 있겠죠.
  1. 하나의 파일만 필요하다면,
      ApplicationContext ctx = 
            new FileSystemXmlApplicationContext("conf/applicationContext_server.xml");
  2. 2개의 파일이 필요한데,applicationContext_common.xml 파일이 부모 context 가 되고 server 와 client 가 자식 context 가 되도록 만들고 싶다면,
      ApplicationContext parent = 
         new FileSystemXmlApplicationContext("conf/applicationContext_common.xml");
      ApplicationContext server = 
         new FileSystemXmlApplicationContext("conf/applicationContext_server.xml", parent);
      ApplicationContext client = 
         new FileSystemXmlApplicationContext("conf/applicationContext_client.xml", parent);

  3. 3개의 파일을 모두 병렬적으로 연결해서 하나의 context 로 만들고 싶다면,
      String[] fileNames = new String[]{
         "conf/applicationContext_common.xml"
         "conf/applicationContext_server.xml"
         "conf/applicationContext_client.xml"};
      ApplicationContext context = new FileSystemXmlApplicationContext(fileNames);

Chapter 3. applicationContext.xml 파일 태그 사용하기#

  1. <bean> 태그
    <bean> 태그는 컨텍스트의 기본저장단위인 bean 을 생성하는 태그입니다.
    bean 태그의 속성 에는 id, class, singleton, init-method, destroy-method, factory-method, lazy-init 등이 있습니다.
    1. id : bean 태그의 이름이며, 해당 bean 에 접근하기 위한 key 입니다.
    2. class : bean 의 실제 클래스이며, 항상 full name 으로 선언되어야 합니다.
    3. singleton : true/false 값을 가지며, 해당 bean 을 singleton 으로 유지할 것인지 여부를 결정합니다. 이 속성 를 지정하지 않았을 경우의 default 값은 true 이며, false 로 지정하였을 경우, getBean() 메써드로 호출시마다 해당 bean 객체가 생성됩니다.
    4. init-method : 해당 bean 이 초기화된 이후 context 에 저장되기 직전에 호출되는 초기화 메써드의 이름입니다. init-method="init" 식으로 기술됩니다.
    5. destroy-method : 해당 bean 이 더이상 사용되지 않을때 호출되는 메써드입니다. 때문에, destroy-method="destroy" 식으로 기술됩니다.
    6. factory-method : bean 의 초기화시 생성자 호출이 아니라 특정한 메써드 호출을 통해 인스턴스를 받고자 할 때 사용되는 메써드입니다. factory-method="getInstance" 식으로 기술됩니다.
    7. lazy-init : true/false 값을 가지며, 해당 bean 이 호출되기 이전까지는 초기화될 것인지 여부를 지정합니다. 기술되지 않았을 경우의 default 값은 false 입니다.
  2. <property> 태그
    <property> 태그는 bean 태그의 하위 태그로 해당 클래스의 프라퍼티 값을 세팅해주는 역할을 합니다.
    <property> 태그에 따라 bean 에 값이 세팅되는 시점은 <bean> 태그의 클래스가 생성되고 난 이후/init-method 가 호출되기 이전 의 시점이므로, 특정한 property 의 값을 가지고 초기화를 해야 한다면 그 초기화 내용은 생성자(혹은 factory-method) 가 아니라 init-method 에서 다루어져야 합니다.
    <property>에는 name 속성이 있으며 해당 bean 의 property 와 같은 이름으로 설정되어야 하며, 반드시 해당 bean 클래스에는 property 에 대한 setter 메써드가 있어야 합니다.(만약 setter 메써드가 없다면 xml 파싱 중에 NotWritableException(??? 기억이 잘... -0-) 가 발생하게 됩니다.)
    1. 기본형
      -. value 에 해당하는 String 값을 인수로 가지는 default 생성자가 있는 경우에는 자동으로 생성 및 캐스팅 됩니다.
      -. 예를 들어, File 타입의 property logFile 이라는 프라퍼티가 있을 경우,
          <property name="logFile"><value>c:/example/test.log</value></property>
      라고 property 지정을 해주면 해당 bean 에서 logFile 이라는 이름의 File 객체가 생성됩니다.
      -. array 형의 property 일 경우
          <property name="stringArray"><value>a,b,c,d,e</value></property>
    2. 기본형의 확장
      * List 타입
          <property name="listProperty">
           <list>
            <value>a list element</value>
            <ref bean="otherBean"/>
            <ref bean="anotherBean"/>
           </list>
          </property>

      * Set 타입
          <property name="setProperty">
           <set>
            <value>a set element</value>
            <ref bean="otherBean"/>
            <ref bean="anotherBean"/>
           </set>
          </property>

      * Map 타입
          <property name="mapProperty">
           <map>
            <entry key="yup an entry">
            <value>just some string</value>
            </entry>
            <entry key="yup a ref">
            <ref bean="otherBean"/>
            </entry>
           </map>
          </property>
    3. 참조형
      * 동일한 applicationContext.xml 파일에 기술되어 있는 bean 을 참조할 경우,
          <property name="propName"><ref local="localBeanId"/></property>
      * Chapter 2. 의 2)번에서 설명했듯이, parent context 파일에 기술되어 있는 bean 을 참조할 경우,
          <property name="propName"><ref parent="parentBeanId"/></property>
      * Chapter 2. 의 3)번에서 설명했듯이, 다른 applicationContext.xml 파일이지만 동일한 컨텍스트 객체에 선언되어 있는 bean 을 참조할 경우,
          <property name="propName"><ref bean="refBeanId"/></property>

      * ref bean 이 가장 포괄적이지만, 여러 개의 context 를 사용할 경우, 중복되는 bean name 이 선언되지 않도록 주의해야 하며, ref local 이 검색해야 할 대상범위가 가장 좁기 때문에 가장 속도가 빠르지 않을까 싶습니다.
  3. <constructor-arg> 태그
    Spring 의 applicationContext.xml 에 선언된 bean 들의 초기화 방법은 특별히 지정되지 않았을 경우엔 모두 default 생성자를 호출하도록 되어 있습니다.
    하지만, chapter 3. 의 1)에서 보았듯이, factory-method 를 기술했을 경우, 해당 factory-method 를 사용하여 객체 초기화를 합니다.
    이 방법 이외에도, <constructor-arg> 를 선언하게 되면, 해당 <constructor-arg> 값을 가지는 생성자를 호출하게 됩니다.
      <bean id="exampleBean" class="eg.ExampleBean">
       <constructor-arg><ref bean="anotherExampleBean"/></constructor-arg>
       <constructor-arg><ref bean="yetAnotherBean"/></constructor-arg>
       <constructor-arg><value>1</value></constructor-arg>
      </bean>

    위와 같은 경우에는 anotherExampleBean 의 클래스, yetAnotherBean 의 클래스, 숫자(혹은 String) 타입의 3개의 인자를 넘겨받는 생성자를 호출하게 됩니다.
    그러나, 이때 세 번째와 같이 여러 타입으로 변할 수 있는 값의 경우에는 그 정의가 모호함으로 인해 오류가 날 수 있기 때문에, <constructor-arg type="int"><value>1</value></constructor-arg> 식으로 type 을 확실히 해두면 오류발생을 막을 수 있습니다.
    {저는 개인적인 귀차니즘으로 인해 해당 부분을 파싱할 때 Exception이 발생하게 되면 그때 type 지정을 합니다. 에러 안나면 걍 놔둡니다. -_ -a)

Chapter 4. 유용한 Spring 의 기능 및 팁???#

  1. 각종 설정 파일의 통합
    Spring 의 가장 유용한 점은 Business Layer 프레임워크로서 각종 다른 Layer 들의 프레임워크들과 라이브러리들을 통합시켜주는 점에 있다고 생각합니다.
    함께 많이들 사용하시는 Hibernate 의 hiberante.cfx.xml 파일도 Spring 의 applicationContext.xml 에서 통합관리가 되며, 이번 프로젝트에 사용하고 있는 스케쥴러 라이브러리인 Quartz 에서 사용하는 jobs.xml 도 spring 설정파일에서 통합관리됩니다.
    (게다가 Quartz만을 사용할 경우, 특정 규칙에 맞추어 스케쥴링 규칙에 따라 해당 메써드를 구현해줘야 하지만, spring 을 사용할 경우 기존의 클래스와 메써드를 '지정'만 하면 되기 때문에 간편해집니다.)
    때문에, Spring 을 사용하고 있다면, 자신이 사용하려는 프레임워크 혹은 라이브러리를 Spring 에서 지원하고 있는지, 혹은 내가 필요로 하는 기능 혹은 라이브러리가 Spring 지원되는 목록 중에는 없는지를 살펴보는 것이 좋다고 생각합니다.
  2. configuration.xml, custom property 파일들이여 안녕
    jakarta 프로젝트의 Configuration 프레임워크는 많은 설정 파일들을 하나로 묶어주는 역할을 해줍니다. Spring 에서도 이와 같은 역할을 할 수 있는데, 일단 Spring의 applicationContext.xml 파일 자체가 그런 역할을 합니다.
    하지만, applicationContext.xml 파일은 Spring 에 낯설은 많은 개발자들 혹은 개발과 거리가 먼 많은 운영자들이 건드리기엔 무서운 존재입니다.
    -0- 따라서, 간단하게 설정을 바꿀 필요가 있는 부분들은 작은 property 파일로 빼내어 관리를 하게 되면, applicationContext.xml 파일을 일일이 수정하는 수고를 덜 수 있게 됩니다.
      <bean id="placeholderConfig" 
         class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="location"><value>conf/props.properties</value></property>
       </bean>
    이렇게 applicationContext.xml 에 지정한 이후, conf/props.properties 파일에
       jdbc.driverClassName=com.mysql.jdbc.Driver
       jdbc.url=jdbc:mysql://localhost/test
       jdbc.username=test
       jdbc.password=test
    라고 선언된 property 를 applicationContext.xml 에서 불러와서 쓰려면,
       <bean id="myDataSource" 
            class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
            <property name="driverClassName"><value>${jdbc.driverClassName}</value></property>
            <property name="url"><value>${jdbc.url}</value></property>
            <property name="username"><value>${jdbc.username}</value></property>
            <property name="password"><value>${jdbc.password}</value></property>
        </bean>
    라고 기술하면 됩니다.(jsp 2.0 에서 쓰이는 EL이랑 똑같습니다.)
  3. 인터페이스 타입의 구현
    org.springframework.transaction.interceptor.TransactionProxyFactoryBean 를 사용한 트랜잭션 관리시 해당 bean 의 실제 구현 클래스가 될 target 클래스는 반드시 interface 타입을 구현해야만 하더군요.
    abstract class 도 안되고 반드시 interface 를 구현해야만 합니다.(interface 를 구현한 abstract 를 상속하는 것은 괜찮았습니다만... =_ =;;;) 아마도 aop 를 통해 트랜잭션 로직을 intercept 하는 것과 무슨 관련이 있을 듯 싶은데, 이 부분은 아시는 분이 설명 쫌... =ㅂ=;;;; 오바가이님원츄>_<

p.s. 위 내용은 대부분 http://www.springframework.org/downloads/EduardoIssao/Spring.pdf 에서 확인해보실 수 있습니다. Spring 을 사용하시기 전에 꼭 한 번씩들 참고하시면 좋을 듯 싶네요~

Add new attachment

Only authorized users are allowed to upload new attachments.
« This page (revision-1) was last changed on 06-Apr-2006 09:45 by UnknownAuthor