포스트

Day87 Java프로그래밍 기초(Spring IOC)

1. bean 태그 사용법

1) 객체생성하기

  • IoC 컨테이너는 다음 태그를 보고 설정된 정보에 따라 객체를 생성한다.
  • 같은 패키지로 여러개의 변수가 선언되면 해당 패키지명으로 getBean(변수.class)로 찾을 수 없다.

    1
    2
    
    <bean id="변수명" class="fully qualify package name"></bean>
    <bean id="변수명" class="fully qualify package name"/>
    
  • bean의 이름을 지정하는 다양한 방법이 있다.
  • bean에서 객체를 호출할 때, getBean(“id”) 또는 getBean(“Alias(name)”)로 생성 할 수 있다.
  • 별명을 알기 위해서는 getAliases(“id”)으로 알아내고, 별명이 없는 경우 Null이 반환된다.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    
    <!-- id: 빈의 이름 -->
    <bean id="c1" class="com.eomcs.spring.ioc.ex02.Car"/>
      
    <!-- id 전체가 하나의 문자열로 취급된다. 즉 "c11 c12 c13" 문자열이 객체 아이디로 사용된다.-->
    <bean id="c11 c12 c13" class="com.eomcs.spring.ioc.ex02.Car"/>
      
    <!-- name: 빈의 별명 -->
    <bean id="c2" name="c3" class="com.eomcs.spring.ioc.ex02.Car"/>
      
    <!-- id를 지정하지 않고 name만 지정하면 name이 id로 사용된다. -->
    <bean name="c4" class="com.eomcs.spring.ioc.ex02.Car"/>
      
    <!-- name 속성에 여러 개의 별명을 지정할 수 있다. -->
    <bean id="c5" name="c51 c52 c53" class="com.eomcs.spring.ioc.ex02.Car"/>
    <bean id="c6" name="c61,c62,c63" class="com.eomcs.spring.ioc.ex02.Car"/>
    <bean id="c7" name="c71;c72;c73" class="com.eomcs.spring.ioc.ex02.Car"/>
      
    <!-- name 속성에 여러 개의 별명을 입력할 때 공백, 콤마(,), 세미콜론(;)을 사용할 수 있다. 그 외에는 불가하다! -->
    <bean id="c8" name="c81:c82:c83" class="com.eomcs.spring.ioc.ex02.Car"/>
      
    <!-- id 없이 name에 여러 개의 별명을 지정할 때는 그 중에서 첫 번째 별명이 id로 사용된다. -->
    <bean name="c91 c92 c93" class="com.eomcs.spring.ioc.ex02.Car"/>
    

2) 빈 생성 정책

  • scope 속성에 빈의 생성 정책을 지정할 수 있다.
    • singleton: 한 개의 객체만 생성 (defualt)
    • prototype: getBean() 호출할 때마다 생성
    • request: (웹) 요청이 들어올 때마다 생성
    • session: (웹) 세션이 생성될 때마다 생성
    • application: (웹) 애플리케이션을 시작할 때 생성
    • websocket: (웹) 웹소켓이 연결될 때 생성
    1
    2
    3
    4
    5
    6
    7
    8
    9
    
    <bean id="변수명" class="full-Package" scope="options"/>
        
    <!-- scope 속성의 기본 값은 singleton -->
    <!-- singleton 객체는 IoC 컨테이너가 생성될 때 미리 준비된다. -->
    <bean id="c1" class="com.eomcs.spring.ioc.ex02.Car" />
    <bean id="c2" class="com.eomcs.spring.ioc.ex02.Car" scope="singleton"/>
        
    <!-- prototype 객체는 getBean()을 호출할 때 생성된다. -->
    <bean id="c3" class="com.eomcs.spring.ioc.ex02.Car" scope="prototype"/>
    

3) 익명객체 생성

  • 빈의 이름을 지정하지 않을 경우, FQName과 인덱스 번호가 객체의 이름으로 사용된다.
  • 익명 객체의 수만큼 인덱스 번호가 증가한다.
  • 첫번째 만들어진 객체만 FQNam의 별명이 붙는다.
  • Ioc컨테이너에서 객체를 생성 할 때 getBean("FQName#index")로 생성한다.

    1
    2
    3
    4
    
    <!-- 0번 익명 객체의 별명은 클래스명과 같다.-->
    <bean class="FQName"/>
    <bean class="FQName"/>
    <bean class="FQName"/>
    

2. 생성자 호출하기

1) 생성자 호출하기

  • 생성자의 파라미터 값을 주지 않으면 기본 생성자가 선택되어 호출된다.

    1
    
    <bean id="변수명" class="FQName"/>
    
  • <constructor-arg/> 태그를 사용하여 생성자를 지정할 수 있다.
  • 파라미터와 생성자의 갯수가 다양할 때는 String 타입을 우선적으로 적용한다.
  • type 옵션을 지정하면 해당 타입을 적용한다.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    
    <!--생성자 파라미터에 String과 int가 있으면, String에 우선 적용된다.-->
    <bean id="변수명" class="FQName">
      <constructor-arg>
        <value>0000</value> 
      </constructor-arg>
    </bean>
      
    <!--생성자 파라미터에 String만 있으면, String을 탐색한다.-->
    <bean id="변수명" class="FQName">
      <constructor-arg>
        <value type="int">0000</value> 
      </constructor-arg>
    </bean>
      
    <!--생성자 파라미터가 여러개면 갯수만큼 arg를 설정한다.-->
    <bean id="변수명" class="FQName">
      <constructor-arg>
        <value>0000</value>
      </constructor-arg>
      <constructor-arg>
        <value type="int">0000</value>
      </constructor-arg>
    </bean>
    

2) 생성자 파라미터 지정

  • 파라미터를 지정하는 방법은 여러가지가 있다.
  • 기본적으로 파라미터의 순서는 IoC에서 컨트롤 한다. index 옵션을 사용하여 파라미터 순서를 지정할 수 있다.
  • IoC컨테이너에서 값을 자동형변환을 적용한다. 자동형변환을 적용하지 못하면 예외가 발생한다.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    
    <!-- 생성자의 파라미터 값을 지정하는 간단한 방법 -->
    <bean id="변수명" class="FQName">
      <constructor-arg index="0" type="java.lang.String" value="StringValue"/>
      <constructor-arg index="1" type="int" value="IntegerValue"/>
    </bean>
      
    <!-- 생성자의 파라미터 값을 지정하는 간단한 방법 -->
    <!--xmlns:c="http://www.springframework.org/schema/c 를 루트 bean에 추가한다.-->
    <bean id="변수명" class="FQName" c:파라미터="StringValue" c:_0="IntegerValue">
    

3. 프로퍼티 값 지정하기

1) 셋터 호출하기

  • property로 객체의 setter의 메서드를 호출 할 수 있다.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    
    <bean name="VarName" class="FQName">
      <property name="StringVar"><value type="java.lang.String">StringValue</value></property>
      <property name="IntegerVar"><value type="int">value</value>IntegetValue</property>
    </bean>
      
    <bean name="VarName" class="FQName">
      <property name="StringVar" value="StringValue"/>
      <property name="IntegerVar" value="IntegerValue"/>
    </bean>
      
    <!-- xmlns:p="http://www.springframework.org/schema/p" 를 추가하면 태그를 사용해서 생성자를 만들수 있다.-->
    <bean name="VarName" class="FQName"
        p:StringVar="StringValue" p:IntegerVar="IntegetValue"/>
    

2) 셋터 호출 시 자동 형변환

  • type을 지정하지 않아도 class의 property를 찾아 type을 자동으로 형 변환한다.
  • 자동 형변환을 할수 없으면 예외가 발생한다.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    
    <bean name="VarName" class="FQName">
      <property name="StringVar" value="StringValue"/>
      <property name="IntegerVar" value="IntegerValue"/>
    </bean>
      
    <!-- 자동 형변환 오류 발생
    <bean name="VarName" class="FQName">
    <property name="StringVar" value="StringValue"/>
    <property name="IntegerVar" value="StringValue"/>
    </bean>
    -->
    

3) 의존객체 주입하기

  • 클래스 안에 의존객체를 주입할 수 있다.
  • 기존 value의 값을 ref로 변경한다.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    
    <bean id="RefName" class="FQName">
      <property name="StringVarName" value="StringValue"/>
      <property name="IntegerVarName" value="IntegerValue"/>
    </bean>
      
    <bean id="VarName" class="FQName">
      <property name="StringVarName" value="StringValue"/>
      <property name="IntegerVarName" value="IntegerValue"/>
      <property name="ClassVarName" ref="RefName"/>
    </bean>
    

4) 객체 주입시 생성 순서

  • 의존 객체 주입할 때 태그를 선언하는 순서를 따지지 않는다.
  • 셋터를 호출할 때 해당 객체가 없으면 즉시 해당 객체를 찾아 생성한다.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    
    <bean id="VarName" class="FQName">
      <property name="StringVarName" value="StringValue"/>
      <property name="IntegerVarName" value="IntegerValue"/>
      <!-- RefName의 객체 생성 bean을 탐색 후 객체를 생성한다. -->
      <property name="ClassVarName" ref="RefName"/>
    </bean>
      
    <bean id="RefName" class="FQName">
      <property name="StringVarName" value="StringValue"/>
      <property name="IntegerVarName" value="IntegerValue"/>
    </bean>
    

5) 객체 생성시 의존 객체 임시 생성(temp)

  • 의존 객체 주입할 때 직접 객체를 만들어 주입할 수 있다.
  • temp를 만들고 temp객체를 setter 메서드를 통해 주입 할 수 있다.
  • 프로퍼티 설정 중에 만든 객체를 다른 객체에 주입 할 수없다.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    
    <bean id="VarName" class="FQName">
      <property name="StringVarName" value="StringValue"/>
      <property name="IntegerVarName" value="IntegerValue"/>
      <property name="ref">
        <bean id="temp" class="FQName">
          <property name="StringVarName" value="StringValue"/>
          <property name="IntegetVarName" value="IntegerValue"/>
        </bean>
      </property>
    </bean>
      
    <!-- 다른 객체에 주입 할 수 없다.
    <bean id="VarName2" class="FQName">
      <property name="StringVarName" value="StringValue"/>
      <property name="IntegerVarName" value="IntegerValue"/>
      <property name="ref" ref="ref"/>
    </bean>
    -->
    

4. 다양한 타입의 의존객체 주입하기

1) 배열 프로퍼티

  • 배열 프로퍼티를 담기위해서는 arry태그를 활용해서 담을 수 있다.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    
    <bean id="VarName" class="FQName">
      <property name="arraysName">
        <array>
          <bean clss="FQName" p:var1="name" p:var2="name"/>
          <bean clss="FQName" p:var1="name" p:var2="name"/>
          <bean clss="FQName" p:var1="name" p:var2="name"/>
        </array>
      </property>
    </bean>
      
    <bean id="VarName" class="FQName">
      <property name="arraysName">
        <list>
          <bean clss="FQName" p:var1="name" p:var2="name"/>
          <bean clss="FQName" p:var1="name" p:var2="name"/>
          <bean clss="FQName" p:var1="name" p:var2="name"/>
        </list>
      </property>
    </bean>
    

2) List 프로퍼티

  • 배열 프로퍼티를 담기위해서는 arry태그를 활용해서 담을 수 있다.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    
    <bean id="VarName" class="FQName">
      <property name="arraysName">
        <array>
          <bean clss="FQName" p:var1="name" p:var2="name"/>
          <bean clss="FQName" p:var1="name" p:var2="name"/>
          <bean clss="FQName" p:var1="name" p:var2="name"/>
        </array>
      </property>
    </bean>
      
    <bean id="VarName" class="FQName">
      <property name="arraysName">
        <list>
          <bean clss="FQName" p:var1="name" p:var2="name"/>
          <bean clss="FQName" p:var1="name" p:var2="name"/>
          <bean clss="FQName" p:var1="name" p:var2="name"/>
        </list>
      </property>
    </bean>
    

3) Map 프로퍼티

  • map은 map태그로 설정하고 값은 entry태그로 설정한다.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    
    <bean id="VarName" class="FQName">
      <property name="PName">
        <!-- <entry> key value </entry> 로 설정하기 -->
        <entry>
          <key><value>key</value></key>
          <value>value</value>
        </entry>
          
        <!-- <entry key value/> 로 설정하기 -->
        <entry key="keyValue" value="Value"/>
          
        <!-- 객체 임시 생성 후 주입 -->
        <entry key="keyValue">
          <bean class="FQName" p:PropertyName="PropertyValue"/>
        </entry>
      
        <!-- 생성된 객체 주입 -->
        <entry key="keyValue" value-ref="refName"/>
      </property>
    </bean>
    

4) Properties 프로퍼티

  • Properties의 값은 String의 key와 value값을 가진다.

    1
    2
    3
    4
    5
    6
    7
    8
    
    <bean id="VarName" class="FQName">
      <property name="propertyName">
        <props>
          <prop key="StringValue">String</prop>
          <prop key="StringValue">String</prop>
        </props>
      </property>
    </bean>
    

5. 팩토리 메서드를 통해 객체 만들기

1) 스태틱 메서드

  • factory-method을 사용하여 Factory를 설정한다.
  • bean의 id는 Factory결과 리턴되는 객체이다.

    1
    2
    3
    
    <bean id="result" class="Factory" factory-method="Factory.methodName">
      <constructor-arg value="parameter"/>
    </bean>
    

2) 스태틱 매서드의 활용 예

  • java.sql.Date을 bean factory를 통해 객체를 만들 수 있다.

    1
    2
    3
    
    <bean id="date" class="java.sql.Date" factory-method="valueOf">
      <constructor-arg value="2024-03-11"/>
    </bean>
    

3) 인스턴스 매서드

  • 인스턴스 매서드는 factory 객체를 먼저 만들고 factory객체에 파라미터를 넘겨 새로운 객체를 만든다.

    1
    2
    3
    4
    5
    
    <bean id="Factory" class="factoryClass"/>
      
    <bean id="returnName" factory-bean="Factory" factory-method="FactoryCreateMethod">
      <constructor-arg value="parameter"/>
    </bean>
    

4) 스프링 팩토리 매서드

  • 스프링 IoC컨테이너가 정한 규칙에 따라 클래스를 생성하면 Bean의 설정이 용이하다.
  • FactoryBean의 Override를 통해 객체 정보와 클래스명을 리턴한다.
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    
    public class FactoryClass implements FactoryBean<?>{
      @Override
      public Car getObject() throws Exception {
        //Object를 리턴한다.
      }
      
      @Override
      public Class<?> getObjectType() {
        //Object의 class타입을 리턴한다.
      }
    }
    
  • xml의 설정에서는 id는 factory에 생성한 객체의 변수명이다.
  • FactoryClass에 varName에 value를 넘긴다.
  • FactoryClass에서 오버라이딩된 getObject를 통해 returnName의 객체를 넘긴다.

    1
    2
    3
    
    <bean id="returnName" class="FactoryClass">
      <property name="varName" value="value"/>
    </bean>
    
이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.