본문 바로가기

JAVA/Spring

빈 설정

반응형

스프링 프레임워크 기초

정적 팩토리 메서드와 인스턴스 팩토리 메서드로 빈을 생성하는 방법

  • 스프링 컨테이너는 인수가 없는 생성자 지원 여부에 상관없이 클래스의 인스턴스를 만들고 관리할 수 있다.
  • 팩토리 클래스를 사용해 객체 인스턴스를 만드는 기존 자바 애플리케이션 있는경우, 스프링 컨테이너를 사용해 팩토리가 만든 객체를 관리할 수 있다.

정적 팩토리 메서드로 빈 초기화

public class FixedDepositDaoFactory {

    private FixedDepositDaoFactory() {}

    public static FixedDepositDao getFixedDepositDao(String daoType) {
        FixedDepositDao fixedDepositDao = null;

        if ("jdbc".equalsIgnoreCase(daoType)) {
            fixedDepositDao = new FixedDepositJdbcDao();
        }

        if ("hibernate".equalsIgnoreCase(daoType)) {
            fixedDepositDao = new FixedDepositHibernateDao();
        }

        return fixedDepositDao;
    }
}
<bean id="service" class="sample.spring.FixedDepositServiceImpl">    
    <property name="fixedDepositDao" ref="dao" />    
</bean>

<bean id="dao" class="sample.spring.FixedDepositDaoFactory" factory-method="getFixedDepositDao">
    <constructor-arg index="0" value="jdbc" />
</bean>
  • getBean("dao")를 호출하면 FixedDepositDaoFactory 클래스의 인스턴스가 아닌 getFixedDepositDao 팩토리 메서드가 생성한 FixedDepositDao 인스턴스를 반환.
  • 빈의 의존관계는 스프링 컨테이너가 빈 인스턴스를 생성하는 방법(인수가 없는 생성자를 사용하든, 정적 팩토리 메서드를 사용하든)과 관계없이 항상 같다.

인스턴스 팩토리 메서드

public class FixedDepositDaoFactory {

    public FixedDepositDaoFactory() {}

    public FixedDepositDao getFixedDepositDao(String daoType) {
        FixedDepositDao fixedDepositDao = null;

        if ("jdbc".equalsIgnoreCase(daoType)) {
            fixedDepositDao = new FixedDepositJdbcDao();
        }

        if ("hibernate".equalsIgnoreCase(daoType)) {
            fixedDepositDao = new FixedDepositHibernateDao();
        }

        return fixedDepositDao;
    }
}
<bean id="service" class="sample.spring.FixedDepositServiceImpl">    
    <property name="fixedDepositDao" ref="dao" />    
</bean>

<bean id="daoFactory" class="sample.spring.FixedDepositDaoFactory" /> 

<bean id="dao" factory-bean="daoFactory" factory-method="getFixedDepositDao">
    <constructor-arg index="0" value="jdbc" />
</bean>
  • 빈 정의는 FixedDepositDaoFactory 클래스(인스턴스 팩토리 메서드가 있는)를 일반 스프링 빈으로 정의한다.
  • 인스턴스 팩토리 메서드에 자세한 내용을 사용하는 빈은 따로 정의한다.

생성자 기반 DI

  • 세터기반 DI
  • 생성자 기반 DI

빈 스코프

  • 빈을 공유하기 위한 인스턴스를 생성.
  • 단 하나만 생성(싱글톤 스코프)
  • 요청될 때마다 새로운 빈 인스턴스 생성(프로토타입 스코프)
public class SingletonTest {
    private static ApplicationContext context;

    @BeforeClass
    public static void init() {
        context = new ClassPathXmlApplicationContext("classpath:META-INF/spring/applicationContext.xml");
    }

    @Test
    public void testInstance() {
        FixedDepositController controller1 = (FixedDepositController) context.getBean("controller");
        FixedDepositController controller2 = (FixedDepositController) context.getBean("controller");
        assertSame("Different FixedDepositController instances", controller1, controller2)
    }
}
  • 스프링 컨테이너가 ApplicationContext의 getBean 메서드를 여러번 호출해도 동일한 controller 빈을 반환

여러 스프링 컨테이너에 있는 싱글턴 스코프 빈

public class SingletonTest {
    private static ApplicationContext context;

    @BeforeClass
    public static void init() {
        context = new ClassPathXmlApplicationContext("classpath:META-INF/spring/applicationContext.xml");
    }

    @Test
    public void testInstance() {
        ApplicationContext anotherContext = new ClassPathXmlApplicationContext("classpath:META-INF/spring/applicationContext.xml");

        FixedDepositController controller1 = (FixedDepositController) context.getBean("controller");
        FixedDepositController controller2 = (FixedDepositController) anotherContext.getBean("controller");
        assertNotSame("Same FixedDepositController instances", controller1, controller2)
    }
}
  • 각 스프링 컨테이너는 자신만의 싱글턴 스코프 빈을 만든다.
  • 싱글턴 스코프 빈은 기본적으로 사전-인스턴스화 된다.
  • 즉 스프링 컨테이너가 인스턴스를 생성할 때 싱글턴 스코프의 인스턴스도 생성된다.
  • 스코프빈을 지연 생성 가능
  • 대부분의 애플리케이션 시나리오에서 문제를 발견하기 위해 싱글턴 빈을 미리 초기화하는 편이 낫다.

적합한 스코프 선택

  • 빈이 어떤 대화적 상태도 유지하지 않는다면(상태가 없는 stateless 빈) 싱글톤 스코프 빈으로 정의
  • 빈이 대화적 상태를 유지해야 한다면 프로토타입 스코프 빈으로 정의

예)

  • FixedDepositControllerImpl, FixedDepositServiceImpl, FixedDepositDaoImpl 상태가 없으므로 싱글턴 스코프 빈으로 선언
  • FixedDepositDetails(도메인 객체)은 대화적 상태를 유지로 프로토타입 스코프 빈으로 선언

 

배워서 바로 쓰는 스프링프레임워크
애시시 사린, 제이 샤르마 지음
오현석 옮김

반응형

'JAVA > Spring' 카테고리의 다른 글

빈과 빈 정의 커스텀  (0) 2021.12.26
의존관계주입  (0) 2021.12.26
IoC 컨테이너 계층 구조 - 토비의 스프링  (0) 2020.09.25
IoC 컨테이너와 DI - 토비의 스프링  (0) 2020.09.24
스프링3 XML를 이용한 설정  (0) 2018.03.19