# Spring / ์Šคํ”„๋ง ๋นˆ Life-cycle callback
Study Repository

Spring / ์Šคํ”„๋ง ๋นˆ Life-cycle callback

by rlaehddnd0422

๋นˆ ์ƒ๋ช…์ฃผ๊ธฐ ์ฝœ๋ฐฑ ์‹œ์ž‘

 

๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์ปค๋„ฅ์…˜ ํ’€์ด๋‚˜, ๋„คํŠธ์›Œํฌ ์†Œ์ผ“์ฒ˜๋Ÿผ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์‹œ์ž‘ ์‹œ์ ์— ํ•„์š”ํ•œ ์—ฐ๊ฒฐ์„ ๋ฏธ๋ฆฌ ํ•ด๋‘๊ณ  ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ข…๋ฃŒ ์‹œ์ ์— ์—ฐ๊ฒฐ์„ ๋ชจ๋‘ ์ข…๋ฃŒํ•˜๋Š” ์ž‘์—…์„ ์ง„ํ–‰ํ•˜๋ ค๋ฉด, ๊ฐ์ฒด์˜ ์ดˆ๊ธฐํ™”์™€ ์ข…๋ฃŒ ์ž‘์—…์ด ํ•„์š”ํ•˜๋‹ค.

 

์˜ˆ๋ฅผ๋“ค์–ด ์™ธ๋ถ€ ๋„คํŠธ์›Œํฌ์— ๋ฏธ๋ฆฌ ์—ฐ๊ฒฐํ•˜๋Š” ๊ฐ์ฒด๋ฅผ ํ•˜๋‚˜ ์ƒ์„ฑํ•œ๋‹ค๊ณ  ๊ฐ€์ •ํ•ด๋ณด์ž. ์‹ค์ œ ์—ฐ๊ฒฐ์€ ์•„๋‹ˆ๊ณ  ๋‹จ์ˆœํžˆ ๋ฌธ์ž๋งŒ ์ถœ๋ ฅํ•˜๋„๋ก ํ–ˆ๋‹ค.

 

์ด NetworkClient๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์‹œ์ž‘ ์‹œ์ ์— connect()๋ฅผ ์ถœํ•ด์„œ ์—ฐ๊ฒฐ์„ ๋งบ์–ด๋‘์–ด์•ผ ํ•˜๊ณ , ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ์ข…๋ฃŒ๋˜๋ฉด disconnect()๋ฅผ ํ˜ธ์ถœํ•ด์„œ ์—ฐ๊ฒฐ์„ ๋Š์–ด์•ผ ํ•œ๋‹ค.

package hello.core.lifecycle;

import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;

public class NetworkClient {
    private String url;

    public NetworkClient()
    {
        System.out.println("์ƒ์„ฑ์ž ํ˜ธ์ถœ, url = " + url);
        connect();
        call("์ดˆ๊ธฐํ™” ์™„๋ฃŒ");
    }

    public void setUrl(String url) {
        this.url = url;
    }

    public void connect()
    {
        System.out.println("connect : " + url);
    }

    public void call(String message)
    {
        System.out.println("call: " + url + " message : " + message);
    }

    // ์„œ๋น„์Šค ์ข…๋ฃŒ์‹œ ํ˜ธ์ถœ
    public void disconnect()
    {
        System.out.println("close : " + url);

    }

}

 

Test Code

package hello.core.lifecycle;

import org.junit.jupiter.api.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

public class BeanLifeCycleTest {
    @Test
    public void lifeCycleTest()
    {
        ConfigurableApplicationContext ac = new AnnotationConfigApplicationContext(LifeCycleConfig.class);
        NetworkClient client = ac.getBean(NetworkClient.class);
        ac.close();
    }

    @Configuration
    static class LifeCycleConfig{

        @Bean
        public NetworkClient networkClient()
        {
            NetworkClient networkClient = new NetworkClient();
            networkClient.setUrl("http://hello-spring.dev");
            return networkClient;

        }
    }
}

 

์‹คํ–‰ํ•ด๋ณด๋ฉด 

์ด์™€ ๊ฐ™์€ ๊ฒฐ๊ณผ๊ฐ€ ๋‚˜์˜จ๋‹ค.

 

์Šคํ”„๋ง ๋นˆ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์€ LifeCycle์„ ๊ฐ€์ง„๋‹ค.

 

๊ฐ์ฒด ์ƒ์„ฑ -> ์˜์กด๊ด€๊ณ„ ์ฃผ์ž…

 

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

๋”ฐ๋ผ์„œ ์ดˆ๊ธฐํ™” ์ž‘์—…์€ ์˜์กด๊ด€๊ณ„ ์ฃผ์ž…์ด ๋ชจ๋‘ ์™„๋ฃŒ๋˜๊ณ  ๋‚œ ๋‹ค์Œ์— ํ˜ธ์ถœํ•ด์•ผ ํ•œ๋‹ค.

 

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

๋˜ํ•œ ์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ๊ฐ€ ์ข…๋ฃŒ๋˜๊ธฐ ์ง์ „์— ์†Œ๋ฉธ ์ฝœ๋ฐฑ์„ ์ฃผ๋Š” ๊ธฐ๋Šฅ์ด ์žˆ์–ด ์•ˆ์ „ํ•˜๊ฒŒ ์ข…๋ฃŒ ์ž‘์—…์„ ์ง„ํ–‰ํ•  ์ˆ˜ ์žˆ์Œ.

 

์Šคํ”„๋ง ๋นˆ์˜ Lifecycle

์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ ์ƒ์„ฑ -> ์Šคํ”„๋ง ๋นˆ ์ƒ์„ฑ -> ์˜์กด๊ด€๊ณ„ ์ฃผ์ž… -> ์ดˆ๊ธฐํ™” ์ฝœ๋ฐฑ -> ์‚ฌ์šฉ -> ์†Œ๋ฉธ ์ „ ์ฝœ๋ฐฑ -> ๋นˆ ์†Œ๋ฉธ -> ์Šคํ”„๋ง ์ข…๋ฃŒ

 

์ดˆ๊ธฐํ™” ์ฝœ๋ฐฑ : ๋นˆ์ด ์ƒ์„ฑ๋˜๊ณ , ์˜์กด๊ด€๊ณ„ ์ฃผ์ž…์ด ์™„๋ฃŒ๋œ ํ›„ ํ˜ธ์ถœ

์†Œ๋ฉธ ์ „ ์ฝœ๋ฐฑ : ๋นˆ์ด ์†Œ๋ฉธ๋˜๊ธฐ ์ง์ „์— ํ˜ธ์ถœ

 

Tip : ๊ฐ์ฒด์˜ ์ƒ์„ฑ๊ณผ ์ดˆ๊ธฐํ™”๋ฅผ ๋ถ„๋ฆฌํ•˜์ž.

์ƒ์„ฑ์ž๋Š” ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ๋ฐ›์•„ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ํ• ๋‹นํ•ด์„œ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๋Š” ์ฑ…์ž„์„ ๊ฐ€์ง„๋‹ค.

์ดˆ๊ธฐํ™”๋Š” ์ด๋ ‡๊ฒŒ ์ƒ์„ฑ๋œ ๊ฐ’๋“ค์„ ํ™œ์šฉํ•ด ์™ธ๋ถ€ ์ปค๋„ฅ์…˜์„ ์—ฐ๊ฒฐํ•˜๋Š” ๋“ฑ ๋ฌด๊ฑฐ์šด ๋™์ž‘์„ ์ˆ˜ํ–‰ํ•œ๋‹ค.

 

๋”ฐ๋ผ์„œ ์ƒ์„ฑ์ž ์•ˆ์—์„œ ๋ฌด๊ฑฐ์šด ์ดˆ๊ธฐํ™” ์ž‘์—…์„ ๋ณ‘ํ–‰ํ•ด์„œ ํ•˜๋Š” ๊ฒƒ๋ณด๋‹ค ๋™์ž‘์„ ๋ถ„๋ฆฌํ•˜๋Š” ๊ฒƒ์ด ์œ ์ง€๋ณด์ˆ˜ ๊ด€์ ์—์„œ ์ข‹๋‹ค.

๋ฌผ๋ก  ์ดˆ๊ธฐํ™” ์ž‘์—…์ด ๋‚ด๋ถ€ ๊ฐ’๋“ค๋งŒ ์•ฝ๊ฐ„ ๋ณ€๊ฒฝํ•˜๋Š” ์ •๋„๋กœ ๋‹จ์ˆœํ•œ ๊ฒฝ์šฐ๋Š” ์˜ˆ์™ธ.

 

์Šคํ”„๋ง์€ ํฌ๊ฒŒ 3๊ฐ€์ง€ ๋นˆ Life-cycle callback์„ ์ง€์›ํ•œ๋‹ค.

1. ์ธํ„ฐํŽ˜์ด์Šค (InitializingBean, DisposableBean)

2. Config ์ •๋ณด์— ์ดˆ๊ธฐํ™” ๋ฉ”์†Œ๋“œ, ์ข…๋ฃŒ ๋ฉ”์†Œ๋“œ ์ง€์ •

3. @PostConstruct, @PreDestroy ์–ด๋…ธํ…Œ์ด์…˜


1. ์ธํ„ฐํŽ˜์ด์Šค (InitializingBean, DisposableBean)

InitializingBean์€ afterPropertiesSet()๋ฉ”์†Œ๋“œ๋กœ ์ดˆ๊ธฐํ™”๋ฅผ ์ง€์›ํ•œ๋‹ค.

DisposableBean์€ destroy() ๋ฉ”์†Œ๋“œ๋กœ ์†Œ๋ฉธ์„ ์ง€์›ํ•œ๋‹ค.

 

package hello.core.lifecycle;

import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;

public class NetworkClient implements InitializingBean, DisposableBean{
    private String url;


    public NetworkClient()
    {
        System.out.println("์ƒ์„ฑ์ž ํ˜ธ์ถœ, url = " + url);
    }
    @Override
    public void afterPropertiesSet() throws Exception {
        connect();
        call("์ดˆ๊ธฐํ™” ์—ฐ๊ฒฐ ๋ฉ”์‹œ์ง€");
    }

    public void setUrl(String url) {
        this.url = url;
    }

    public void connect()
    {
        System.out.println("connect : " + url);
    }

    public void call(String message)
    {
        System.out.println("call: " + url + " message : " + message);
    }

    @Override
    public void destroy() throws Exception {
        disconnect();
    }

    // ์„œ๋น„์Šค ์ข…๋ฃŒ์‹œ ํ˜ธ์ถœ
    public void disconnect()
    {
        System.out.println("close : " + url);
    }


}

 

์ถœ๋ ฅ ๊ฒฐ๊ณผ๋ฅผ ๋ณด๋ฉด ์ดˆ๊ธฐํ™” ๋ฉ”์†Œ๋“œ๊ฐ€ ์ฃผ์ž… ์™„๋ฃŒ ํ›„ ์ ์ ˆํ•˜๊ฒŒ ํ˜ธ์ถœ ๋œ ๊ฒƒ์„ ํ™•์ธ ๊ฐ€๋Šฅ.

๊ทธ๋ฆฌ๊ณ  ์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ์˜ ์ข…๋ฃŒ๊ฐ€ ํ˜ธ์ถœ๋˜์ž ์†Œ๋ฉธ ๋ฉ”์†Œ๋“œ๊ฐ€ ํ˜ธ์ถœ ๋œ ๊ฒƒ์„ ํ™•์ธ ๊ฐ€๋Šฅ.

 

์ดˆ๊ธฐํ™”, ์†Œ๋ฉธ ์ธํ„ฐํŽ˜์ด์Šค ๋‹จ์ .

์Šคํ”„๋ง ์ „์šฉ ์ธํ„ฐํŽ˜์ด์Šค๋ผ๋Š” ์ธก๋ฉด์—์„œ ์˜์กด์ ์ด๋‹ค.

์ดˆ๊ธฐํ™”, ์†Œ๋ฉธ ๋ฉ”์†Œ๋“œ์˜ ์ด๋ฆ„์„ ๋ณ€๊ฒฝ ๋ถˆ๊ฐ€๋Šฅํ•˜๋‹ค. (์ธํ„ฐํŽ˜์ด์Šค)

๋‚ด๊ฐ€ ์ฝ”๋“œ๋ฅผ ๊ณ ์น  ์ˆ˜ ์—†๋Š” ์™ธ๋ถ€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์— ์ ์šฉํ•  ์ˆ˜ ์—†๋‹ค.

 

์ธํ„ฐํŽ˜์ด์Šค๋Š” ์ดˆ์ฐฝ๊ธฐ์— ๋‚˜์˜จ ๋ฐฉ๋ฒ•๋“ค์ด๊ณ , ์ง€๊ธˆ์€ ๊ฑฐ์˜ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š”๋‹ค.

 


2. Config ์ •๋ณด์— ์ดˆ๊ธฐํ™” ๋ฉ”์†Œ๋“œ, ์ข…๋ฃŒ ๋ฉ”์†Œ๋“œ ์ง€์ •

์„ค์ • ์ •๋ณด์— @Bean(initMethod = "init", destroyMethod = "close)์ฒ˜๋Ÿผ ์ดˆ๊ธฐํ™” ์†Œ๋ฉธ ๋ฉ”์†Œ๋“œ๋ฅผ ์ง€์ •ํ•  ์ˆ˜ ์žˆ์Œ.

 


public void init()
{
    System.out.println("NetworkClient.init");
    connect();
    call("์ดˆ๊ธฐํ™” ์—ฐ๊ฒฐ ๋ฉ”์‹œ์ง€");
}

public void close()
{
    System.out.println("NetworkClient.close");
    disconnect();
}
package hello.core.lifecycle;

import org.junit.jupiter.api.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

public class BeanLifeCycleTest {
    @Test
    public void lifeCycleTest()
    {
        ConfigurableApplicationContext ac = new AnnotationConfigApplicationContext(LifeCycleConfig.class);
        NetworkClient client = ac.getBean(NetworkClient.class);
        ac.close();
    }

    @Configuration
    static class LifeCycleConfig{

        @Bean(initMethod = "init" , destroyMethod = "close")
        public NetworkClient networkClient()
        {
            NetworkClient networkClient = new NetworkClient();
            networkClient.setUrl("http://hello-spring.dev");
            return networkClient;

        }
    }
}

ํŠน์ง•

๋ฉ”์†Œ๋“œ ์ด๋ฆ„์„ ์ž์œ ๋กญ๊ฒŒ ์ค„ ์ˆ˜ ์žˆ๋‹ค.

์Šคํ”„๋ง ๋นˆ์ด ์Šคํ”„๋ง ์ฝ”๋“œ์— ์˜์กดํ•˜์ง€ ์•Š์Œ.

์ฝ”๋“œ๊ฐ€ ์•„๋‹Œ ์„ค์ •์ •๋ณด๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ฝ”๋“œ๋ฅผ ๊ณ ์น  ์ˆ˜ ์—†๋Š” ์™ธ๋ถ€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์—๋„ ์ดˆ๊ธฐํ™”, ์ข…๋ฃŒ ๋ฉ”์†Œ๋“œ ์ ์šฉ ๊ฐ€๋Šฅ

 

@Bean destroyMethod ์†์„ฑ์˜ ์ถ”๋ก (inferred) ๊ธฐ๋Šฅ

- ์ง€์ •ํ•˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ close , shutdown๋ผ๋Š” ์ด๋ฆ„์˜ ๋ฉ”์†Œ๋“œ๋ฅผ ์ž๋™์œผ๋กœ ํ˜ธ์ถœํ•ด์ค€๋‹ค.

- ์ถ”๋ก  ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•˜๊ธฐ ์‹ซ์œผ๋ฉด ๋นˆ ๊ณต๋ฐฑ์„ ์ง€์ •ํ•˜๋ฉด ๋œ๋‹ค. ""

 


3. @PostConstruct, @PreDestroy

@PostConstruct
public void init()
{
    System.out.println("NetworkClient.init");
    connect();
    call("์ดˆ๊ธฐํ™” ์—ฐ๊ฒฐ ๋ฉ”์‹œ์ง€");
}

@PreDestroy
public void close()
{
    System.out.println("NetworkClient.close");
    disconnect();
}

@PostConstruct , @PreDestroy ์ด ๋‘ ์• ๋…ธํ…Œ์ด์…˜์„ ์‚ฌ์šฉํ•˜๋ฉด ๊ฐ€์žฅ ํŽธ๋ฆฌํ•˜๊ฒŒ ์ดˆ๊ธฐํ™”์™€ ์ข…๋ฃŒ๋ฅผ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๋‹ค.

 

ํŠน์ง•

1. ์ตœ์‹  ์Šคํ”„๋ง์—์„œ ๊ฐ€์žฅ ๊ถŒ์žฅํ•˜๋Š” ๋ฐฉ๋ฒ•

2. ์–ด๋…ธํ…Œ์ด์…˜ ํ•˜๋‚˜๋งŒ ๋ถ™์ด๋ฉด ๋˜๋ฏ€๋กœ ๋งค์šฐ ํŽธ๋ฆฌ.

3. javax ํŒจํ‚ค์ง€๋กœ ์Šคํ”„๋ง ์ข…์† ๊ธฐ์ˆ ์ด ์•„๋‹ˆ๋ผ ์ž๋ฐ” ํ‘œ์ค€ ๊ธฐ์ˆ ์ด๋ผ ์Šคํ”„๋ง์ด ์•„๋‹Œ ๋‹ค๋ฅธ ์ปจํ…Œ์ด๋„ˆ์—์„œ๋„ ์ž‘๋™

4. ์ปดํฌ๋„ŒํŠธ ์Šค์บ”๊ณผ ์ž˜ ์–ด์šธ๋ฆผ

5. ๋‹จ์ ์œผ๋กœ๋Š” ์™ธ๋ถ€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์—๋Š” ์ ์šฉํ•˜์ง€ ๋ชปํ•จ.

 


<์ •๋ฆฌ>

@PostConstruct, @PreDestroy ์–ด๋…ธํ…Œ์ด์…˜์„ ์‚ฌ์šฉํ•˜๋˜, ์™ธ๋ถ€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์ดˆ๊ธฐํ™”, ์ข…๋ฃŒํ•ด์•ผํ•˜๋ฉด @Bean์˜ initMethod, destroyMethod๋ฅผ ์‚ฌ์šฉํ•˜์ž.

 

<์ฐธ๊ณ ์ž๋ฃŒ>

https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-%ED%95%B5%EC%8B%AC-%EC%9B%90%EB%A6%AC-%EA%B8%B0%EB%B3%B8%ED%8E%B8/dashboard

 

 

 

 

์Šคํ”„๋ง ํ•ต์‹ฌ ์›๋ฆฌ - ๊ธฐ๋ณธํŽธ - ์ธํ”„๋Ÿฐ | ๊ฐ•์˜

์Šคํ”„๋ง ์ž…๋ฌธ์ž๊ฐ€ ์˜ˆ์ œ๋ฅผ ๋งŒ๋“ค์–ด๊ฐ€๋ฉด์„œ ์Šคํ”„๋ง์˜ ํ•ต์‹ฌ ์›๋ฆฌ๋ฅผ ์ดํ•ดํ•˜๊ณ , ์Šคํ”„๋ง ๊ธฐ๋ณธ๊ธฐ๋ฅผ ํ™•์‹คํžˆ ๋‹ค์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค., - ๊ฐ•์˜ ์†Œ๊ฐœ | ์ธํ”„๋Ÿฐ...

www.inflearn.com

 

๋ธ”๋กœ๊ทธ์˜ ์ •๋ณด

Study Repository

rlaehddnd0422

ํ™œ๋™ํ•˜๊ธฐ