9. 빈의 scope
1> 개념
빈 생성후에 ctx.getBean() 를 여러번 헀을때 반환되는 빈의 스코프를 의미한다.
기본적으로 bean은 한번만 생성되고 getBean() 을 여러번 했을때 동일한 인스턴스를 반환한다.(싱글톤)
ex>
DeptServiceImpl s = ctx.getBean("xxx", DeptServiceImpl.class);
DeptServiceImpl s2 = ctx.getBean("xxx", DeptServiceImpl.class);
2> scope 값 종류
@Scope(value=상수값)
ex>
@Scope(value = ConfigurableBeanFactory.SCOPE_SINGLETON) // 기본
@Scope("singleton")
@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
@Scope("prototype")
- singleton (기본, 단 하나의 빈으로 서비스, thread-unsafe)
- prototype (getBean 할떄마다 매번 생성해서 서비스, thread-safe)
- request (web 사용가능. 요청~응답 사이에서만 사용가능.)
- session (web 사용가능. 기본적으로 web브라우저가 open 되어있는 동안 사용 가능.)
- application (web 사용가능. 기본적으로 Tomcat컨테이너가 start 되어있는 동안 사용 가능.)
package com.exam;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;
import com.exam.service.NormalBean;
import com.exam.service.PrototypeBean;
@SpringBootApplication
public class Application implements CommandLineRunner{
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
//IoC Container 참조
Logger logger = LoggerFactory.getLogger(getClass());
// IoC Container
@Autowired // 생성자주입 대신에 사용가능.
ApplicationContext ctx;
// 생성자 주입
public Application(ApplicationContext ctx) {
logger.info("logger:ApplicationContext:{}","Application 생성");
this.ctx = ctx;
}
@Override
public void run(String... args) throws Exception {
logger.info("logger:ApplicationContext:{}",ctx);
NormalBean n1 = ctx.getBean("normalBean", NormalBean.class);
NormalBean n2 = ctx.getBean("normalBean", NormalBean.class);
// n1 이 num 수정
n1.num = 20;
logger.info("logger:NormalBean:{}",n1);
logger.info("logger:NormalBean:{}",n2);
logger.info("logger:NormalBean:{}",n1 == n2); // true
logger.info("logger:n1.num:{}, n2.num:{}",n1.num, n2.num); // n1 & n2 변경됨
// >>> 20 20
//////////////////////////////////////////////////////////////
PrototypeBean p1 = ctx.getBean("prototypeBean", PrototypeBean.class);
PrototypeBean p2 = ctx.getBean("prototypeBean", PrototypeBean.class);
logger.info("logger:PrototypeBean:{}",p1 == p2); // false
// p1 이 num 수정
p1.num = 20;
logger.info("logger:p1.num:{}, p2.num:{}",p1.num, p2.num); // p1 만 변경됨(각자변경)
// >>> 20 10
}
}
package com.exam.service;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
//@Service 사용해도 괜챃음.
@Component
//@Scope("singleton")
@Scope(value = ConfigurableBeanFactory.SCOPE_SINGLETON)
public class NormalBean {
Logger logger = LoggerFactory.getLogger(getClass());
public int num = 10; // thread-unsafe 함
public NormalBean() {
logger.info("logger:{}", "NormalBean 생성");
}
}
package com.exam.service;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
//@Service 사용해도 괜챃음.
@Component
//@Scope("prototype")
@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class PrototypeBean {
Logger logger = LoggerFactory.getLogger(getClass());
public int num = 10; // thread-unsafe 함
public PrototypeBean() {
logger.info("logger:{}", "PrototypeBean 생성");
}
}
# application.properties
logging.level.org.springframework=info
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.18</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.exam</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>demo</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>11</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
'[study]이론정리 > Spring Boot' 카테고리의 다른 글
프로파일(Profile) (0) | 2024.07.02 |
---|---|
초기화 및 cleanup 작업 처리(@PostConstruct & @PreDestroy) (0) | 2024.07.02 |
생성된 빈 접근방법 (0) | 2024.07.02 |
의존성 설정 (0) | 2024.07.02 |
빈(Bean) 생성 (0) | 2024.07.02 |