๐Ÿง‘๐Ÿปโ€๐Ÿ’ป๋นˆ ์ƒ๋ช…์ฃผ๊ธฐ CallBackโœ๐Ÿป

DEVJUNยท2021๋…„ 12์›” 26์ผ
0
post-thumbnail

์ฝ”๋“œ๋ฅผ ํ†ตํ•ด ์Šคํ”„๋ง ๋นˆ์˜ ๊ฐ„๋‹จํ•œ ๋ผ์ดํ”„ ์‚ฌ์ดํด์„ ์•Œ์•„๋ณด๋ ค ํ•œ๋‹ค.

//์˜ˆ์ œ์ฝ”๋“œ
package hello.core.lifecycle;

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);
      	}
}

์œ„์— ์˜ˆ์ œ ์ฝ”๋“œ์— ๋Œ€ํ•œ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ์ด๋‹ค.

//ํ…Œ์ŠคํŠธ ์ฝ”๋“œ
package hello.core.lifecycle;
import org.junit.jupiter.api.Test;
import org.springframework.context.ApplicationContext;
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 = newAnnotationConfigApplicationContext(LifeCycleConfig.class);
          NetworkClient client = ac.getBean(NetworkClient.class); 
          ac.close(); //์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ๋ฅผ ์ข…๋ฃŒ, ConfigurableApplicationContext ํ•„์š”
      }
      
      
      @Configuration
      static class LifeCycleConfig {
          @Bean
          public NetworkClient networkClient() {
              NetworkClient networkClient = new NetworkClient();
              networkClient.setUrl("http://hello-spring.dev");
              return networkClient;
	} 
    }
}

ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•˜๋ฉด ๊ฐ์ฒด ์ƒ์„ฑ ๋‹จ๊ณ„์—๋Š” ์„ค์ •๋œ url์ด ์—†๊ธฐ ๋•Œ๋ฌธ์— ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ฒฐ๊ณผ๊ฐ€ ๋‚˜์˜ฌ ๊ฒƒ์ด๋‹ค. ์ฝ”๋“œ์—์„  setUrl(์ˆ˜์ •์ž ์ฃผ์ž…)์„ ํ†ตํ•ด์•ผ๋งŒ url์ด ๋งŒ๋“ค์–ด์ง„๋‹ค.

์ƒ์„ฑ์ž ํ˜ธ์ถœ, url = null 
connect: null
call: null message = ์ดˆ๊ธฐํ™” ์—ฐ๊ฒฐ ๋ฉ”์‹œ์ง€

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

โญ๏ธ์Šคํ”„๋ง ๋นˆ์˜ ์ด๋ฒคํŠธ ๋ผ์ดํ”„์‚ฌ์ดํดโญ๏ธ

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


์Šคํ”„๋ง์€ ํฌ๊ฒŒ 3๊ฐ€์ง€ ๋ฐฉ๋ฒ•์œผ๋กœ ๋นˆ ์ƒ๋ช…์ฃผ๊ธฐ ์ฝœ๋ฐฑ์„ ์ง€์›ํ•œ๋‹ค.

  • ์ธํ„ฐํŽ˜์ด์Šค(InitializingBean, DisposableBean)
  • ์„ค์ • ์ •๋ณด์— ์ดˆ๊ธฐํ™” ๋ฉ”์„œ๋“œ, ์ข…๋ฃŒ ๋ฉ”์„œ๋“œ ์ง€์ •
  • @PostConstruct, @PreDestroy ์• ๋…ธํ…Œ์ด์…˜ ์ง€์›

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

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); 
      }
      
      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);
      }
      
      @Override
      public void afterPropertiesSet() throws Exception {
	  connect();
	  call("์ดˆ๊ธฐํ™” ์—ฐ๊ฒฐ ๋ฉ”์‹œ์ง€");
      }
      
      @Override
      public void destroy() throws Exception {
          disConnect();
      }
 }

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

ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋Š” ๊ทธ๋Œ€๋กœ ๋‘์—ˆ๋‹ค.

์ƒ์„ฑ์ž ํ˜ธ์ถœ, url = null
NetworkClient.afterPropertiesSet
connect: http://hello-spring.dev
call: http://hello-spring.dev message = ์ดˆ๊ธฐํ™” ์—ฐ๊ฒฐ ๋ฉ”์‹œ์ง€
13:24:49.043 [main] DEBUG org.springframework.context.annotation.AnnotationConfigApplicationContext - Closing NetworkClient.destroy
close + http://hello-spring.dev

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

์ด ์ฝ”๋“œ๋Š” ์Šคํ”„๋ง ์ „์šฉ ์ธํ„ฐํŽ˜์ด์Šค์— ์˜์กดํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ข‹์€ ๋ฐฉ๋ฒ•์ด ์•„๋‹ˆ๋‹ค.

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

package hello.core.lifecycle;

public class NetworkClient {
        private String url;
        
        public NetworkClient() {
	    System.out.println("์ƒ์„ฑ์ž ํ˜ธ์ถœ, url = " + url); 
        }
        
        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);
      	}
        
        
	public void init() { 
    	    System.out.println("NetworkClient.init"); 	
            connect();
	    call("์ดˆ๊ธฐํ™” ์—ฐ๊ฒฐ ๋ฉ”์‹œ์ง€");
	}
     
     	public void close() {
             System.out.println("NetworkClient.close");
             disConnect();
	} 
}

ํ…Œ์ŠคํŠธ ์ฝ”๋“œ์—์„  @Configuration(์„ค์ •์ •๋ณด) ๋ถ€๋ถ„๋งŒ ๋ฐ”๋€Œ์—ˆ๋‹ค.

์„ค์ • ์ •๋ณด์— @Bean(initMethod = "init", destroyMethod = "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;
      } 
}
์ƒ์„ฑ์ž ํ˜ธ์ถœ, url = null
NetworkClient.init
connect: http://hello-spring.dev
call: http://hello-spring.dev message = ์ดˆ๊ธฐํ™” ์—ฐ๊ฒฐ ๋ฉ”์‹œ์ง€
13:33:10.029 [main] DEBUG org.springframework.context.annotation.AnnotationConfigApplicationContext - Closing NetworkClient.close
close + http://hello-spring.dev

์ดˆ๊ธฐํ™” ๋ฉ”์„œ๋“œ์™€, ์ข…๋ฃŒ ๋ฉ”์„œ๋“œ๋ฅผ ์ง€์ •ํ•˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์€ ํŠน์ง•์ด ์žˆ๋‹ค.

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


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

package hello.core.lifecycle;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
 
public class NetworkClient {
	private String url;
	public NetworkClient() {
		System.out.println("์ƒ์„ฑ์ž ํ˜ธ์ถœ, url = " + url); 
        }
        
	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);
        }
        
        @PostConstruct
        public void init() {
            System.out.println("NetworkClient.init"); 
            connect();
            call("์ดˆ๊ธฐํ™” ์—ฐ๊ฒฐ ๋ฉ”์‹œ์ง€");
        }
        @PreDestroy
        public void close() {
            System.out.println("NetworkClient.close");
            disConnect();
        }
}

//ํ…Œ์ŠคํŠธ ์ฝ”๋“œ

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

//์ถœ๋ ฅ๊ฒฐ๊ณผ
  
์ƒ์„ฑ์ž ํ˜ธ์ถœ, url = null
NetworkClient.init
connect: http://hello-spring.dev
call: http://hello-spring.dev message = ์ดˆ๊ธฐํ™” ์—ฐ๊ฒฐ ๋ฉ”์‹œ์ง€
19:40:50.269 [main] DEBUG org.springframework.context.annotation.AnnotationConfigApplicationContext - Closing NetworkClient.close
close + http://hello-spring.dev

๐Ÿ“@PostConstruct, @PreDestroy ์• ๋…ธํ…Œ์ด์…˜ ํŠน์ง•

  • ์ตœ์‹  ์Šคํ”„๋ง์—์„œ ๊ฐ€์žฅ ๊ถŒ์žฅํ•˜๋Š” ๋ฐฉ๋ฒ•์ด๋‹ค.
  • ์• ๋…ธํ…Œ์ด์…˜ ํ•˜๋‚˜๋งŒ ๋ถ™์ด๋ฉด ๋˜๋ฏ€๋กœ ๋งค์šฐ ํŽธ๋ฆฌํ•˜๋‹ค.
  • ํŒจํ‚ค์ง€๋ฅผ ์ž˜ ๋ณด๋ฉด javax.annotation.PostConstruct ์ด๋‹ค. ์Šคํ”„๋ง์— ์ข…์†์ ์ธ ๊ธฐ์ˆ ์ด ์•„๋‹ˆ๋ผ JSR-250 ๋ผ๋Š” ์ž๋ฐ” ํ‘œ์ค€์ด๋‹ค.
  • ๋”ฐ๋ผ์„œ ์Šคํ”„๋ง์ด ์•„๋‹Œ ๋‹ค๋ฅธ ์ปจํ…Œ์ด๋„ˆ์—์„œ๋„ ๋™์ž‘ํ•œ๋‹ค.
  • ์ปดํฌ๋„ŒํŠธ ์Šค์บ”๊ณผ ์ž˜ ์–ด์šธ๋ฆฐ๋‹ค.
  • ์œ ์ผํ•œ ๋‹จ์ ์€ ์™ธ๋ถ€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์—๋Š” ์ ์šฉํ•˜์ง€ ๋ชปํ•œ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค. ์™ธ๋ถ€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์ดˆ๊ธฐํ™”, ์ข…๋ฃŒ ํ•ด์•ผ ํ•˜๋ฉด @Bean์˜ ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค๋Š” ์ ์ด๋‹ค.


์ถœ์ฒ˜

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

profile
๐Ÿง‘๐Ÿปโ€๐Ÿ’ปiOS

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