[Spring] Bean Scope

๐Ÿ”น Bean Scope

์Šคํ”„๋ง์—์„œ ๋นˆ์€ ๊ธฐ๋ณธ์ ์œผ๋กœ  ์‹ฑ๊ธ€ํ†ค ์Šค์ฝ”ํ”„๋กœ ์ƒ์„ฑ๋œ๋‹ค.

ํŠน์ • ํƒ€์ž…์˜ ๋นˆ์„ ํ•˜๋‚˜๋งŒ ๋งŒ๋“ค์–ด ๋‘๊ณ  ๊ณต์œ ํ•ด์„œ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•จ์ธ๋ฐ, ์ด๋Ÿฌํ•œ ์ด์œ ๋กœ ๋นˆ์— ์ƒํƒœ๋ฅผ ์ €์žฅํ•˜๋Š” ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๋Š” ๊ฒƒ์€ ๋™์‹œ์„ฑ ๋ฌธ์ œ๋ฅผ ์œ ๋ฐœํ•˜์—ฌ ์œ„ํ—˜ํ•œ ์ƒํ™ฉ์„ ์ดˆ๋ž˜ํ•  ์ˆ˜ ์žˆ๋‹ค.

ํ•˜์ง€๋งŒ ์š”๊ตฌ์‚ฌํ•ญ๊ณผ ๊ตฌํ˜„ ๊ธฐ๋Šฅ ๋“ฑ์˜ ํ•„์š”์— ๋”ฐ๋ผ ๋น„์‹ฑ๊ธ€ํ†ค์ด ํ•„์š”ํ•œ ๊ฒฝ์šฐ๋„ ๋งŽ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์ด๋ฅผ ๋ช…์‹œ์ ์œผ๋กœ ๊ตฌ๋ถ„ํ•˜๊ธฐ ์œ„ํ•ด Scope๋ผ๋Š” ํ‚ค์›Œ๋“œ๋ฅผ ์ œ๊ณตํ•œ๋‹ค.

 

๐Ÿ”น Scope ์ข…๋ฅ˜

1. ์‹ฑ๊ธ€ํ†ค

  • ์Šคํ”„๋ง ํ”„๋ ˆ์ž„์›Œํฌ์—์„œ ๊ธฐ๋ณธ์ด ๋˜๋Š” ์Šค์ฝ”ํ”„
  • ์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ์˜ ์‹œ์ž‘๊ณผ ์ข…๋ฃŒ๊นŒ์ง€ ํ•œ ๊ฐœ์˜ ๊ฐ์ฒด๋กœ ์œ ์ง€๋œ๋‹ค.
  • ๊ฐ€์žฅ ๋„“์€ ๋ฒ”์œ„์˜ ์Šค์ฝ”ํ”„์ด๋‹ค.

2. ํ”„๋กœํ† ํƒ€์ž…

  • ํ”„๋กœํ† ํƒ€์ž… ๋นˆ์˜ ์ƒ์„ฑ๊ณผ ์˜์กด๊ด€๊ณ„ ์ฃผ์ž…๊นŒ์ง€๋งŒ ๊ด€์—ฌํ•˜๊ณ  ๋”๋Š” ๊ด€๋ฆฌํ•˜์ง€ ์•Š๋Š” ๋งค์šฐ ์งง์€ ๋ฒ”์œ„์˜ ์Šค์ฝ”ํ”„
  • ์š”์ฒญ์ด ๋“ค์–ด์˜ค๋ฉด ํ•ญ์ƒ ์ƒˆ๋กœ์šด ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•˜์—ฌ ๋ฐ˜ํ™˜ํ•˜๊ณ  ์ดํ›„์— ๊ด€๋ฆฌํ•˜์ง€ ์•Š๋Š”๋‹ค.
  • ํ”„๋กœํ† ํƒ€์ž…์„ ๋ฐ›์€ ํด๋ผ์ด์–ธํŠธ๊ฐ€ ๊ฐ์ฒด๋ฅผ ๊ด€๋ฆฌํ•ด์•ผ ํ•œ๋‹ค.

3. ์›น

  • request : ๊ฐ๊ฐ์˜ ์š”์ฒญ์ด ๋“ค์–ด์˜ค๊ณ  ๋‚˜๊ฐˆ ๋•Œ๊นŒ์ง€ ์œ ์ง€๋˜๋Š” ์Šค์ฝ”ํ”„
  • session : ์„ธ์…˜์ด ์ƒ์„ฑ๋˜๊ณ  ์ข…๋ฃŒ๋  ๋•Œ๊นŒ์ง€ ์œ ์ง€๋˜๋Š” ์Šค์ฝ”ํ”„
  • application : ์›น์˜ ์„œ๋ธ”๋ฆฟ ์ปจํ…์ŠคํŠธ์™€ ๊ฐ™์€ ๋ฒ”์œ„๋กœ ์œ ์ง€๋˜๋Š” ์Šค์ฝ”ํ”„

 

๋นˆ ์Šค์ฝ”ํ”„๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์ด @Scope ์–ด๋…ธํ…Œ์ด์…˜์„ ํ†ตํ•ด ์ง€์ •ํ•  ์ˆ˜ ์žˆ๋‹ค.

// ์ž๋™ ๋นˆ ๋“ฑ๋ก
@Scope("prototype")
@Component
public class PrototypeBean {
   public PrototypeBean() { }
}

// ์ˆ˜๋™ ๋นˆ ๋“ฑ๋ก
@Configuration
class PrototypeBeanConfig {
    @Scope("prototype")
    @Bean
    PrototypeBean prototypeBean() {
        return new PrototypeBean();
    }
}

 

[ ์‹ฑ๊ธ€ํ†ค ์Šค์ฝ”ํ”„(Singleton Scope) ]

์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ ์‹ฑ๊ธ€ํ†ค ์Šค์ฝ”ํ”„๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.

์Šคํ”„๋ง ์Šค์ฝ”ํ”„์˜ ๋นˆ์„ ์กฐํšŒํ•˜๋ฉด ์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ๋Š” ํ•ญ์ƒ ๊ฐ™์€ ์ธ์Šคํ„ด์Šค๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

 

์Šคํ”„๋ง ์Šค์ฝ”ํ”„๋ฅผ ์„ค์ •ํ•˜๋Š” ๋ฐฉ๋ฒ•์€ Scope๋ฅผ ๋ช…์‹œ์ ์œผ๋กœ ์ง€์ •ํ•˜์ง€ ์•Š์œผ๋ฉด ๋œ๋‹ค.

// ๋ช…์‹œ์  ์ง€์ •, ๋˜๋Š” ์ง€์ •ํ•˜์ง€ ์•Š์œผ๋ฉด ์‹ฑ๊ธ€ํ†ค ์Šค์ฝ”ํ”„๋กœ ๊ด€๋ฆฌ
@Component
@Scope("singleton")
public class SingletonBean { }

@Component
public class SingletonBean { }

 

[ ํ”„๋กœํ† ํƒ€์ž… ์Šค์ฝ”ํ”„(Prototype Scope) ]

ํ”„๋กœํ† ํƒ€์ž… ์Šค์ฝ”ํ”„์˜ ๋นˆ์„ ์กฐํšŒํ•˜๋ฉด ์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ๋Š” ํ•ญ์ƒ ์ƒˆ๋กœ์šด ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•ด์„œ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

 

ํ”„๋กœํ† ํƒ€์ž…์˜ ๋นˆ์„ ์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ์— ์š”์ฒญํ•˜๋ฉด ์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ๋Š” ํ”„๋กœํ† ํƒ€์ž…์˜ ๋นˆ์„ ์ƒ์„ฑํ•˜๊ณ , ํ•„์š”ํ•œ ์˜์กด๊ด€๊ณ„๋ฅผ ์ฃผ์ž…ํ•œ๋‹ค.

์‹ฑ๊ธ€ํ†ค ๋นˆ์€ ์ปจํ…Œ์ด๋„ˆ ์ƒ์„ฑ ์‹œ์ ์— ๊ฐ™์ด ์ƒ์„ฑ๋˜๊ณ  ์ดˆ๊ธฐํ™”๋˜์ง€๋งŒ,

ํ”„๋กœํ† ํƒ€์ž… ๋นˆ์€ ์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ์—์„œ ๋นˆ์„ ์กฐํšŒํ•  ๋•Œ ์ƒ์„ฑ๋˜๊ณ  ์ดˆ๊ธฐํ™” ๋ฉ”์„œ๋“œ๋„ ์‹คํ–‰๋œ๋‹ค.

 

์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ๋Š” ํ”„๋กœํ† ํƒ€์ž… ๋นˆ์„ ์ƒ์„ฑํ•˜๊ณ , ์˜์กด ๊ด€๊ณ„ ์ฃผ์ž…, ์ดˆ๊ธฐํ™”๊นŒ์ง€๋งŒ ์ฒ˜๋ฆฌํ•œ๋‹ค.

ํด๋ผ์ด์–ธํŠธ์—๊ฒŒ ๋นˆ์„ ๋ฐ˜ํ™˜ํ•œ ์ดํ›„์—๋Š” ์ƒ์„ฑ๋œ ํ”„๋กœํ† ํƒ€์ž… ๋นˆ์„ ๊ด€๋ฆฌํ•˜์ง€ ์•Š๋Š”๋‹ค.

 

ํ”„๋กœํ† ํƒ€์ž… ๋นˆ์„ ๊ด€๋ฆฌํ•  ์ฑ…์ž„์„ ์ปจํ…Œ์ด๋„ˆ๊ฐ€ ์•„๋‹Œ ํด๋ผ์ด์–ธํŠธ๊ฐ€ ๊ฐ€์ง€๊ฒŒ ๋˜๋Š” ๊ฒƒ์ด๋‹ค.

๋”ฐ๋ผ์„œ @PreDestory์™€ ๊ฐ™์€ ์ข…๋ฃŒ ์ฝœ๋ฐฑ ๋ฉ”์„œ๋“œ๊ฐ€ ํ˜ธ์ถœ๋˜์ง€ ์•Š๋Š”๋‹ค. ๊ทธ๋ ‡๊ธฐ ๋•Œ๋ฌธ์— ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์†Œ๋ฉธ ๋ฉ”์„œ๋“œ(@PreDestory) ๊ฐ™์€ ๊ฒƒ์„ ์ž์ฒด์ ์œผ๋กœ ๊ด€๋ฆฌํ•ด ์ฃผ์–ด์•ผ ํ•œ๋‹ค.

 

๐Ÿค”  ๊ทธ๋ ‡๋‹ค๋ฉด ํ”„๋กœํ† ํƒ€์ž… ์Šค์ฝ”ํ”„๋Š” ์–ธ์ œ ์‚ฌ์šฉ๋ ๊นŒ?

1. ์ƒํƒœ๋ฅผ ๊ฐ€์ง„(Statedul) ๋นˆ ์‚ฌ์šฉ ์‹œ

์ดํ•ดํ•˜๊ธฐ ์‰ฝ๊ฒŒ ์˜จ๋ผ์ธ ์‡ผํ•‘ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ์ƒ๊ฐํ•ด ๋ณด์ž.

๊ฐ ์‚ฌ์šฉ์ž์—๊ฒŒ ์žฅ๋ฐ”๊ตฌ๋‹ˆ ์—ญํ• ์„ ํ•˜๋Š” ๋นˆ์ด ์ฃผ์–ด์ง„ ๊ฒฝ์šฐ, ํ•ด๋‹น ๋นˆ์€ ์‚ฌ์šฉ์ž๋งˆ๋‹ค ๋‹ค๋ฅธ ์ƒํƒœ์˜ ๊ตฌ๋งค ํ•ญ๋ชฉ ๋ชฉ๋ก์„ ์œ ์ง€ํ•ด์•ผ ํ•œ๋‹ค.

์—ฌ๊ธฐ์—์„œ ์‹ฑ๊ธ€ํ†ค ์Šค์ฝ”ํ”„๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค๋ฉด ๋ชจ๋“  ์‚ฌ์šฉ์ž๊ฐ€ ๊ฐ™์€ ์žฅ๋ฐ”๊ตฌ๋‹ˆ ์ธ์Šคํ„ด์Šค๋ฅผ ๊ณต์œ ํ•˜๊ฒŒ ๋˜์–ด ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋‹ค.

 

์ด๋Ÿด ๋•Œ ํ”„๋กœํ† ํƒ€์ž… ์Šค์ฝ”ํ”„๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค๋ฉด,

๊ฐ ์š”์ฒญ๋งˆ๋‹ค ์ƒˆ๋กœ์šด ์žฅ๋ฐ”๊ตฌ๋‹ˆ ์ธ์Šคํ„ด์Šค๊ฐ€ ์ƒ์„ฑ๋˜์–ด ๊ฐ ์‚ฌ์šฉ์ž์˜ ์ƒํƒœ๋ฅผ ๋…๋ฆฝ์ ์œผ๋กœ ์œ ์ง€ํ•  ์ˆ˜ ์žˆ๋‹ค.

 

2. ๋ฉ€ํ‹ฐ ์Šค๋ ˆ๋“œ ํ™˜๊ฒฝ์—์„œ ์Šค๋ ˆ๋“œ ์•ˆ์ „์„ฑ(Thread Safety) ๋ณด์žฅ ํ•„์š”์‹œ

์ดํ•ดํ•˜๊ธฐ ์‰ฝ๊ฒŒ ๊ธฐ์ˆ™์‚ฌ์—์„œ ์‚ฌ์šฉํ•˜๋Š” ๊ณต์šฉ ์ฃผ๋ฐฉ์„ ์ƒ๊ฐํ•ด ๋ณด์ž.

๊ธฐ์ˆ™์‚ฌ์—๋Š” ์—ฌ๋Ÿฌ ์‚ฌ๋žŒ์ด ์‚ด๊ณ  ์žˆ๊ณ , ๋ชจ๋‘ ํ•˜๋‚˜์˜ ๊ณต์šฉ ์ฃผ๋ฐฉ์„ ์ด์šฉํ•ด์•ผ ํ•œ๋‹ค.

์ฃผ๋ฐฉ์—๋Š” ํ•˜๋‚˜์˜ ์กฐ๋ฆฌ ๋„๊ตฌ ์„ธํŠธ๋งŒ ์žˆ์–ด, ์—ฌ๋Ÿฌ ์‚ฌ๋žŒ์ด ์š”๋ฆฌ๋ฅผ ํ•˜๋ ค๋ฉด ์ „ ์‚ฌ๋žŒ์˜ ์š”๋ฆฌ๊ฐ€ ๋๋‚  ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ ค์•ผ ํ•œ๋‹ค.

์ด๋•Œ ์‚ฌ๋žŒ๋“ค์—๊ฒŒ ๊ฐ์ž์˜ ์š”๋ฆฌ ๋„๊ตฌ ์„ธํŠธ๋ฅผ ๋‚˜๋ˆ ์ค€๋‹ค๋ฉด ์ „ ์‚ฌ๋žŒ์˜ ์š”๋ฆฌ๊ฐ€ ๋๋‚  ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ฆด ํ•„์š” ์—†์–ด ๋” ํšจ์œจ์ ์ด๋‹ค.

 

์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ ๊ฐ ์Šค๋ ˆ๋“œ(๊ธฐ์ˆ™์‚ฌ ์‚ฌ์šฉ์ž)๊ฐ€ ๋…๋ฆฝ์ ์œผ๋กœ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๋ฉด์„œ ๋นˆ์˜ ์ธ์Šคํ„ด์Šค(์š”๋ฆฌ ๋„๊ตฌ ์„ธํŠธ)๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ, ์‹ฑ๊ธ€ํ†ค ๋นˆ์„ ์‚ฌ์šฉํ•˜๋ฉด ์—ฌ๋Ÿฌ ์Šค๋ ˆ๋“œ๊ฐ€ ๋™์ผ ์ธ์Šคํ„ด์Šค๋ฅผ ๊ณต์œ ํ•˜๊ฒŒ ๋˜์–ด ์Šค๋ ˆ๋“œ ์•ˆ์ „์„ฑ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋‹ค.

 

์ด๋Ÿด ๋•Œ ํ”„๋กœํ† ํƒ€์ž… ์Šค์ฝ”ํ”„๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค๋ฉด,

๊ฐ ์Šค๋ ˆ๋“œ๋งˆ๋‹ค ์ƒˆ๋กœ์šด ๋นˆ ์ธ์Šคํ„ด์Šค๊ฐ€ ํ• ๋‹น๋˜์–ด ๋…๋ฆฝ์„ฑ์„ ๋ณด์žฅํ•˜๋ฏ€๋กœ ์ด๋Ÿฌํ•œ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋‹ค.

 

3. ๋ฆฌ์†Œ์Šค ์ง‘์•ฝ์  ์ธ์Šคํ„ด์Šค์˜ ์‚ฌ์šฉ ์ œ์–ด

์ดํ•ดํ•˜๊ธฐ ์‰ฝ๊ฒŒ ๋„์„œ๊ด€์˜ ์ฐธ๊ณ  ์„œ์ ์„ ์ƒ๊ฐํ•ด ๋ณด์ž.

๋„์„œ๊ด€์—๋Š” ๋งค์šฐ ์œ ์šฉํ•˜์ง€๋งŒ ์ œํ•œ๋œ ์ˆ˜๋Ÿ‰๋งŒ ์žˆ๋Š” ์ฐธ๊ณ  ์„œ์ ์ด ์žˆ๋‹ค.

๋งŽ์€ ์‚ฌ๋žŒ๋“ค์ด ์ด ์„œ์ ์„ ์‚ฌ์šฉํ•˜๊ณ  ์‹ถ์–ด ํ•˜์ง€๋งŒ, ๋™์‹œ์— ์—ฌ๋Ÿฌ ์‚ฌ๋žŒ์ด ์‚ฌ์šฉํ•  ๊ฒฝ์šฐ ์†์ƒ๋˜๊ฑฐ๋‚˜ ํ•„์š”ํ•  ๋•Œ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๋Š” ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋‹ค. ์ด๋Ÿฌํ•œ ๋ฌธ์ œ๋ฅผ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•ด, ๋„์„œ๊ด€์€ ์ฐธ๊ณ  ์„œ์ ์„ ํ•„์š”ํ•  ๋•Œ๋งŒ ๋Œ€์—ฌํ•˜๊ณ  ์‚ฌ์šฉ ํ›„ ๋ฐ˜ํ™˜๋ฐ›์•„ ๊ด€๋ฆฌํ•œ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ์„œ์ ์˜ ์ƒํƒœ๋ฅผ ์œ ์ง€ํ•˜๊ณ , ๊ณต์ •ํ•˜๊ฒŒ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋„๋ก ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค.

 

์Šคํ”„๋ง์—์„œ ํ”„๋กœํ† ํƒ€์ž… ์Šค์ฝ”ํ”„๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์€ ์ด๋Ÿฌํ•œ ๋„์„œ๊ด€ ๋Œ€์—ฌ ๋ฐฉ์‹๊ณผ ์œ ์‚ฌํ•˜๋‹ค.

๋ฆฌ์†Œ์Šค๊ฐ€ ๋งŽ์ด ์†Œ๋ชจ๋˜๋Š” ๋นˆ(์ฐธ๊ณ  ์„œ์ )์„ ํ•„์š”ํ•œ ์‹œ์ ์—๋งŒ ์ƒˆ๋กœ ์ƒ์„ฑํ•˜์—ฌ ์ œ๊ณตํ•œ๋‹ค. ์‚ฌ์šฉ์ด ๋๋‚œ ๋นˆ์€ ๋” ์ด์ƒ ์œ ์ง€๋˜์ง€ ์•Š๋Š”๋‹ค.

์ด๋ฅผ ํ†ตํ•ด ๋ฆฌ์†Œ์Šค ๋‚ญ๋น„๋ฅผ ์ค„์ด๊ณ  ๋นˆ์˜ ์ƒ๋ช…์ฃผ๊ธฐ๋ฅผ ํšจ๊ณผ์ ์œผ๋กœ ๊ด€๋ฆฌํ•˜์—ฌ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์„ฑ๋Šฅ์„ ์ตœ์ ํ™”ํ•  ์ˆ˜ ์žˆ๋‹ค.

 

๐Ÿ”ธ ์‹ฑ๊ธ€ํ†ค ์Šค์ฝ”ํ”„์™€ ํ”„๋กœํ† ํƒ€์ž… ์Šค์ฝ”ํ”„ ํ•จ๊ป˜ ์‚ฌ์šฉ ์‹œ ๋ฌธ์ œ์ 

์‹ฑ๊ธ€ํ†ค ์Šค์ฝ”ํ”„์™€ ํ”„๋กœํ† ํƒ€์ž… ์Šค์ฝ”ํ”„๋ฅผ ํ•จ๊ป˜ ์‚ฌ์šฉํ•  ๋•Œ ์ฃผ์˜ํ•  ์ ์ด ์žˆ๋‹ค.

์‹ฑ๊ธ€ํ†ค ์Šค์ฝ”ํ”„์˜ ๋นˆ์ด ํ”„๋กœํ† ํƒ€์ž…์˜ ๋นˆ์„ ์ฃผ์ž…๋ฐ›์œผ๋ฉด ์‹ฑ๊ธ€ํ†ค์˜ ํ”„๋กœํ† ํƒ€์ž… ๋นˆ์€ ๋งค๋ฒˆ ๋ฐ”๋€Œ์ง€ ์•Š๊ณ  ๊ฐ™์€ ๋นˆ์ด ์‚ฌ์šฉ๋œ๋‹ค.

 

์‹ฑ๊ธ€ํ†ค ๋นˆ์€ ApplicationContext(์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ)๊ฐ€ ์ฒ˜์Œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๊ตฌ๋™ํ•  ๋•Œ ๋นˆ์„ ๋งŒ๋“ค์–ด์ฃผ๊ณ ,

๋นˆ์„ ์ฃผ์ž…ํ•ด์„œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ์ข…๋ฃŒ๋  ๋•Œ๊นŒ์ง€ ๊ณ„์† ์‚ฌ์šฉ๋˜๊ธฐ ๋•Œ๋ฌธ์— ์‹ฑ๊ธ€ํ†ค ๋นˆ ์•ˆ์— ์žˆ๋Š” ํ”„๋กœํ† ํƒ€์ž… ๋นˆ๋„ ์ฒ˜์Œ ๊ทธ๋Œ€๋กœ ์‚ฌ์šฉ๋˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

 

์ •๋ฆฌํ•˜์ž๋ฉด, ์‹ฑ๊ธ€ํ†ค ๋นˆ ์•ˆ์— ํ”„๋กœํ† ํƒ€์ž… ๋นˆ์„ ์‚ฌ์šฉํ•˜๊ฒŒ ๋œ๋‹ค๋ฉด ์ผ๋ฐ˜ ๊ฐ์ฒด(๋นˆ)์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ๊ณผ ๋‹ค๋ฅผ ๊ฒƒ ์—†๋‹ค.

 

์ด์™€ ๊ฐ™์€ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•œ ๋ฐฉ๋ฒ•์œผ๋กœ๋Š” ์„ธ ๊ฐ€์ง€๊ฐ€ ์žˆ๋‹ค.

1. ํ”„๋ก์‹œ ๋ชจ๋“œ(Proxy Mode) ์ด์šฉ

// ํด๋ž˜์Šค
@Component
@Scope(value = "prototype", proxyMode = ScopedProxyMode.TARGET_CLASS)
public class PrototypeBean { }

// ์ธํ„ฐํŽ˜์ด์Šค
@Component
@Scope(value = "prototype", proxyMode = ScopedProxyMode.INTERFACES)
public interface PrototypeInterface { }

ํ”„๋กœํ† ํƒ€์ž…์œผ๋กœ ์‚ฌ์šฉํ•  ๋นˆ์˜ @Scope ์–ด๋…ธํ…Œ์ด์…˜์— proxy Mode ์†์„ฑ์„ ScopedProxyMode.TARGET_CLASS๋กœ ์„ค์ •ํ•˜์—ฌ ํ•œ๋‹ค.

๋งŒ์•ฝ ํ•ด๋‹น ๋นˆ์ด ํด๋ž˜์Šค๊ฐ€ ์•„๋‹Œ ์ธํ„ฐํŽ˜์ด์Šค๋ผ๋ฉด, ScopedProxyMode_INTERFACE๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

 

์ด ์„ค์ •์„ ์‚ฌ์šฉํ•˜๋ฉด ์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ๋Š” ํ”„๋กœํ† ํƒ€์ž… ๋นˆ์„ ์ง์ ‘ ์ฃผ์ž…ํ•˜์ง€ ์•Š๊ณ , ํ”„๋กœํ† ํƒ€์ž… ํด๋ž˜์Šค๋ฅผ ์ƒ์†๋ฐ›์€ ํ”„๋ก์‹œ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜์—ฌ ๋Œ€์‹  ์ฃผ์ž…ํ•œ๋‹ค. ์ด ํ”„๋ก์‹œ ๊ฐ์ฒด๋Š” ํ˜ธ์ถœ๋  ๋•Œ๋งˆ๋‹ค ํ”„๋กœํ† ํƒ€์ž… ๋นˆ์˜ ์ƒˆ๋กœ์šด ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•˜์—ฌ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

 

2. ObjectFactory, ObjectProvider ์‚ฌ์šฉ

๊ฐ€์žฅ ๊ฐ„๋‹จํ•œ ๋ฐฉ๋ฒ•์œผ๋กœ, ์‹ฑ๊ธ€ํ†ค ๋นˆ์ด ํ”„๋กœํ† ํƒ€์ž…์˜ ๋นˆ์„ ์‚ฌ์šฉํ•  ๋•Œ๋งˆ๋‹ค ์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ์— ์ƒˆ๋กœ ์š”์ฒญํ•˜๋Š” ๋ฐฉ์‹์ด๋‹ค.

 

โ—ฝ ObjectFactory

ObjectFactory๋Š” ์ง€์ •๋œ ๋นˆ์„ ์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ์—์„œ ์ฐพ์•„์ฃผ๋Š” ์˜์กด์„ฑ ์กฐํšŒ(Dependency Lookup, DI) ์„œ๋น„์Šค๋ฅผ ์ œ๊ณตํ•œ๋‹ค.

getObject() ๋ฉ”์„œ๋“œ๋งŒ์„ ์ œ๊ณตํ•˜๋ฉฐ, ์ด๋ฅผ ํ†ตํ•ด ๋นˆ์„ ์š”์ฒญํ•  ์ˆ˜ ์žˆ๋‹ค. ๋ณ„๋„์˜ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋‚˜ ์„ค์ •์ด ํ•„์š” ์—†์œผ๋ฉฐ, ์Šคํ”„๋ง์— ์˜์กดํ•˜๋Š” ๋ฐฉ์‹์ด๋‹ค.

 

โ—ฝ ObjectProvider

ObjectProvider๋Š” ObjectFactory์— ๋‹ค์–‘ํ•œ ํŽธ์˜ ๊ธฐ๋Šฅ(Optional, Stream ๋“ฑ)์„ ์ถ”๊ฐ€ํ•œ ์ธํ„ฐํŽ˜์ด์Šค์ด๋‹ค.

ObjectFactory์˜ ๊ธฐ๋Šฅ์„ ํ™•์žฅํ•˜์—ฌ ์ข€ ๋” ์œ ์—ฐํ•œ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•œ๋‹ค. ๋˜ํ•œ, ๋ณ„๋„์˜ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ํ•„์š” ์—†์œผ๋ฉฐ, ์Šคํ”„๋ง์— ์˜์กดํ•œ๋‹ค

 

๋‹ค์Œ ์ฝ”๋“œ๋Š” ์‹ฑ๊ธ€ํ†ค ๋นˆ์—์„œ ํ”„๋กœํ† ํƒ€์ž… ๋นˆ์„ ๋งค๋ฒˆ ์ƒˆ๋กœ ์š”์ฒญํ•˜๋Š” ๋ฐฉ์‹์ด๋‹ค.

getObect()๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด ์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ์—์„œ ํ•ด๋‹น ํ”„๋กœํ† ํƒ€์ž… ๋นˆ์„ ์ฐพ์•„ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

@Component
public class Singleton {
    @Autowired
    private ObjectProvider<PrototypeBean> prototypeBeanProvider;

    public PrototypeBean getPrototypeBean() {
        // ๋งค๋ฒˆ ์ƒˆ๋กœ์šด PrototypeBean ์ธ์Šคํ„ด์Šค๋ฅผ ๋ฐ˜ํ™˜๋ฐ›์Œ
        return prototypeBeanProvider.getObject();
    }
}

์ด ๋ฐฉ๋ฒ•์„ ์‚ฌ์šฉํ•˜๋ฉด ๋‹จ์œ„ ํ…Œ์ŠคํŠธ๋‚˜ Mock ๊ฐ์ฒด๋ฅผ ์‰ฝ๊ฒŒ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค. ์‹ค์ œ ๊ฐ์ฒด์™€ mock ๊ฐ์ฒด๋ฅผ ๊ตฌ๋ถ„ํ•˜์—ฌ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ์–ด ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ์ž‘์„ฑ์ด ์šฉ์ดํ•˜๋‹ค.

 

3. JSR-330 Provider

์ด ๋ฐฉ๋ฒ•์€ jakarta.injection.Provider๋ผ๋Š” JSR-330 ์ž๋ฐ” ํ‘œ์ค€์„ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์ด๋‹ค.

Provider๋Š” ๋นˆ์„ ์ง€์—ฐ ๋กœ๋”ฉ(lazy loading) ํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋˜๋Š” ์ž๋ฐ” ํ‘œ์ค€ ์ธํ„ฐํŽ˜์ด์Šค๋กœ, ์Šคํ”„๋ง๊ณผ ๊ฐ™์€ DI ์ปจํ…Œ์ด๋„ˆ์— ์˜์กดํ•˜์ง€ ์•Š๊ณ ๋„ ๋‹ค์–‘ํ•œ DI ์ปจํ…Œ์ด๋„ˆ์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

 

์ด ๋ฐฉ๋ฒ•์„ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” jakarta.inject ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์ถ”๊ฐ€ํ•ด์•ผ ํ•œ๋‹ค.

๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ถ”๊ฐ€ ํ›„, ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

@Component
public class Singleton {
    @Autowired
    private Provider<PrototypeBean> prototypeProvider;
    
    public PrototypeBean getPrototype() {
        // ๋งค๋ฒˆ ์ƒˆ๋กœ์šด PrototypeBean ์ธ์Šคํ„ด์Šค๋ฅผ ๋ฐ˜ํ™˜
        return prototypeProvider.get();
    }
}

Provider.get() ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด, ์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ์—์„œ ํ•ด๋‹น ํ”„๋กœํ† ํƒ€์ž… ๋นˆ์„ ์ง€์—ฐ ๋กœ๋”ฉ ๋ฐฉ์‹์œผ๋กœ ์ฐพ์•„ ๋ฐ˜ํ™˜ํ•œ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ํ•„์š”ํ•  ๋•Œ๋งˆ๋‹ค ์ƒˆ๋กœ์šด ๋นˆ์„ ์š”์ฒญํ•  ์ˆ˜ ์žˆ๋‹ค.

 

Provider๋Š” ์ง€์—ฐ ๋กœ๋”ฉ์„ ํ†ตํ•ด ํ”„๋กœํ† ํƒ€์ž… ๋นˆ์„ ํšจ์œจ์ ์œผ๋กœ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ์Šคํ”„๋ง ์™ธ ๋‹ค์–‘ํ•œ  DI ์ปจํ…Œ์ด๋„ˆ์—์„œ๋„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. ๋˜ํ•œ, ๊ธฐ๋Šฅ์ด ๋‹จ์ˆœํ•˜๊ณ  ์˜์กด์„ฑ์ด ์ ๊ธฐ ๋•Œ๋ฌธ์— ๋‹จ์œ„ ํ…Œ์ŠคํŠธ๋ฅผ ์ž‘์„ฑํ•˜๊ฑฐ๋‚˜ Mock ๊ฐ์ฒด๋ฅผ ์‰ฝ๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์–ด ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ์ž‘์„ฑ์ด ์šฉ์ดํ•˜๋‹ค.

 

[ ์›น ์Šค์ฝ”ํ”„(Web Scope) ]

์›น ์Šค์ฝ”ํ”„๋Š” ์›น ํ™˜๊ฒฝ์—์„œ๋งŒ ์ž‘๋™ํ•œ๋‹ค. ์›น ์Šค์ฝ”ํ”„๋Š” ํ”„๋กœํ† ํƒ€์ž… ์Šค์ฝ”ํ”„์™€ ๋‹ค๋ฅด๊ฒŒ ์Šคํ”„๋ง์ด ํ•ด๋‹น ์Šค์ฝ”ํ”„ ์ข…๋ฃŒ ์‹œ์ ๊นŒ์ง€ ๊ด€๋ฆฌํ•˜๋ฏ€๋กœ,  ์ข…๋ฃŒ ์‹œ์ ์— ์ข…๋ฃŒ ๋ฉ”์„œ๋“œ๊ฐ€ ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค.

 

์›น ์Šค์ฝ”ํ”„ ๋นˆ์„ ์‹ฑ๊ธ€ํ†ค ๋นˆ์— ์ฃผ์ž…ํ•˜๋ ค๊ณ  ํ•  ๊ฒฝ์šฐ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค. ๊ทธ ์ด์œ ๋Š” ์‹ฑ๊ธ€ํ†ค ๋นˆ์€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์‹คํ–‰ ์‹œ์ ์— ์ƒ์„ฑ๋˜๋ฉฐ, ์›น ์Šค์ฝ”ํ”„ ๋นˆ์€ HTTP ์š”์ฒญ ์‹œ์ ์— ์ƒ์„ฑ๋˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ๋”ฐ๋ผ์„œ ์‹ฑ๊ธ€ํ†ค ๋นˆ์ด ์ƒ์„ฑ๋  ๋•Œ๋Š” ์›น ์Šค์ฝ”ํ”„ ๋นˆ์ด ์•„์ง ์ƒ์„ฑ๋˜์ง€ ์•Š์€ ์ƒํƒœ์—ฌ์„œ ์˜์กด๊ด€๊ณ„๋ฅผ ์ฃผ์ž…ํ•  ์ˆ˜ ์—†๋‹ค.

 

์ฆ‰, ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ์‹คํ–‰๋˜์ž๋งˆ์ž ์‹ฑ๊ธ€ํ†ค ๋นˆ์€ ์ƒ์„ฑ๋˜์ง€๋งŒ, ์›น ์Šค์ฝ”ํ”„ ๋นˆ์€ HTTP ์š”์ฒญ์ด ์˜ฌ ๋•Œ ์ƒ์„ฑ๋˜๋ฏ€๋กœ ์›น ์Šค์ฝ”ํ”„ ๋นˆ์„ ์ฃผ์ž…๋ฐ›์œผ๋ ค๋Š” ์‹œ์ ์—์„œ ์Šคํ”„๋ง์—์„œ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•˜๋Š” ๊ฒƒ์ด๋‹ค.

 

์ด์™€ ๊ฐ™์€ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•œ ๋ฐฉ๋ฒ•์œผ๋กœ๋Š” ๋‘ ๊ฐ€์ง€๊ฐ€ ์žˆ๋‹ค.

1. Provider ์‚ฌ์šฉ

Provider๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด getObject() ๋˜๋Š” get() ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ์‹œ์ ๊นŒ์ง€ ์›น ์Šค์ฝ”ํ”„ ๋นˆ์˜ ์ƒ์„ฑ์„ ์ง€์—ฐ์‹œํ‚ฌ ์ˆ˜ ์žˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ์‹ฑ๊ธ€ํ†ค ๋นˆ์ด ์ƒ์„ฑ๋  ๋•Œ ์›น ์Šค์ฝ”ํ”„ ๋นˆ์ด ์•„์ง ์ƒ์„ฑ๋˜์ง€ ์•Š๋”๋ผ๋„ ํ•„์š”ํ•œ ์‹œ์ ์—๋งŒ ์›น ์Šค์ฝ”ํ”„ ๋นˆ์„ ์š”์ฒญํ•  ์ˆ˜ ์žˆ๋‹ค.

 

2. Proxy ์‚ฌ์šฉ

Proxy๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ @Scope ์–ด๋…ธํ…Œ์ด์…˜์˜ proxyMode๋ฅผ ์„ค์ •ํ•˜๋ฉด, ์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ๋Š” CGLIB๋ผ๋Š” ๋ฐ”์ดํŠธ์ฝ”๋“œ ์กฐ์ž‘ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์›น ์Šค์ฝ”ํ”„ ๋นˆ์„ ์ƒ์†๋ฐ›์€ ๊ฐ€์งœ ํ”„๋ก์‹œ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•œ๋‹ค. ์ด ํ”„๋ก์‹œ ๊ฐ์ฒด๋Š” ์‹ค์ œ ์›น ์Šค์ฝ”ํ”„ ๋นˆ์˜ ์—ญํ• ์„ ๋Œ€์‹ ํ•œ๋‹ค.

์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ์—๋Š” ํ”„๋ก์‹œ ๊ฐ์ฒด๊ฐ€ ๋“ฑ๋ก๋˜๊ณ , ์˜์กด๊ด€๊ณ„์—์„œ๋„ ํ”„๋ก์‹œ ๊ฐ์ฒด๊ฐ€ ์ฃผ์ž…๋œ๋‹ค. ์š”์ฒญ ์‹œ์ ์— ํ”„๋ก์‹œ ๊ฐ์ฒด๊ฐ€ ์‹ค์ œ ์›น ์Šค์ฝ”ํ”„ ๋นˆ์„ ํ˜ธ์ถœํ•˜์—ฌ ํ•„์š”ํ•œ ์‹œ์ ์—๋งŒ ๋นˆ์„ ์ƒ์„ฑํ•˜๊ฒŒ ๋œ๋‹ค.

 

์ด์™€ ๊ฐ™์ด, Provider์™€ Proxy๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์›น ์Šค์ฝ”ํ”„ ๋นˆ์„ ์•ˆ์ „ํ•˜๊ฒŒ ๋‹ค๋ฃฐ ์ˆ˜ ์žˆ๋‹ค. Provider๋Š” ๋นˆ์„ ์ง€์—ฐ ๋กœ๋”ฉํ•˜๋ฉฐ, Proxy๋Š” CGLIB ํ”„๋ก์‹œ๋ฅผ ํ†ตํ•ด ์›น ์Šค์ฝ”ํ”„ ๋นˆ์„ ๋Œ€์‹ ํ•˜๋Š” ๋ฐฉ์‹์ด๋‹ค. ์ด ๋ฐฉ๋ฒ•๋“ค์€ ํ”„๋กœํ† ํƒ€์ž… ๋นˆ์—์„œ ๋ฐœ์ƒํ•˜๋Š” ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๋Š” ๋ฐฉ์‹๊ณผ ์œ ์‚ฌํ•˜๋‹ค.

 

 

 

 

 

๐Ÿ“ƒ reference