{"componentChunkName":"component---src-templates-post-template-jsx","path":"/history/posts/2022-07-30--001","result":{"data":{"site":{"siteMetadata":{"title":"Blog by Eunyoung","subtitle":"작업 기록 블로그","copyright":"© All rights reserved.","author":{"name":"EunYoung","twitter":"#"},"disqusShortname":"","url":"https://ssongey.github.io"}},"markdownRemark":{"id":"681006e7-235c-5a74-9e6c-f57e5b7dd565","html":"<h2>1. <strong>InitializingBean, DisposableBean</strong> 인터페이스</h2>\n<ul>\n<li>이 인터페이스는 <strong>스프링 전용 인터페이스</strong>이다. 해당 코드가 스프링 전용 인터페이스에 의존한다.</li>\n<li>초기화, 소멸 메소드의 이름을 변경할 수 없다.</li>\n<li>코드를 수정할 수 없는 외부 라이브러리에 적용할 수 없다.</li>\n<li>현재는 이보다 더 좋은 방법이 있기 때문에 거의 사용 되지 않는다.</li>\n</ul>\n<div class=\"gatsby-highlight\" data-language=\"java\"><pre class=\"language-java\"><code class=\"language-java\"><span class=\"token keyword\">class</span> <span class=\"token class-name\">BeanTest</span> <span class=\"token operator\">:</span> <span class=\"token operator\">*</span><span class=\"token operator\">*</span><span class=\"token class-name\">InitializingBean</span><span class=\"token punctuation\">,</span> <span class=\"token class-name\">DisposableBean</span><span class=\"token operator\">*</span><span class=\"token operator\">*</span> <span class=\"token punctuation\">{</span>\n\n    init <span class=\"token punctuation\">{</span>\n        <span class=\"token function\">println</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"call initBlock\"</span><span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">}</span>\n\n    fun <span class=\"token function\">initTest</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n        <span class=\"token function\">println</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"call initTest\"</span><span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">}</span>\n\n    fun <span class=\"token function\">destroyTest</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n        <span class=\"token function\">println</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"call destroyTest\"</span><span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">}</span>\n\n    <span class=\"token comment\">// 의존관계 주입이 끝나면 호출</span>\n    <span class=\"token operator\">*</span><span class=\"token operator\">*</span>override fun afterPropertiesSet<span class=\"token operator\">*</span><span class=\"token operator\">*</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n        <span class=\"token function\">initTest</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">}</span>\n\n\t\t<span class=\"token comment\">// 스프링 컨테이너 종료시 호출</span>\n    <span class=\"token operator\">*</span><span class=\"token operator\">*</span>override fun destroy<span class=\"token operator\">*</span><span class=\"token operator\">*</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n        <span class=\"token function\">destroyTest</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>\n  <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/devHistoryBlog/static/d6211b13cb4105c1ba8d392f97766abe/027f0/001-01.png\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n  \n  <span\n    class=\"gatsby-resp-image-wrapper\"\n    style=\"position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;\"\n  >\n    <span\n      class=\"gatsby-resp-image-background-image\"\n      style=\"padding-bottom: 24.166666666666664%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAFCAYAAABFA8wzAAAACXBIWXMAABYlAAAWJQFJUiTwAAAA1klEQVQY03WQWxbCIAxEuxc9aqFS3hQpdf+rGidVPv3IgYTMzYSpvRrylpCShzMey7Ig5oxrKbjW+g3mznvs+47WGiprEpn1EAK1CZ7vck597yg1IZcAv0Y8nwQKZNu+MAIuvDs2H72jMwQ8oOu6niaUUpjneQAzpxFoAh81osA4/ULBnQ5uzsHFiPdxoND5cBNZk7sx5gRqrTHJNAGWwgafuJpjXjETqtoLDwoFaBniaIAGTE5r7elUwJNMTFma+BcxYSMo0Z2lULNR/daRtUQoInHyLz5y+p8cbytjaAAAAABJRU5ErkJggg=='); background-size: cover; display: block;\"\n    >\n      <img\n        class=\"gatsby-resp-image-image\"\n        style=\"width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;\"\n        alt=\"001 01\"\n        title=\"\"\n        src=\"/devHistoryBlog/static/d6211b13cb4105c1ba8d392f97766abe/d9199/001-01.png\"\n        srcset=\"/devHistoryBlog/static/d6211b13cb4105c1ba8d392f97766abe/8ff5a/001-01.png 240w,\n/devHistoryBlog/static/d6211b13cb4105c1ba8d392f97766abe/e85cb/001-01.png 480w,\n/devHistoryBlog/static/d6211b13cb4105c1ba8d392f97766abe/d9199/001-01.png 960w,\n/devHistoryBlog/static/d6211b13cb4105c1ba8d392f97766abe/07a9c/001-01.png 1440w,\n/devHistoryBlog/static/d6211b13cb4105c1ba8d392f97766abe/29114/001-01.png 1920w,\n/devHistoryBlog/static/d6211b13cb4105c1ba8d392f97766abe/027f0/001-01.png 2824w\"\n        sizes=\"(max-width: 960px) 100vw, 960px\"\n      />\n    </span>\n  </span>\n  \n  </a>\n    </p>\n<br/>\n<h2>2. initMethod, destroyMethod</h2>\n<ul>\n<li>빈을 생성하기 위한 @Bean 어노테이션에 initMethod와 destroyMethod를 사용하여 지정</li>\n<li>스프링 빈이 스프링 코드에 의존하지 않는다.</li>\n<li>메소드의 이름을 자유롭게 변경할 수 있으며, 코드에 접근할 수 없는 외부 라이브러리에도 초기화, 종료 메소드를 적용할 수 있다.</li>\n</ul>\n<div class=\"gatsby-highlight\" data-language=\"java\"><pre class=\"language-java\"><code class=\"language-java\"><span class=\"token annotation punctuation\">@Configuration</span>\n<span class=\"token keyword\">class</span> <span class=\"token class-name\">WebConfig</span> <span class=\"token punctuation\">{</span>\n\n    <span class=\"token operator\">*</span><span class=\"token operator\">*</span><span class=\"token annotation punctuation\">@Bean</span><span class=\"token punctuation\">(</span>initMethod <span class=\"token operator\">=</span> <span class=\"token string\">\"initTest\"</span><span class=\"token punctuation\">,</span> destroyMethod <span class=\"token operator\">=</span> <span class=\"token string\">\"destroyTest\"</span><span class=\"token punctuation\">)</span><span class=\"token operator\">*</span><span class=\"token operator\">*</span>\n    fun <span class=\"token function\">getBeanTest</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token operator\">:</span> <span class=\"token class-name\">BeanTest</span> <span class=\"token punctuation\">{</span>\n        <span class=\"token keyword\">return</span> <span class=\"token class-name\">BeanTest</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span>\n\n<span class=\"token keyword\">class</span> <span class=\"token class-name\">BeanTest</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">private</span> val logger <span class=\"token operator\">=</span> <span class=\"token class-name\">LoggerFactory</span><span class=\"token punctuation\">.</span><span class=\"token function\">getLogger</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"!!! bean check log !!!\"</span><span class=\"token punctuation\">)</span>\n\n    init <span class=\"token punctuation\">{</span>\n        logger<span class=\"token punctuation\">.</span><span class=\"token function\">info</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"call initBlock\"</span><span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">}</span>\n\n    fun <span class=\"token function\">initTest</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n        logger<span class=\"token punctuation\">.</span><span class=\"token function\">info</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"call initTest\"</span><span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">}</span>\n\n    fun <span class=\"token function\">destroyTest</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n        logger<span class=\"token punctuation\">.</span><span class=\"token function\">info</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"call destroyTest\"</span><span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<h3>2.2. 종료 메소드 추론</h3>\n<ul>\n<li>또한 destroyMethod에는 inferred라는 추론 기능이 추가되어 있다.</li>\n<li>일반적으로 종료 메소드의 이름으로 close 또는 shutdown을 많이 이용하기 때문에, close 또는 shutdown 함수가 존재하면 이를 소멸자 메소드로 인식하여 호출한다.</li>\n<li>이러한 추론 기능을 사용하고 싶지 않으면 destroyMethod=\"\" 처럼 destroyMethod를 공백으로 지정하면 된다.</li>\n</ul>\n<div class=\"gatsby-highlight\" data-language=\"java\"><pre class=\"language-java\"><code class=\"language-java\"><span class=\"token annotation punctuation\">@Configuration</span>\n<span class=\"token keyword\">class</span> <span class=\"token class-name\">WebConfig</span> <span class=\"token punctuation\">{</span>\n\n    <span class=\"token annotation punctuation\">@Bean</span><span class=\"token punctuation\">(</span>initMethod <span class=\"token operator\">=</span> <span class=\"token string\">\"initTest\"</span><span class=\"token punctuation\">)</span>\n    fun <span class=\"token function\">getBeanTest</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token operator\">:</span> <span class=\"token class-name\">BeanTest</span> <span class=\"token punctuation\">{</span>\n        <span class=\"token keyword\">return</span> <span class=\"token class-name\">BeanTest</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span>\n\n<span class=\"token keyword\">class</span> <span class=\"token class-name\">BeanTest</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">private</span> val logger <span class=\"token operator\">=</span> <span class=\"token class-name\">LoggerFactory</span><span class=\"token punctuation\">.</span><span class=\"token function\">getLogger</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"!!! bean check log !!!\"</span><span class=\"token punctuation\">)</span>\n\n    init <span class=\"token punctuation\">{</span>\n        logger<span class=\"token punctuation\">.</span><span class=\"token function\">info</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"call initBlock\"</span><span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">}</span>\n\n    fun <span class=\"token function\">initTest</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n        logger<span class=\"token punctuation\">.</span><span class=\"token function\">info</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"call initTest\"</span><span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">}</span>\n\n    <span class=\"token operator\">*</span><span class=\"token operator\">*</span>fun <span class=\"token function\">close</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span> <span class=\"token comment\">// 스프링 컨테이너 종료시 호출됨</span>\n        logger<span class=\"token punctuation\">.</span><span class=\"token function\">info</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"call destroyTest\"</span><span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">}</span><span class=\"token operator\">*</span><span class=\"token operator\">*</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<br/>\n<h2>3. PostConstruct, PreDestroy</h2>\n<ul>\n<li>최신 스프링에서 가장 권장하는 방법이다.</li>\n<li>애노테이션 하나만 붙이면 되므로 매우 편리하다.</li>\n<li>패키지를 확인해보면 javax.annotation.PostConstruct이다.스프링에 종속적인 기술이 아니라 JSR-250이라는 자바 표준이므로 스프링이 아닌 다른 컨테이너에서도 동작한다,.</li>\n<li>컴포넌트 스캔과 잘 어울린다.</li>\n<li>외부 라이브러리에는 적용하지 못하기 때문에 외부 라이브러리를 초기화, 종료해야 한다면 @Bean 기능을 사용하면 된다.</li>\n</ul>\n<div class=\"gatsby-highlight\" data-language=\"java\"><pre class=\"language-java\"><code class=\"language-java\"><span class=\"token annotation punctuation\">@Configuration</span>\n<span class=\"token keyword\">class</span> <span class=\"token class-name\">WebConfig</span> <span class=\"token punctuation\">{</span>\n\n    <span class=\"token annotation punctuation\">@Bean</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n    fun <span class=\"token function\">getBeanTest</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token operator\">:</span> <span class=\"token class-name\">BeanTest</span> <span class=\"token punctuation\">{</span>\n        <span class=\"token keyword\">return</span> <span class=\"token class-name\">BeanTest</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span>\n\n<span class=\"token keyword\">class</span> <span class=\"token class-name\">BeanTest</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">private</span> val logger <span class=\"token operator\">=</span> <span class=\"token class-name\">LoggerFactory</span><span class=\"token punctuation\">.</span><span class=\"token function\">getLogger</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"!!! bean check log !!!\"</span><span class=\"token punctuation\">)</span>\n\n    init <span class=\"token punctuation\">{</span>\n        logger<span class=\"token punctuation\">.</span><span class=\"token function\">info</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"call initBlock\"</span><span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">}</span>\n\n    <span class=\"token operator\">*</span><span class=\"token operator\">*</span><span class=\"token annotation punctuation\">@PostConstruct</span><span class=\"token operator\">*</span><span class=\"token operator\">*</span>\n    fun <span class=\"token function\">initTest</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n        logger<span class=\"token punctuation\">.</span><span class=\"token function\">info</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"call initTest\"</span><span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">}</span>\n\n    <span class=\"token operator\">*</span><span class=\"token operator\">*</span><span class=\"token annotation punctuation\">@PreDestroy</span><span class=\"token operator\">*</span><span class=\"token operator\">*</span>\n    fun <span class=\"token function\">destroyTest</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n        logger<span class=\"token punctuation\">.</span><span class=\"token function\">info</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"call destroyTest\"</span><span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<br/>\n<h2>4. 정리</h2>\n<p>보통은 @PostConstruct, @PreDestroy 을 사용하는걸 권장하지만, 외부 라이브러리 초기화/ 소멸시 처리해야 할 과정이 있다면, @Bean 의 InitMethod, destroyMethod를 사용하면 된다.</p>\n<h3>4.1. 만약 <strong>SIGKILL 시그널(</strong>kill -9 {PID})<strong>로 종료가 되었다면</strong>,</h3>\n<ul>\n<li><strong>SIGKILL</strong>은 프로세스를 즉시 종료 시킨다. 해당 시그널을 받으면 프로세스가 종료되기 전에 수행되어야 하는 종료 절차를 실행하지 않고 즉시 종료하므로 graceful shutdown을 위해서라면 해당 시그널을 통해 프로세스를 종료시키는 것은 피해야한다.</li>\n</ul>\n<h3>4.2. 호출 순서는?</h3>\n<ul>\n<li><strong>init</strong> : @PostConstruct → InitializingBean 인터페이스 → @Bean initMethod</li>\n<li><strong>destroy</strong> : @PreDestroy → DisposableBean 인터페이스 → @Bean destroyMethod</li>\n</ul>\n<p>\n  <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/devHistoryBlog/static/58087959a667ff91de6ffeeb64655605/763a5/001-02.png\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n  \n  <span\n    class=\"gatsby-resp-image-wrapper\"\n    style=\"position: relative; display: block;  max-width: 960px; margin-left: auto; margin-right: auto;\"\n  >\n    <span\n      class=\"gatsby-resp-image-background-image\"\n      style=\"padding-bottom: 19.583333333333332%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAECAYAAACOXx+WAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAxUlEQVQY0y2PWQ6DMAxEuUvV0iyQANkTUHv/Q03HqB8jy9uzZ+q9o/eBVANyyFiWFd47bKXgmRJejHMIeDuHnDOu60JhTSR54oz3nnsLtNaYxugYBOYWb6C1C9y6YqsVDy68YoTmsLIW6Q8cY9wSoIBEln1jDKbzPNk8UVpCyRX7tvNqRGgNmjIEz4S++UU4DhTm8l1ljKwHfi+SLx1dTL03tNoQy4F4xBv6/X7geX2mHcVhQytaqXtRQI2HRAIRm4o9iaIfDzCAP7YYuXwAAAAASUVORK5CYII='); background-size: cover; display: block;\"\n    >\n      <img\n        class=\"gatsby-resp-image-image\"\n        style=\"width: 100%; height: 100%; margin: 0; vertical-align: middle; position: absolute; top: 0; left: 0; box-shadow: inset 0px 0px 0px 400px white;\"\n        alt=\"001 02\"\n        title=\"\"\n        src=\"/devHistoryBlog/static/58087959a667ff91de6ffeeb64655605/d9199/001-02.png\"\n        srcset=\"/devHistoryBlog/static/58087959a667ff91de6ffeeb64655605/8ff5a/001-02.png 240w,\n/devHistoryBlog/static/58087959a667ff91de6ffeeb64655605/e85cb/001-02.png 480w,\n/devHistoryBlog/static/58087959a667ff91de6ffeeb64655605/d9199/001-02.png 960w,\n/devHistoryBlog/static/58087959a667ff91de6ffeeb64655605/07a9c/001-02.png 1440w,\n/devHistoryBlog/static/58087959a667ff91de6ffeeb64655605/29114/001-02.png 1920w,\n/devHistoryBlog/static/58087959a667ff91de6ffeeb64655605/763a5/001-02.png 2804w\"\n        sizes=\"(max-width: 960px) 100vw, 960px\"\n      />\n    </span>\n  </span>\n  \n  </a>\n    </p>","fields":{"tagSlugs":["/tags/spring/"],"slug":"/history/posts/2022-07-30--001"},"frontmatter":{"title":"Bean 초기화/ 소멸 방법 3가지","tags":["spring"],"date":"2022-07-30","description":""}}},"pageContext":{"slug":"/history/posts/2022-07-30--001"}},"staticQueryHashes":[]}