티스토리 뷰

Spring/Spring Framework

FactoryBean이란?

wavid 2020. 11. 3. 02:52

스프링은 지정된 클래스 이름을 가지고 리플렉션을 이용해서 해당 클래스의 오브젝트를 만듦. 클래스의 이름을 갖고 있다면 다음과 같은 방법으로 새로운 오브젝트를 생성할 수 있음.

Date now = (Date) Class.forName("java.util.Date").newInstance();

스프링은 내부적으로 리플렉션 API를 이용해서 빈 정의에 나오는 클래스 이름을 가지고 빈 오브젝트를 생성함. 그러나 다이나믹 프록시 오브젝트는 위와 같이 일반적인 스프링의 빈으로는 등록할 방법이 없음.

스프링은 클래스 정보를 가지고 디폴트 생성자를 통해 오브젝트를 만드는 방법 외에도 빈을 만들 수 있는 여러 가지 방법을 제공함. 

=> 대표적으로 팩토리 빈을 이용한 생성 방법.

팩토리 빈을 만드는 방법에서 가장 간단한 방법은 스프링의 FactoryBean이라는 인터페이스를 구현하는 것.

FactoryBean 인터페이스를 구현한 클래스를 스프링의 빈으로 등록하면 팩토리 빈으로 동작함.

public class Message {
	private String text;

	private Message(String text) {
		this.text = text;
	}

	public String getText() {
		return text;
	}

	public static Message newMessage(String text) {
		return new Message(text);
	}
}

위와 같은 Message 클래스는 생성자를 통해 오브젝트를 만들 수 없고, 반드시 스태틱 메소드를 사용해서 오브젝트를 만들어야 함. 이 클래스를 직접 스프링 빈으로 등록해서 사용할 수 없음. (사실 스프링은 private 생성자를 가진 클래스도 빈으로 등록해주면 리플렉션을 이용해 오브젝트를 만들어 줌. 그러나 private으로 막아둔 이유가 다 있을 것이기 때문에 권장 X)

import org.springframework.beans.factory.FactoryBean;

public class MessageFactoryBean implements FactoryBean<Message> {

	// 오브젝트를 생성할 때 필요한 정보를 팩토리 빈의 프로퍼티로 설정해서 대신 DI 받을 수 있게 함.
	private String text;

	public void setText(String text) {
		this.text = text;
	}

	// 실제 빈으로 사용될 오브젝트를 직접 생성함.
	@Override
	public Message getObject() throws Exception {
		return Message.newMessage(this.text);
	}

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

	// getObject() 메소드가 돌려주는 오브젝트가 싱글톤인지 알려줌.
	// 매번 요청할 때마다 새로운 오브젝트를 만들기 위해 false
	// 이것은 팩토리 빈의 동작방식에 관한 설정이고, 만들어진 빈 오브젝트는 싱글톤으로 스프링이 관리해줄 수 있음.
	@Override
	public boolean isSingleton() {
		return false;
	}
}

Message 클래스의 오브젝트를 생성해주는 팩토리 빈 클래스를 만듦.

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class AppConfiguration {
	@Bean(name = "message")
	public MessageFactoryBean messageFactory() {
		MessageFactoryBean factory = new MessageFactoryBean();
		factory.setText("이것은 팩토리 빈 테스트입니다.");
		return factory;
	}
}

위와 같이 빈 설정을 해준 뒤, 빈으로 잘 등록되었는지 ApplicationContext에서 getBean을 해서 text를 출력하도록 함.

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;

@Component
public class AppRunner implements ApplicationRunner {
    @Autowired
    ApplicationContext ctx;

    @Override
    public void run(ApplicationArguments args) {
        Message message = (Message)ctx.getBean("message");
        System.out.println(message.getText());
    }
}

위와 같이 로그가 정상적으로 찍히는 것을 확인할 수 있음.

 

[참고] 토비의 스프링 3.1

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/09   »
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
글 보관함