Dependency Injection(2/2):๐ŸŒฟSpringํ™˜๊ฒฝ์—์„œ์˜ DI

Alwaysยท2024๋…„ 10์›” 17์ผ
1

Backend&Devops

๋ชฉ๋ก ๋ณด๊ธฐ
7/15

springํ™˜๊ฒฝ์—์„œ ์˜์กด๊ด€๊ณ„ ์ฃผ์ž…์€ ํฌ๊ฒŒ @Component,@ComponentScan์œผ๋กœ ๋“ฑ๋ก๋œ ๊ฐ์ฒด ๋นˆ์„ @Autowired๋ฅผ ์ด์šฉํ•ด์„œ ์ž๋™์œผ๋กœ ์ฃผ์ž…ํ•˜๋Š” ์ž๋™์ฃผ์ž…๊ณผ @Configuration๋‚ด์—์„œ @Bean์„ ๋“ฑ๋กํ•˜๋ฉด์„œ ์ฃผ์ž…ํ•˜๋Š” ์ˆ˜๋™์ฃผ์ž…์ด ์กด์žฌํ•ฉ๋‹ˆ๋‹ค.

์šฐ์„  di 1ํŽธ์—์„œ ์‚ฌ์šฉํ•œ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ฝ”๋“œ๋กœ๋ถ€ํ„ฐ ์‹œ์ž‘ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

๐Ÿ”—@Autowired

์‚ฌ์šฉ๋ฐฉ๋ฒ•

์Šคํ”„๋ง์€ @Autowired๋ฅผ ํ†ตํ•ด์„œ spring container์— ๋“ฑ๋ก๋œ ๋นˆ ๊ฐ์ฒด๋ฅผ ์ž๋™์œผ๋กœ DI ํ•ด์ค๋‹ˆ๋‹ค

  • ์œ„์˜ ์ฝ”๋“œ์ฒ˜๋Ÿผ di๋ฅผ ์ง์ ‘ ํ•ด์„œ ๊ฐ์ฒด๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ, ์•„๋ž˜์ฒ˜๋Ÿผ @Autowired๋ฅผ ํ†ตํ•ด์„œ ์Šคํ”„๋ง ๋นˆ์— ๋“ฑ๋ก๋œ ๊ฐ์ฒด์ค‘ drink.class๋ฅผ ํฌํ•จํ•œ ์ž์‹๋“ค์˜ class๋ฅผ ์ฃผ์ž…ํ•ฉ๋‹ˆ๋‹ค.

  • ๋งŒ์•ฝ ์ฃผ์ž…ํ•  ์ˆ˜ ์žˆ๋Š” ๋นˆ์ด ์—ฌ๋Ÿฌ๊ฐœ๋ผ๋ฉด
  • ์ฃผ์ž…๋ฐ›๋Š” ๋ณ€์ˆ˜๋ช…์„ ๋นˆ์˜ ์ด๋ฆ„๊ณผ ๊ฐ™๊ฒŒ ํ•˜๋ฉด spring์ด ์ด๋ฅผ ์ธ์‹ํ•˜์—ฌ ํ•ด๋‹น ๋นˆ์„ ์ฃผ์ž…ํ•ฉ๋‹ˆ๋‹ค ex)drink-> americano
  • ์•„๋‹ˆ๋ฉด @Primary ๋ฅผ ์‚ฌ์šฉํ•ด์„œ ๋นˆ ์ฃผ์ž…์˜ 1์ˆœ์œ„๋ฅผ ๋ถ€์—ฌํ•˜๊ฑฐ๋‚˜, @Qualifier("๋นˆ์ด๋ฆ„")์„ ํ†ตํ•œ mapping์œผ๋กœ ์ฃผ์ž…์„ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋™์ž‘๋ฐฉ์‹

  • ์˜์กด๊ด€๊ณ„ ์ฃผ์ž…์„ ์‚ฌ์šฉํ•˜๋ ค๋ฉด ์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ์˜ ๋นˆ์œผ๋กœ ๋“ฑ๋ก์ด ๋˜์–ด์žˆ์–ด์•ผํ•ฉ๋‹ˆ๋‹ค.
  • ๋นˆ์œผ๋กœ ๋“ฑ๋กํ•  ๋•Œ @ComponentScan์„ ํ™œ์šฉํ•ด์„œ @Component๊ฐ€ ๋ถ™์€ ํด๋ž˜์Šค๋ฅผ ์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ์— ๋“ฑ๋กํ•˜๋Š” ๋นˆ ์ž๋™ ๋“ฑ๋ก๊ณผ @Configuration์ด ๋ถ™์€ ํด๋ž˜์Šค ๋‚ด์—์„œ @Bean์„ ์ด์šฉํ•ด์„œ ์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ์— ๋“ฑ๋กํ•˜๋Š” ๋นˆ ์ˆ˜๋™ ๋“ฑ๋ก์ด ์žˆ์Šต๋‹ˆ๋‹ค.
  • @Autowired๋Š” ์ด๋ ‡๊ฒŒ ๋“ฑ๋ก๋œ ๋นˆ์„ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ˆœ์„œ๋กœ ์ฐพ์Šต๋‹ˆ๋‹ค.
1. ํƒ€์ž… ๋งค์นญ
2-1 ํƒ€์ž… ๋งค์นญ์˜ ๊ฒฐ๊ณผ๊ฐ€ 2๊ฐœ ์ด์ƒ์ผ ๋•Œ ํ•„๋“œ ๋ช…, ํŒŒ๋ผ๋ฏธํ„ฐ ๋ช…์œผ๋กœ ๋นˆ ์ด๋ฆ„ ๋งค์นญ
2-2 ํƒ€์ž… ๋งค์นญ์˜ ๊ฒฐ๊ณผ๊ฐ€ 2๊ฐœ์ด์ƒ์ด๋ฉด @Primary,@Qualifier๋ฅผ ์ฐธ์กฐ

๊ทธ๋ ‡๋‹ค๋ฉด ์™œ ๊ตณ์ด ์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ๋‚ด์—์„œ ๋นˆ์„ ๊ด€๋ฆฌํ•˜๊ณ  ๋“ฑ๋กํ•˜๋ฉด์„œ, ์ด๋ฅผ ์ฃผ์ž…ํ•˜๋Š” ๊ฑธ๊นŒ์š”?

์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ

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

์ด๋ ‡๊ฒŒ ๋™์ž‘์„ ํ•˜๊ฒŒ ๋œ๋‹ค๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋ฌธ์ œ์ ์„ ์•ผ๊ธฐํ•ฉ๋‹ˆ๋‹ค.

  1. ๊ณ ๊ฐ ํŠธ๋ž˜ํ”ฝ์ด ์ดˆ๋‹น 100์ด ๋‚˜์˜ค๋ฉด ์ดˆ๋‹น 100๊ฐœ ๊ฐ์ฒด๊ฐ€ ํž™๋ฉ”๋ชจ๋ฆฌ์— ์ƒ์„ฑ๋˜๋Š”๋ฐ, ์ด ๋•Œ ๋ฉ”๋ชจ๋ฆฌ ๋‚ญ๋น„๊ฐ€ ์‹ฌํ•˜๋‹ค.
  2. ๊ฐ์ฒด๊ฐ€ ์‚ฌ์šฉ๋œ ํ›„ ๋” ์ด์ƒ ์ฐธ์กฐ๋˜์ง€ ์•Š์œผ๋ฉด ๊ฐ€๋น„์ง€ ์ปฌ๋ ‰์…˜(GC)์ด ๋ฐœ๋™ํ•˜์—ฌ, ๊ฐ์ฒด๋ฅผ ํšŒ์ˆ˜ํ•ฉ๋‹ˆ๋‹ค. ์ด ๋•Œ์˜ ๋น„์šฉ๋˜ํ•œ ํฝ๋‹ˆ๋‹ค.

์ด๋Ÿฌํ•œ ๋ฌธ์ œ์  ๋•Œ๋ฌธ์— ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์‹ฑ๊ธ€ํ†ค ์ปจํ…Œ์ด๋„ˆ๋ฅผ ์ด์šฉํ•ด์„œ ๋นˆ์„ ๊ด€๋ฆฌํ•ฉ๋‹ˆ๋‹ค.

  • ์‹ฑ๊ธ€ํ†ค์œผ๋กœ ๋™์ž‘ํ•˜๋ฏ€๋กœ, ํ•ญ์ƒ ๋ฌด์ƒํƒœ๋ฅผ ์œ ์ง€ํ•˜๋„๋ก ๋…ธ๋ ฅํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค.
  • ์‹ฑ๊ธ€ํ†ค์— ๋Œ€ํ•ด์„œ๋Š” ๋‹ค์Œ์— ๋‹ค๋ฅธ ๊ธ€์„ ํ†ตํ•ด์„œ ๋” ์ž์„ธํžˆ ๋‹ค๋ฃจ๊ฒ ์Šต๋‹ˆ๋‹ค.

๐Ÿš @Configuration

์‚ฌ์šฉ๋ฐฉ๋ฒ•

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

๋™์ž‘๋ฐฉ์‹

  • @Configuration์˜ ๊ฒฝ์šฐ ComponentScan์ด ๋  ๋•Œ CGLIB ํ”„๋ก์‹œ ํ˜•ํƒœ๋กœ ๋นˆ์— ์ €์žฅ๋ฉ๋‹ˆ๋‹ค.
  • ์ด ์ดํ›„ @Bean์— ์žˆ๋Š” ๊ฐ์ฒด๋Š” @Configuration ํ”„๋ก์‹œ์—์„œ ๊ฐ€๋กœ์ฑ„์„œ, ๋ฐ”์ดํŠธ ์ฝ”๋“œ ์กฐ์ž‘์„ ํ†ตํ•ด์„œ ์‹ฑ๊ธ€ํ†ค์„ ๋ณด์žฅํ•ฉ๋‹ˆ๋‹ค.
  • ๋งŒ์•ฝ @Configuration์ด ์•ˆ ๋ถ™์–ด์žˆ์œผ๋ฉด ์‹ฑ๊ธ€ํ†ค์€ ๋ณด์žฅ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
  • ํ•ด๋‹น ๋นˆ์ด ์žˆ์œผ๋ฉด, ํ•ด๋‹น ๋นˆ์„ ๋ฐ˜ํ™˜ํ•˜๊ณ , ์•„๋‹ˆ๋ฉด ๋นˆ์„ ์ƒˆ๋กœ ์ƒ์„ฑ ํ›„ ๋“ฑ๋กํ•˜๋Š” ๋กœ์ง์ด ์ˆ˜ํ–‰๋  ๊ฒƒ์œผ๋กœ ์˜ˆ์ƒ

๐Ÿซ›์ˆ˜๋™ ๋นˆ ์ฃผ์ž…vs ์ž๋™ ๋นˆ ์ฃผ์ž…

@Configuration
public class RedisConfig {
    @Value("${spring.data.redis.host}")
    private String host;

    @Value("${spring.data.redis.port}")
    private int port;

    @Bean
    public RedisConnectionFactory redisConnectionFactory() {
        return new LettuceConnectionFactory(host, port);
    }

    @Bean
    public RedisTemplate<String,String> redisTemplate() {
        RedisTemplate<String,String> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(redisConnectionFactory());
        return redisTemplate;
    }
}
  • ์œ„ ์ฒ˜๋Ÿผ spring๊ณผ ๊ด€๋ จ๋œ ๊ธฐ์ˆ ์ด ์•„๋‹Œ, ์œ„์ฒ˜๋Ÿผ Redis์™€ ์—ฐ๊ฒฐํ•˜๋Š” ๊ธฐ์ˆ ๋กœ์ง์„ ํ†ตํ•ด์„œ Bean์„ ๋“ฑ๋กํ•˜๊ฑฐ๋‚˜, AOP๊ด€๋ จ ๋กœ์ง๋“ฑ์ผ ๋•Œ ์ˆ˜๋™ ๋นˆ ์ฃผ์ž…์„ ํ•˜๋Š” ๊ฒƒ์ด ํŽธํ• ๊ฒƒ์ด๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.
    • ๊ธฐ์ˆ  ์ง€์› ๋นˆ์ธ ๊ฒฝ์šฐ์—๋Š” ์œ„์ฒ˜๋Ÿผ ๋ณ€๊ฒฝ์‚ฌํ•ญ์„ ์ ์šฉํ•ด์•ผํ•˜๋ฉฐ, ๋กœ๊น…์„ ํ†ตํ•œ ๋””๋ฒ„๊น…์„ ํ•ด์•ผํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ง์ ‘ ๋“ฑ๋กํ•˜๋Š” ๊ฒƒ์ด ๋‚ซ์Šต๋‹ˆ๋‹ค.
  • ์ด๋Ÿฌํ•œ ๊ฒƒ ์ด์™ธ์—์˜ ๊ฒฝ์šฐ์—๋Š” ์ž๋™ ๋นˆ ์ฃผ์ž…์ด ํŽธํ•˜๋ฉฐ, ๋น ๋ฆ…๋‹ˆ๋‹ค.
    • spring boot๊ฐ€ ์ œ๊ณตํ•ด์ฃผ๋Š” ํŽธํ•œ ์–ด๋…ธํ…Œ์ด์…˜์ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

๊ฒฐ๋ก 

์˜ค๋Š˜์€ Spring์—์„œ ์ œ๊ณตํ•˜๋Š” DI์— ๊ด€๋ จํ•œ ๋‚ด์šฉ๋“ค์„ ํ•™์Šตํ•˜์˜€์Šต๋‹ˆ๋‹ค. ์‹ฑ๊ธ€ํ†ค ์ปจ๋ฐ์ด๋„ˆ,ํ”„๋ก์‹œ,AOP์˜ ๋‚ด์šฉ์€ ์ถ”ํ›„์— ๋ณด์™„ํ•ด์„œ ๊ธ€๋กœ ์ถ”๊ฐ€ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

profile
๐Ÿถ๊ฐœ๋ฐœ ๋ธ”๋กœ๊ทธ

0๊ฐœ์˜ ๋Œ“๊ธ€