๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
Today I Learned(TIL)/์ˆ˜์ค€๋ณ„ ํ•™์Šต๋ฐ˜

์ˆ˜์ค€๋ณ„ ํ•™์Šต๋ฐ˜_๋ฒ ์ด์ง๋ฐ˜ 1ํšŒ์ฐจ ์„ธ์…˜

by carrot0911 2024. 12. 7.

๋ฒ ์ด์ง๋ฐ˜

์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ, ์ปดํฌ๋„ŒํŠธ ์Šค์บ”, ์Šคํ”„๋ง ๋นˆ

 

์ค‘์š” ํ‚ค์›Œ๋“œโญ๏ธโญ๏ธโญ๏ธโญ๏ธโญ๏ธ - ๋ฉด์ ‘์— ๋‚˜์˜ค๋Š” ๋‚ด์šฉ๋“ค

  • ์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ
  • ์˜์กด์„ฑ ์ฃผ์ž…
  • ์ œ์–ด์˜ ์—ญ์ „
  • ์ปดํฌ๋„ŒํŠธ ์Šค์บ”
  • ์Šคํ”„๋ง ๋นˆ
  • ๋นˆ์˜ ์ƒ์• ์ฃผ๊ธฐ
  • ๋นˆ ์Šค์ฝ”ํ”„
  • ์‹ฑ๊ธ€ํ†ค

 

์Šคํ”„๋ง ์š”์ฒญ ํ๋ฆ„๋„

 

@RestController
@RequestMapping("/hello")
public class HelloController {

    @GetMapping()
    public String sayHello() {
        return "hello";
    }
}
  • ์•„๋ž˜ ์ž‘์—…์€ ๋ˆ„๊ฐ€ ํ–ˆ์„๊นŒ?!
    • ์ „๋ถ€ ์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ๊ฐ€ ํ•ด์ค€๋‹ค!!
HelloController helloController = new HelloController();
helloController.sayHello();

 

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

์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ๋ฅผ ํ†ตํ•ด์„œ IoC๋ฅผ ๊ตฌํ˜„ํ•˜๊ณ  ์žˆ๋‹ค.
๊ฐ์ฒด๋“ค์„ ๊ต‰์žฅํžˆ ๋งŽ์ด ๋งŒ๋“ค์–ด๋†“์€ ๋‹ค์Œ์— ์‚ฌ์šฉํ•  ๊ฐ์ฒด๋“ค์„ ๋ฏธ๋ฆฌ ๋งˆํ‚นํ•ด๋†“์œผ๋ฉด play ๋ฒ„ํŠผ์„ ๋ˆ„๋ฅด๋Š” ์ˆœ๊ฐ„ ๋งˆํ‚น๋œ ๊ฐ์ฒด๋ฅผ ๋นˆ์œผ๋กœ ์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ์— ๋“ฑ๋กํ•œ๋‹ค.

์ œ์–ด์˜ ์—ญ์ „

ํ”„๋กœ๊ทธ๋žจ ์‹คํ–‰ ํ๋ฆ„์˜ ์ œ์–ด๊ถŒ์„ ์™ธ๋ถ€๋กœ ๋„˜๊ฒจ์ฃผ๋Š” ๊ฒƒ์ด๋‹ค!
์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์‹œ์ž‘ ์‹œ ํ•„์š”ํ•œ ๊ฐ์ฒด๋ฅผ ๋นˆ์œผ๋กœ ์ปจํ…Œ์ด๋„ˆ์— ๋“ฑ๋กํ•˜๊ณ  ์„œ๋ฒ„๋กœ ์š”์ฒญ์ด ๋“ค์–ด์˜ค๋ฉด ํ•ด๋‹น ์š”์ฒญ ์ฒ˜๋ฆฌ์— ํ•„์š”ํ•œ ๋นˆ์„ ํ™œ์šฉํ•ด์„œ ์š”์ฒญ์„ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค.

๋“ฑ๋ก๋œ ๋นˆ ํ™•์ธํ•ด๋ณด๊ธฐ

@RestController
@RequestMapping("/hello")
public class HelloController {

    // ์†์„ฑ
    private final ApplicationContext applicationContext;

    // ์ƒ์„ฑ์ž ์ฃผ์ž…
    public HelloController(ApplicationContext applicationContext) {
        this.applicationContext = applicationContext;
    }

    // ๊ธฐ๋Šฅ
    @GetMapping()
    public String sayHello() {
        String[] beanDefinitionNames = applicationContext.getBeanDefinitionNames();
        for (String beanName : beanDefinitionNames) {
            System.out.println(beanName.toString());
        }
        return "hello";
    }
}

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

  • ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์‹œ์ž‘ ์‹œ ํ•„์š”ํ•œ ๋นˆ ์ƒ์„ฑ
  • ๋นˆ์— ํ•„์š”ํ•œ ์˜์กด์„ฑ ์ฃผ์ž…
  • ๋นˆ์˜ ์ƒ์• ์ฃผ๊ธฐ ๊ด€๋ฆฌ

 

์ปดํฌ๋„ŒํŠธ ์Šค์บ”

ํด๋ž˜์Šค๋ฅผ ๋นˆ์œผ๋กœ ์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ์— ๋“ฑ๋กํ•˜๋Š” ๊ธฐ์ˆ ์ด๋‹ค.

import org.springframework.boot.autoconfigure.SpringBootApplication;
๊ธฐ๋Šฅ Annotation ์„ค๋ช…
์ž๋™์„ค์ • @EnableAutoConfiguration ์Šคํ”„๋ง ๋ถ€ํŠธ์— ํƒ‘์žฌ๋œ ๊ธฐ๋ณธ ์„ค์ •
์ปดํฌ๋„ŒํŠธ ์Šค์บ” @ComponentScan ํ˜„์žฌ ์œ„์น˜์—์„œ๋ถ€ํ„ฐ ํ•˜์œ„ ํŒจํ‚ค์ง€์˜ ๋ชจ๋“  @Component ๋Œ€์ƒ์„ ๋นˆ์œผ๋กœ ๋“ฑ๋ก
์ถ”๊ฐ€ ์„ค์ • @Configuration ์ปค์Šคํ…€ํ•˜๊ฒŒ ๋งŒ๋“  ์„ค์ • ๊ฐ์ฒด๋ฅผ ํ™œ์šฉํ•˜๊ณ  ์‹ถ์„ ๋•Œ ์‚ฌ์šฉ

์ง์ ‘ ๋นˆ(Bean) ๋“ฑ๋กํ•ด๋ณด๊ธฐ

@Component
public class HelloService {
    // ์†์„ฑ

    // ์ƒ์„ฑ์ž

    // ๊ธฐ๋Šฅ
    public void printHello() {
        System.out.println("printing hello");
    }
}
@Service
public class HelloService {
    // ์†์„ฑ

    // ์ƒ์„ฑ์ž

    // ๊ธฐ๋Šฅ
    public void printHello() {
        System.out.println("printing hello");
    }
}

 

์˜์กด์„ฑ ์ฃผ์ž… (DI: Dependency Injection)

โญ๏ธ๋ฉด์ ‘์—์„œ ๋ฌผ์–ด๋ณด๋Š” ์งˆ๋ฌธ ๋‚ด์šฉ๋“คโญ๏ธ

  • ์ƒ์„ฑ์ž ์ฃผ์ž… ์˜ˆ์‹œ
@Component
public class Car {

    private final Engine engine;

    public Car(Engine engine) {
        this.engine = engine;
    }

    public void start() {
       ...
    }
}
  • ์„ธํ„ฐ ์ฃผ์ž… ์˜ˆ์‹œ
@Component
public class Car {

    private Engine engine;

    @Autowired // ์„ธํ„ฐ ์ฃผ์ž…
    public void setEngine(Engine engine) {
        this.engine = engine;
    }

    public void start() {
       ...
    }
}
  • ํ•„๋“œ ์ฃผ์ž… ์˜ˆ์‹œ
@Component
public class Car {

    private Engine engine;

    @Autowired // ์„ธํ„ฐ ์ฃผ์ž…
    public void setEngine(Engine engine) {
        this.engine = engine;
    }

    public void start() {
       ...
    }
}
์ข…๋ฅ˜ ์ƒ์„ฑ์ž ์ฃผ์ž… ์„ธํ„ฐ ์ฃผ์ž… ํ•„๋“œ ์ฃผ์ž…
์žฅ์  ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์‹คํ–‰๊ณผ ๋™์‹œ์— ์˜์กด์„ฑ์„ ์ฃผ์ž…
== ์•ˆ์ „ํ•œ ์‹œ์Šคํ…œ ์•ˆ์ •์„ฑ
   
๋‹จ์  ์˜์กด์„ฑ์ด ๋งŽ์•„์งˆ ๊ฒฝ์šฐ ๊ฐ€๋…์„ฑ์ด ์ €ํ•˜.... 1. ํด๋ž˜์Šค ์•ˆ์— ์˜์กด์„ฑ์ด ์ˆจ๊ฒจ์ ธ ์žˆ์–ด์„œ ์œ ์ง€๋ณด์ˆ˜๊ฐ€ ์–ด๋ ต๋‹ค.
2. ์˜์กด์„ฑ์ด ๋ณ€๊ฒฝ๋  ๊ฐ€๋Šฅ์„ฑ์ด ์žˆ๋‹ค.
1. ํด๋ž˜์Šค ์•ˆ์— ์˜์กด์„ฑ์ด ์ˆจ๊ฒจ์ ธ ์žˆ์–ด์„œ ์œ ์ง€๋ณด์ˆ˜๊ฐ€ ์–ด๋ ต๋‹ค.
2. ์˜์กด์„ฑ์ด ๋ณ€๊ฒฝ๋  ๊ฐ€๋Šฅ์„ฑ์ด ์žˆ๋‹ค.

์˜์กด์„ฑ ์ฃผ์ž… ์ง์ ‘ ์„ค์ •ํ•ด๋ณด๊ธฐ

@RestController
@RequestMapping("/hello")
public class HelloController {

    // ์†์„ฑ
    private final ApplicationContext applicationContext;
    private final HelloService helloService;

    // ์ƒ์„ฑ์ž ์ฃผ์ž…
    public HelloController(ApplicationContext applicationContext, HelloService helloService) {
        this.applicationContext = applicationContext;
        this.helloService = helloService;
    }

    // ๊ธฐ๋Šฅ
    @GetMapping()
    public String sayHello() {
        helloService.printHello();
        return "hello";
    }
}

 

์Šคํ”„๋ง ๋นˆ

์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ์— ์˜ํ•ด์„œ ๊ด€๋ฆฌ๋˜๋Š” ๊ฐ์ฒด์ด๋‹ค.

๋นˆ์˜ ์ƒ์• ์ฃผ๊ธฐ(Bean LifeCycle)

  • ์ดˆ๊ธฐํ™”๋‹จ๊ณ„
    • ๋นˆ์ด ์‹ค์ œ ์‚ฌ์šฉ๋˜๊ธฐ ์ „ ํ•„์š”ํ•œ ์ถ”๊ฐ€ ์ž‘์—…์„ ํ•˜๋Š” ๋‹จ๊ณ„์ด๋‹ค.
    • Ex) ๋นˆ์˜ ์ƒํƒœ ์—…๋ฐ์ดํŠธ, ๋ฐ์ดํ„ฐ ๋ฒ ์ด์Šค ์—ฐ๊ฒฐ ๋“ฑ๋“ฑ
์ข…๋ฅ˜ ์ดˆ๊ธฐํ™” ๋‹จ๊ณ„ ์†Œ๋ฉธ ์ง์ „
์ธํ„ฐํŽ˜์ด์Šค InitializingBean DisposableBean
๋ฉ”์„œ๋“œ initMethod destroyMethod
์–ด๋…ธํ…Œ์ด์…˜ @PostConstruct @PreDestory
  • ์–ด๋…ธํ…Œ์ด์…˜ ๊ธฐ๋ฐ˜
@Component
public class PostConstructExample {
    @PostConstruct  // ์ดˆ๊ธฐํ™” ๋‹จ๊ณ„์—์„œ ์–ด๋– ํ•œ ์กฐ์ž‘์„ ํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด ์ด๋Ÿฌํ•œ ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•ด๋ณผ ์ˆ˜ ์žˆ๋‹ค.
    public void init() {
        System.out.println("@PostConstruct: ์ดˆ๊ธฐํ™” ์ž‘์—… ์‹คํ–‰");
    }
}
@Component
public class PreDestroyExample {
    @PreDestroy  // ์†Œ๋ฉธ๋˜๊ธฐ ์ „ ์œ ์–ธ์„ ๋“ฃ๋Š” ๊ธฐ๋Šฅ.
    public void cleanup() {
        System.out.println("@PreDestroy: ์†Œ๋ฉธ ์ž‘์—… ์‹คํ–‰");
    }
}

๋นˆ ์Šค์ฝ”ํ”„(Bean Scope)

  • ๋นˆ์˜ ์ƒ์กด ๋ฒ”์œ„, ๊ธฐ๋ณธ๊ฐ’ : ์‹ฑ๊ธ€ํ†ค
  • ์‹ฑ๊ธ€ํ†ค
    • ํ”„๋กœ๊ทธ๋žจ ์ „์ฒด์—์„œ ๋‹จ ํ•˜๋‚˜์˜ ๊ฐ์ฒด๋งŒ ๋งŒ๋“ค์–ด์ง€๊ณ  ๋ชจ๋‘๊ฐ€ ๊ทธ ๊ฐ์ฒด๋ฅผ ๊ณต์œ ํ•ด์„œ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ์‹์ด๋‹ค.
public class Singleton {
    // ์†์„ฑ
    private static Singleton instance;

    // ์ƒ์„ฑ์ž: private ์œผ๋กœ ์™ธ๋ถ€์—์„œ ๊ฐ์ฒด ์ƒ์„ฑ ๋ถˆ๊ฐ€
    private Singleton() {}

    // ๊ธฐ๋Šฅ: ์ธ์Šคํ„ด์Šค๋ฅผ ๋ฐ˜ํ™˜
    public static Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }
}
public class Main {
    public static void main(String[] args) {
        // ๋‘ ๋ฒˆ ํ˜ธ์ถœํ•ด๋„ ๋™์ผํ•œ ๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜
        Singleton singleton1 = Singleton.getInstance();
        Singleton singleton2 = Singleton.getInstance();

        // ๊ฐ์ฒด๊ฐ€ ๊ฐ™์€์ง€ ํ™•์ธ
        System.out.println(singleton1 == singleton2); // true
    }

๋‹ค์–‘ํ•œ ์ข…๋ฅ˜์˜ ์Šค์ฝ”ํ”„

์Šค์ฝ”ํ”„ ์„ค๋ช… ์ƒ์กด๋ฒ”์œ„
singleton ์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ์— ํ•˜๋‚˜์˜ ์ธ์Šคํ„ด์Šค๋งŒ ์ƒ์„ฑ ์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ์™€ ํ•จ๊ป˜
prototype ์š”์ฒญ๋งˆ๋‹ค ์ƒˆ๋กœ์šด ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑ ์ปจํ…Œ์ด๋„ˆ๊ฐ€ ์†Œ๋ฉธ ๊ด€๋ฆฌํ•˜์ง€ ์•Š์Œ
request HTTP ์š”์ฒญ๋งˆ๋‹ค ์ธ์Šคํ„ด์Šค ์ƒ์„ฑ HTTP ์š”์ฒญ ์ข…๋ฃŒ ์‹œ๊นŒ์ง€
session HTTP ์„ธ์…˜๋งˆ๋‹ค ์ธ์Šคํ„ด์Šค ์ƒ์„ฑ ์„ธ์…˜ ์ข…๋ฃŒ ์‹œ
application ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ „์ฒด์—์„œ ํ•˜๋‚˜์˜ ์ธ์Šคํ„ด์Šค ๊ณต์œ  ์„œ๋ธ”๋ฆฟ ์ปจํ…Œ์ด๋„ˆ์™€ ํ•จ๊ป˜
websocket ์›น ์†Œ์ผ“ ์„ธ์…˜ ๋ฒ”์œ„์—์„œ ๋™์ž‘ ์›น์†Œ์ผ“ ์—ฐ๊ฒฐ ์ข…๋ฃŒ๊นŒ์ง€

๊ทธ๋ ‡๋‹ค๋ฉด ์™œ ์‹ฑ๊ธ€ํ†ค์ผ๊นŒ...?!

์š”์ฒญ๋งˆ๋‹ค ๊ฐ์ฒด๋ฅผ ์ƒˆ๋กœ ์ƒ์„ฑํ•ด์•ผ ํ•œ๋‹ค๋ฉด?!
๋น„์šฉ์ด ๋งŽ์ด ๋“ค๊ธฐ ๋•Œ๋ฌธ์— ๋ฏธ๋ฆฌ ํ•˜๋‚˜ ์ƒ์„ฑํ•ด๋†“๊ณ  ๊ทธ๊ฒƒ๋งŒ ๊ฐ€์ ธ๋‹ค ์“ฐ๋Š” ๊ฒƒ์ด๋‹ค.