[Spring Framework] Spring Bean Scope 완벽 가이드 | Singleton부터 Prototype까지
[Spring Framework] Spring Bean Scope 완벽 가이드 | Singleton부터 Prototype까지
[Spring Framework] Spring Framework에서 @Inject 애너테이션 완벽 가이드 [Spring Framework] Spring Framework에서 @Inject 애너테이션 완벽 가이드[Spring Framework] Spring Boot DI 완벽 정리 | @Resource 활용법 [Spring Framework] Sp
crushed-taro.tistory.com
1. Bean
1. init, destroy method
스프링 빈은 초기화(init)와 소멸화(destroy)의 라이프 사이클을 가지고 있다. 이 라이프 사이클을 이해하면 빈 객체가 생성되고 소멸될 때 추가적인 작업을 수행할 수 있다.
init-method 속성을 사용하면 스프링이 빈 객체를 생성한 다음 초기화 작업을 수행할 메소드를 지정할 수 있다. 이 메소드는 빈 객체 생성자가 완료된 이후에 호출된다. init-method 속성으로 지정된 메소드는 일반적으로 빈의 초기화를 위해 사용된다.
destroy-method 속성을 사용하면 빈 객체가 소멸될 때 호출할 메소드를 지정할 수 있다. 이 메소드는 ApplicationContext의 close() 메소드가 호출되기 전에 빈 객체가 소멸될 때 호출된다. destroy-method 속성으로 지정 된 메소드는 일반적으로 사용하던 리소스를 반환하기 위해 사용된다.
1. java
java 설정 방식으로init-method, destroy-method 를 테스트 하기 위해 Owner라는 클래스를 추가한다.
public class Owner {
public void openShop() {
System.out.println("사장님이 가게 문을 열었습니다. 이제 쇼핑을 하실 수 있습니다.");
}
public void closeShop() {
System.out.println("사장님이 가게 문을 닫았습니다. 이제 쇼핑을 하실 수 없습니다.");
}
}
Owner 타입의 빈 객체를 설정 파일에 등록한다. @Bean 어노테이션에는 initMethod, destoryMethod 라는 속성이 있는데 해당 속성을 Owner 클래스에 정의했던 openShop, closeShop메소드로 설정한다.
@Configuration
public class ContextConfiguration {
...생략
/* init-method로 openShop 메소드를 설정하고 destory-method로 closeShope 메소드를 설정한다. */
@Bean(initMethod = "openShop", destroyMethod="closeShop")
public Owner owner() {
return new Owner()
}
}
실행 파일에서 빈 설정 파일을 기반으로 IoC 컨테이너를 생성하고 쇼핑 카트에 상품을 담는 동일한 코드의 끝에 컨테이너를 종료하는 코드를 추가하여 실행해본다.
/* 빈 설정 파일을 기반으로 IoC 컨테이너 생성 */
ApplicationContext context = new AnnotationConfigApplicationContext(ContextConfiguration.class);
...생략
/* init 메소드는 빈 객체 생성 시점에 동작하므로 바로 확인할 수 있지만
* destroy 메소드는 빈 객체 소멸 시점에 동작하므로 컨테이너가 종료 되지 않을 경우 확인할 수 없다.
* 가비지 컬렉터가 해당 빈을 메모리에서 지울 때 destroy 메소드가 동작하게 되는데
* 메모리에서 지우기 전에 프로세스는 종료되기 때문이다.
* 따라서 아래와 같이 강제로 컨테이너를 종료시키면 destroy 메소드가 동작할 것이다.
* */
((AnnotationConfigApplicationContext) context).close();
/*
사장님이 가게 문을 열었습니다. 이제 쇼핑을 하실 수 있습니다.
cart1에 담긴 내용 : [붕어빵 1000 Thu Jun 08 21:58:53 KST 2023, 딸기우유 1500 500]
cart2에 담긴 내용 : [지리산암반수 3000 500]
사장님이 가게 문을 닫았습니다. 이제 쇼핑을 하실 수 없습니다.
*/
openShop 메소드가 Owner 객체의 생성 시점에 호출 되고, closeShop 메소드가 Owner객체의 소멸 시점에 호출 되었음을 확인할 수 있다. init 메소드는 빈 객체 생성 시점에 동작하므로 바로 확인할 수 있지만 destroy 메소드는 빈 객체 소멸 시점에 동작하므로 컨테이너가 종료 되지 않을 경우 확인할 수 없다. 따라서 컨테이너를 종료시키면 destroy 메소드의 동작까지 확인 할 수 있다.
2. annotation
annotation 방식으로init-method,destroy-method를 테스트 하기 위해Owner라는 클래스를 추가한다.
@Component
public class Owner {
/* init-method와 같은 설정 어노테이션이다. */
@PostConstruct
public void openShop() {
System.out.println("사장님이 가게 문을 오픈하셨습니다. 이제 쇼핑을 하실 수 있습니다.");
}
/* destroy-method와 같은 설정 어노테이션이다. */
@PreDestroy
public void closeShop() {
System.out.println("사장님이 가게 문을 닫으셨습니다. 이제 쇼핑을 하실 수 없습니다.");
}
}
컴포넌트 스캔을 통해 빈 등록 하기 위해 @Componet 어노테이션을 클래스 위에 설정한다. javax.annotation의 @PostConstruct , @PreDestroy 어노테이션은 @Bean 어노테이션에 init-method, destroy-method 속성을 설정하는 것과 같은 역할을 한다. 단, 해당 어노테이션을 사용할 수 있도록 라이브러리 의존성이 build.gradle.kts파일에 추가 되어 있어야 한다.
dependencies {
...생략
implementation("javax.annotation:javax.annotation-api:1.3.2")
}
Owner타입의 빈 객체를 컴포넌트 스캔을 통해 읽어 등록할 수 있도록 빈 설정 파일에 컴포넌트 스캔 경로를 설정한다. 그 외의 상품과 쇼핑 카트의 빈 등록 코드는 그대로 사용한다.
@Configuration
@ComponentScan("project.initdestroy.subsection02.annotation")
public class ContextConfiguration {
...생략
}
실행 파일에서 빈 설정 파일을 기반으로 IoC 컨테이너를 생성하고 쇼핑 카트에 상품을 담는 동일한 코드의 끝에 컨테이너를 종료하는 코드를 추가하여 실행해본다.
/* 빈 설정 파일을 기반으로 IoC 컨테이너 생성 */
ApplicationContext context = new AnnotationConfigApplicationContext(ContextConfiguration.class);
...생략
/* init 메소드는 빈 객체 생성 시점에 동작하므로 바로 확인할 수 있지만
* destroy 메소드는 빈 객체 소멸 시점에 동작하므로 컨테이너가 종료 되지 않을 경우 확인할 수 없다.
* 가비지 컬렉터가 해당 빈을 메모리에서 지울 때 destroy 메소드가 동작하게 되는데 메모리에서 지우기 전에 프로세스는 종료되기 때문이다.
* 따라서 아래와 같이 강제로 컨테이너를 종료시키면 destroy 메소드가 동작할 것이다.
* */
((AnnotationConfigApplicationContext) context).close();
/*
사장님이 가게 문을 열었습니다. 이제 쇼핑을 하실 수 있습니다.
cart1에 담긴 내용 : [붕어빵 1000 Thu Jun 08 21:59:07 KST 2023, 딸기우유 1500 500]
cart2에 담긴 내용 : [지리산암반수 3000 500]
사장님이 가게 문을 닫았습니다. 이제 쇼핑을 하실 수 없습니다.
*/
openShop 메소드가 Owner 객체의 생성 시점에 호출 되고, closeShop 메소드가 Owner 객체의 소멸 시점에 호출 되었음을 확인할 수 있다.
3. xml
xml 설정 방식으로init-method, destroy-method 를 테스트 하기 위해 Owner라는 클래스를 추가한다.
public class Owner {
public void openShop() {
System.out.println("사장님이 가게 문을 열었습니다. 이제 쇼핑을 하실 수 있습니다.");
}
public void closeShop() {
System.out.println("사장님이 가게 문을 닫았습니다. 이제 쇼핑을 하실 수 없습니다.");
}
}
bean configuration file에<bean> 태그를 통해 상품, 쇼핑카트 그리고 Owener 에 대한 빈 등록을 설정한다.Owener 에는 init-method, destroy-method를 설정한다.
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="carpBread" class="project.common.Bread">
<constructor-arg name="name" value="붕어빵"/>
<constructor-arg name="price" value="1000"/>
<constructor-arg name="bakedDate" ref="today"/>
</bean>
<bean id="today" class="java.util.Date" scope="prototype"/>
<bean id="milk" class="project.common.Beverage">
<constructor-arg name="name" value="딸기우유"/>
<constructor-arg name="price" value="1500"/>
<constructor-arg name="capacity" value="500"/>
</bean>
<bean id="water" class="project.common.Beverage">
<constructor-arg name="name" value="지리산암반수"/>
<constructor-arg name="price" value="3000"/>
<constructor-arg name="capacity" value="500"/>
</bean>
<bean id="cart" class="project.common.ShoppingCart" scope="prototype"/>
<bean id="owner" class="project.section02.initdestroy.subsection03.xml.Owner"
init-method="openShop" destroy-method="closeShop"/>
</beans>
실행 파일에서 빈 설정 파일을 기반으로 IoC 컨테이너를 생성하고 쇼핑 카트에 상품을 담는 동일한 코드의 끝에 컨테이너를 종료하는 코드를 추가하여 실행해본다.
/* 빈 설정 파일을 기반으로 IoC 컨테이너 생성 */
ApplicationContext context
= new GenericXmlApplicationContext("section02/initdestroy/subsection03/xml/spring-context.xml");
...생략
/* init 메소드는 빈 객체 생성 시점에 동작하므로 바로 확인할 수 있지만
* destroy 메소드는 빈 객체 소멸 시점에 동작하므로 컨테이너가 종료 되지 않을 경우 확인할 수 없다.
* 가비지 컬렉터가 해당 빈을 메모리에서 지울 때 destroy 메소드가 동작하게 되는데
* 메모리에서 지우기 전에 프로세스는 종료되기 때문이다.
* 따라서 아래와 같이 강제로 컨테이너를 종료시키면 destroy 메소드가 동작할 것이다.
* */
((GenericXmlApplicationContext) context).close();
/*
사장님이 가게 문을 열었습니다. 이제 쇼핑을 하실 수 있습니다.
cart1에 담긴 내용 : [붕어빵 1000 Thu Jun 08 22:00:09 KST 2023, 딸기우유 1500 500]
cart2에 담긴 내용 : [지리산암반수 3000 500]
사장님이 가게 문을 닫았습니다. 이제 쇼핑을 하실 수 없습니다.
*/
openShop 메소드가 Owner 객체의 생성 시점에 호출 되고, closeShop 메소드가 Owner 객체의 소멸 시점에 호출 되었음을 확인할 수 있다.
'Java > Spring Framework' 카테고리의 다른 글
[Spring Framework] [Spring AOP] 종류와 특징 총정리 – 입문자를 위한 기초 가이드 (0) | 2025.06.25 |
---|---|
[Spring Framework] 초보자를 위한 Spring Bean Properties 가이드 (0) | 2025.06.23 |
[Spring Framework] Spring Bean Scope 완벽 가이드 | Singleton부터 Prototype까지 (0) | 2025.06.17 |
[Spring Framework] Spring Framework에서 @Inject 애너테이션 완벽 가이드 (1) | 2025.06.16 |
[Spring Framework] Spring Boot DI 완벽 정리 | @Resource 활용법 (1) | 2025.06.15 |