티스토리 뷰

생성자를 통한 주입, 설정자(setter)를 통한 주입은 평소에도 많이 사용해오던 방식이라 익숙한데 static factory method를 이용한 spring bean 생성은 어렵다기보다 익숙하지않았다. 그래서 간략하게 정리를 해보고자 한다.


1. static factory Method

class Person {
private int age;

public static Person newInstance(int age) {
Person person = new Person();
person.age = age;

return person;
}

private Person(){}
}


Person 클래스가 있고 해당 클래스의 인스턴스를 생성하는 팩토리 메서드를 제공한다. 팩토리메서드의 사용을 강제하기위해 기본생성자는 private 으로 설정했다.


이제 이 클래스를 spring 빈으로 만들자.


xml

<bean id="person" class="Person" factory-method="newInstance">

  <constructor-arg>

    <props>

      <prop key="age">29</prop>

    </props>

  </constructor-arg>

</bean>


자바 설정시엔 그냥 팩토리 메서드를 호출해주면 된다.


2. FactoryBean Interface

class Person{
private int age;

public Person(int age){
this.age = age;
}
}


이번엔 생성자로 생성하는 Person 클래스이다. 팩토리 메서드를 Person 에다가 추가할수도있지만 스프링은 외부에서 객체를 생성하도록 하는 팩토리 인터페이스를 제공한다.


public interface FactoryBean<T> {
T getObject() throws Exception;

Class<?> getObjectType();

boolean isSingleton();
}


해당 인터페이스를 구현하는 팩토리 클래스를 만들어 Person bean 을 제공할 수 있다.


class PersonBean implements FactoryBean<Person> {
@Override
public Person getObject() throws Exception {
return new Person(29);
}

@Override
public Class<?> getObjectType() {
return Person.class;
}

@Override
public boolean isSingleton() {
return false;
}
}


직관적이지만 간략히 설명하면


* getObject() : 실제 객체 반환

* getObjectType() : 반환하는 객체의 타입 반환

* isSingleton() : 반환하는 객체가 싱글톤인지 여부


이다. 지금같은 경우 getObject() 를 호출할때마다 new 로 신규 객체를 만들기때문에 isSingleton() 메서드는 false를 반환한다.


class PersonBean implements FactoryBean<Person> {
private Person person;
private int age;

public PersonBean(int age){
this.age = age;
}

@Override
public Person getObject() throws Exception {
if(this.person == null){
this.person = new Person(this.age);
}

return this.person;
}

@Override
public Class<?> getObjectType() {
return Person.class;
}

@Override
public boolean isSingleton() {
return true;
}
}


이런식으로 싱글톤 방식으로 구현할 수도있으며 이런 경우 true를 반환하면 된다. FactoryBean 자체가 Spring bean 이므로 생성자 주입, 설정자 주입 모두 사용할 수 있다.


xml

<bean id="person" class="PersonBean">

  <constructor-arg>

    29

  </constructor-arg>

</bean>


이렇게 사용할거면 그냥 Person에다 팩토리 메서드를 구현하면 되지 뭐하러 이런 거창한 작업을 할까 생각할수도 있을것이다. 이런 경우라면 그렇게 생각하는게 맞을 수 있으나 외부에서 제공하는 클래스라면 어떨까? 외부 라이브러리의 클래스는 수정할 수 없으니 이런식으로 빈을 만드는게 유용하게 사용될 것 같다.

'Java > spring' 카테고리의 다른 글

Spring DI  (3) 2018.01.21
Spring Bean 초기화/소멸  (0) 2017.11.17
Spring Converter  (0) 2017.03.12
List, Map Spring Bean 생성  (0) 2017.02.24
intellij spring mvc 설정  (0) 2016.07.20
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/12   »
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
글 보관함