반응형
스프링 프레임워크 기초
정적 팩토리 메서드와 인스턴스 팩토리 메서드로 빈을 생성하는 방법
- 스프링 컨테이너는 인수가 없는 생성자 지원 여부에 상관없이 클래스의 인스턴스를 만들고 관리할 수 있다.
- 팩토리 클래스를 사용해 객체 인스턴스를 만드는 기존 자바 애플리케이션 있는경우, 스프링 컨테이너를 사용해 팩토리가 만든 객체를 관리할 수 있다.
정적 팩토리 메서드로 빈 초기화
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 |