IOC컨테이너의 다양한 객체등록에 대해 좀 더 알아보자.


◆ Factory Pattern bean

팩토리 패턴이란 생성자가 private로 막혀있어 직접적으로 new를 통하여 객체를 생성하지 않고 메서드를 이용하여 객체를 생성해야하는 패턴을 말하며, 이러한 객체들을 팩토리 객체라고 한다.

  • 객체 등록은 생성자가 있어야 등록이 되기 때문에, 생성자가 막혀있는 팩토리객체의 경우 객체를 생성해주는 메서드를 factory-method옵션에 같이 등록시켜야 객체 등록이 가능해진다.

  • factory-method의 메서드이름은 괄호()를 제외한 메서드 명만 적는다.

  • factory-method에 등록시킬 메서드는 static method이어야 한다. static method가 아닌 경우 메서드 등록이 불가하다.


▶ 팩토리 객체 내에 자기 자신 객체를 생성/반환하는 메서드가 있는 경우

factory-method에 객체반환 메서드만 등록시키면 된다.

<bean id="bomb" class="spring.delta.Bomb" factory-method="create">


▶ 다른 객체에서 객체를 생성/반환 해주는경우

이러한 경우에는 객체 생성 메서드를 가지고 있는 객체를 먼저 <bean>을 이용해 등록
등록할 객체를 등록할 때 factory-bean에 객체생성 메서드를 가지고 있는 객체의 아이디 값을 적어준다. 그리고 factory-method에 해당 메서드를 적어주면 된다.
( factory-bean등록시 factory-method를 자동완성으로 볼 수 있다. )

<bean id="mf" class="spring.delta.MultiFactory"></bean>

<bean id="map" factory-bean="mf" factory-method="createMap"></bean>
<bean id="list" factory-bean="mf" factory-method="createList"></bean>

MultiFactory객체 등록 후 factory-bean에 id를 적어주게 되면, factory-method옵션의 메서드를 자동완성으로 확인할 수 있게 된다.

  • 이때 팩토리 객체의 class를 적어주어도 상관은 없지만 큰 의미는 없다.
  • factory-bean옵션을 지정하면 factory-method는 static메서드가 아니 여도 쓸 수 있다.


▶ factory-method에 인자가 필요한 경우

팩토리객체 생성메서드에서 인자가 필요한 경우에도 생성자의 인자를 설정하는 태그인 <constructor-arg>태그를 이용하면 된다.
factory-method를 등록했다면, 자동으로 <constructor-arg>태그는 팩토리객체 생성메서드의 인자설정 태그로 인식된다.

<bean id="conn" class="java.sql.DriverManager" factory-method="getConnection"
scope="prototype">
    <constructor-arg name="url"
    value="jdbc:oracle:thin:@192.168.10.80:1521:xe" />
    <constructor-arg name="user" value="root" />
    <constructor-arg name="password" value="oracle" />
</bean>


◆ 주입 시 객체 생성하기

IOC컨테이너에 객체를 등록하게 되면 불러올 때 마다 새로운 객체를 생성해서 주입 시켜 주는 것이 아닌, 컴파일 시 이미 생성된 같은 객체를 주는 것이다.
( 생성자는 여러번 호출 될 수 있지만 같은 객체이다. 단, 같은 ApplicationContext객체에서 주입된 객체라는 가정 )

  • 매번 새로운 객체를 생성하여 받는 방법
    scope옵션을 "prototype"

    으로 바꿔주어야 한다.
    ( 디폴트는 “singleton”으로 설정되어 있다. ) 즉,

  • singleton: 항상 같은 객체를 반환해줌.
  • prototype: 매번 새로운 객체를 생성해줌.
<bean id="bomb" class="spring.delta.Bomb" factory-method="create" scope="prototype">


◆ InitMethod와 DestroyMethod 설정

객체 등록 시 컴파일 시 호출되는 InitMethod와 어플리케이션 종료 시 호출되는 DestroyMethod를 설정할 수 있다.
InitMethod는 init-method옵션으로 설정하고, DestroyMethod는 destroy-method로 설정한다.

<bean id="action" class="spring.gamma.Action" scope="singleton"
init-method="postConstruct" destroy-method="preDestroy"></bean>

IOC의 객체들은 꼭 객체주입을 하지 않아도 ApplicationContext객체가 생성될 때 모든 IOC객체들이 생성되고, initMethod또한 생성된다.


◆ 객체의 필드설정

객체를 등록할 때 해당 객체가 가지고 있는 필드 값들을 설정하는 생성자가 없이도 필드 값들을 설정할 수 있다.
단, 해당 필드 값들을 설정하기 위해서는 객체에 해당 필드 값들을 세팅하는 setter메서드가 반드시 필요하다.필드 값 설정은 <property>태그를 이용하여 설정하고 사용하는 방식은 <constructor-arg>태그와 동일하다. ( 단, setter가 등록된 필드들만 설정이 가능하다. )

<bean id="t" class="java.util.Date">
    <constructor-arg name="date" type="long"> // 생성자 인자설정
        <value>0</value>
    </constructor-arg>
    // 생성자가 아닌 객체 필드값 설정
    <property name="year">
        <value>118</value>
    </property>
    <property name="month" value="3" />
    <property name="date" value="17"></property>
</bean>