본문 바로가기
Programming/Spring Boot

빈의 scope

by yoon9i 2024. 7. 2.

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>

'Programming > 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