팩토리 메서드(Factory Method) 패턴

weekbelt·2022년 1월 16일
2

디자인패턴

목록 보기
2/4
post-thumbnail

Spring에서 팩토리 메소드 사용 예

스프링은 DI(Dependency Injection) 컨테이너에서 이 패턴을 사용합니다.
기본적으로 스프링은 빈 컨테이너를 빈을 생산하는 Factory로 취급합니다. 따라서 스프링 컨테이너는 다양한 형식의 설정 정보를 받아드릴 수 있게 유연하게 설계되어 있습니다.

public interface BeanFactory {

    Object getBean(String name) throws BeansException;

    <T> T getBean(String name, Class<T> requiredType) throws BeansException;

    Object getBean(String name, Object... args) throws BeansException;

    <T> T getBean(Class<T> requiredType) throws BeansException;

    <T> T getBean(Class<T> requiredType, Object... args) throws BeansException;
    
    //...
}

각각의 getBean 메서드는 팩토리 메서드입니다. 빈의 이름이나 타입이 일치하는 빈을 반환합니다.
그런 다음 Spring은 ApplicationContext 인터페이스로 BeanFactory를 확장하여 추가 기능들을 추가하여 구성합니다.

AnnotationConfigApplicationContext와 같은 ApplicationContext클래스 구현을 사용하여 BeanFactory 인터페이스에서 상속된 다양한 팩토리 메서드를 통해 빈을 만들 수 있습니다.

Application Context

첫째로 간단한 Spring 설정을 만들어 보겠습니다.

@Configuration
@ComponentScan(basePackageClasses = ApplicationConfig.class)
public class ApplicationConfig {
}

다음으로 생성자 인수를 허용하지 않는 단순 클래스 Foo를 만듭니다.

@Component
public class Foo {
    
}

그런 다음 단일 생성자 인수를 허용하는 다른 클래스인 Bar를 만듭니다.

@Component
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class Bar {
 
    private String name;
     
    public Bar(String name) {
        this.name = name;
    }
     
    // Getter ...
}

마지막으로 ApplicationContext의 AnnotationConfigApplicationContext 구현을 통해 빈을 생성합니다.

@Test
public void whenGetSimpleBean_thenReturnConstructedBean() {
    
    ApplicationContext context = new AnnotationConfigApplicationContext(ApplicationConfig.class);
    
    Foo foo = context.getBean(Foo.class);
    
    assertNotNull(foo);
}

@Test
public void whenGetPrototypeBean_thenReturnConstructedBean() {
    
    String expectedName = "Some name";
    ApplicationContext context = new AnnotationConfigApplicationContext(ApplicationConfig.class);
    
    Bar bar = context.getBean(Bar.class, expectedName);
    
    assertNotNull(bar);
    assertThat(bar.getName(), is(expectedName));
}

getBean 팩터리 메서드를 사용하여 클래스 타입으로 빈을 생성할 수 있습니다.팩터리 메서드패턴을 이용해서 외부 구성에 따라서 애플리케이션의 동작을 변경할 수 있습니다. 만약 빈 설정정보가 Java가 아닌 xml일 경우
ClassPathXmlApplicationContext와 같은 XML기반 구성 클래스로 변경할 수 있습니다.

@Test 
public void givenXmlConfiguration_whenGetPrototypeBean_thenReturnConstructedBean() { 

    String expectedName = "Some name";
    ApplicationContext context = new ClassPathXmlApplicationContext("context.xml");
 
    // Same test as before ...
}

결론적으로 ApplicationContext의 getBean()메서드를 추상메서드로 선언하여 서브클래스인 ClassPathXmlApplicationContext, AnnotationConfigApplicationContext와 같은 서브클래스에서 객체생성을 책임지도록 합니다.

참고

profile
백엔드 개발자 입니다

0개의 댓글