๋น ์๋ช ์ฃผ๊ธฐ ์ฝ๋ฐฑ
๋ฐ์ดํฐ๋ฒ ์ด์ค ์ปค๋ฅ์ ํ์ด๋, ๋คํธ์ํฌ ์์ผ์ฒ๋ผ
์ ํ๋ฆฌ์ผ์ด์ ์์ ์์ ์ ํ์ํ ์ฐ๊ฒฐ์ ๋ฏธ๋ฆฌ ํด๋๊ณ , ์ ํ๋ฆฌ์ผ์ด์ ์ข ๋ฃ ์์ ์ ์ฐ๊ฒฐ์ ๋ชจ๋ ์ข ๋ฃํ๋ ์์ ์ ์งํํ๋ ค๋ฉด,
๊ฐ์ฒด์ ์ด๊ธฐํ์ ์ข ๋ฃ ์์ ์ด ํ์ํ๋ค.
์ด๋ฒ์๊ฐ์๋ ์คํ๋ง์ ํตํด ์ด๋ฌํ ์ด๊ธฐํ ์์
๊ณผ ์ข
๋ฃ ์์
์ ์ด๋ป๊ฒ ์งํํ๋์ง ์์ ๋ก ์์๋ณด์.
์ฐธ๊ณ : ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ปค๋ฅ์ ํ
WAS(Web Application Server)์ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ฌ์ด์ ์ฐ๊ฒฐ์๋ ๋ง์ ๋น์ฉ์ด ๋ ๋ค
์๋ฒ๊ฐ DB์ ์ฐ๊ฒฐํ๊ธฐ ์ํ Connecting ๋น์ฉ์ด ๊ฐ์ฅ ํฐ ๋น์จ์ ์ฐจ์งํ๋ค.
์ด์ฒ๋ผ Connection์ ์์ฑํ๋ ์์ ์ ๋น์ฉ์ด ๋ง์ด ๋๋ ์์ ์ด๋ค.
์ด๋ฅผ ๋ณด์ํ ์ ์๋ ๋ฐฉ๋ฒ์ด ๋ฐ๋ก Connection Pool์ด๋ค.
์ปค๋ฅ์ ํ(Connection Pool)์ด๋?
์ปค๋ฅ์ ํ์ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ฐ๊ฒฐ๋ ์ปค๋ฅ์ ์ ๋ฏธ๋ฆฌ ๋ง๋ค์ด ๋๊ณ ์ด๋ฅผ pool๋ก ๊ด๋ฆฌํ๋ ๊ฒ์ด๋ค.
์ฆ, ํ์ํ ๋๋ง๋ค ์ปค๋ฅ์ ํ์ ์ปค๋ฅ์ ์ ์ด์ฉํ๊ณ ๋ฐํํ๋ ๊ธฐ๋ฒ์ด๋ค.
์ด์ฒ๋ผ ๋ฏธ๋ฆฌ ๋ง๋ค์ด ๋์ ์ปค๋ฅ์ ์ ์ด์ฉํ๋ฉด Connection์ ํ์ํ ๋น์ฉ์ ์ค์ผ ์ ์๋ค.
๋ฐ๋ผ์ DB์ ๋น ๋ฅด๊ฒ ์ ์ํ ์ ์๋ค.
์์ ์ฝ๋ ์์ฑ
๊ฐ๋จํ๊ฒ ์ธ๋ถ ๋คํธ์ํฌ์ ๋ฏธ๋ฆฌ ์ฐ๊ฒฐํ๋ ๊ฐ์ฒด๋ฅผ ํ๋ ์์ฑํ๋ค๊ณ ๊ฐ์ ํด๋ณด์.
์ค์ ๋ก ๋คํธ์ํฌ์ ์ฐ๊ฒฐํ๋ ๊ฒ์ ์๋๊ณ , ๋จ์ํ ๋ฌธ์๋ง ์ถ๋ ฅํ๋๋ก ํ๋ค.
์ด NetworkClient ๋ ์ ํ๋ฆฌ์ผ์ด์ ์์ ์์ ์ connect() ๋ฅผ ํธ์ถํด์ ์ฐ๊ฒฐ์ ๋งบ์ด๋์ด์ผ ํ๊ณ ,
์ ํ๋ฆฌ์ผ์ด์ ์ด ์ข ๋ฃ๋๋ฉด disConnect() ๋ฅผ ํธ์ถํด์ ์ฐ๊ฒฐ์ ๋์ด์ผ ํ๋ค.
@Configuration
static class LifeCycleConfig {
@Bean
public NetworkClient networkClient() {
NetworkClient networkClient = new NetworkClient();
networkClient.setUrl("http://hello-spring.dev");
new NetworkClient() : ๊ฐ์ฒด๋ฅผ ์์ฑ --> ์์ฑ์ ํธ์ถ ( url ์์ )
setUrl : url ์์ ์ ์ฃผ์
public NetworkClient() {
System.out.println("์์ฑ์ ํธ์ถ , url = " + url);
connect();
call("์ด๊ธฐํ ์ฐ๊ฒฐ ๋ฉ์์ง");
}
์์ฑ์
๊ฐ์ฒด๊ฐ ์์ฑ๋ ๋(new) ํธ์ถํ๋ ๋ฉ์๋
์์ฑ์ ๋ถ๋ถ์ ๋ณด๋ฉด url ์ ๋ณด ์์ด connect๊ฐ ํธ์ถ๋๋ ๊ฒ์ ํ์ธํ ์ ์๋ค.
๋๋ฌด ๋น์ฐํ ์ด์ผ๊ธฐ์ด์ง๋ง ๊ฐ์ฒด๋ฅผ ์์ฑํ๋ ๋จ๊ณ์๋ url์ด ์๊ณ ,
๊ฐ์ฒด๋ฅผ ์์ฑํ ๋ค์์ ์ธ๋ถ์์ ์์ ์ ์ฃผ์ ์ ํตํด์ setUrl() ์ด ํธ์ถ๋์ด์ผ url์ด ์กด์ฌํ๊ฒ ๋๋ค.
์คํ๋ง ๋น์ ๊ฐ๋จํ๊ฒ ๋ค์๊ณผ ๊ฐ์ ๋ผ์ดํ์ฌ์ดํด์ ๊ฐ์ง๋ค.
๊ฐ์ฒด ์์ฑ -> ์์กด๊ด๊ณ ์ฃผ์
์คํ๋ง ๋น์ ๊ฐ์ฒด๋ฅผ ์์ฑํ๊ณ , ์์กด๊ด๊ณ ์ฃผ์ ์ด ๋ค ๋๋ ๋ค์์์ผ ํ์ํ ๋ฐ์ดํฐ๋ฅผ ์ฌ์ฉํ ์ ์๋ ์ค๋น๊ฐ ์๋ฃ๋๋ค.
๋ฐ๋ผ์ ์ด๊ธฐํ ์์ ์ ์์กด๊ด๊ณ ์ฃผ์ ์ด ๋ชจ๋ ์๋ฃ๋๊ณ ๋ ๋ค์์ ํธ์ถํด์ผ ํ๋ค.
๊ทธ๋ฐ๋ฐ ๊ฐ๋ฐ์๊ฐ ์์กด๊ด๊ณ ์ฃผ์ ์ด ๋ชจ๋ ์๋ฃ๋ ์์ ์ ์ด๋ป๊ฒ ์ ์ ์์๊น?
์คํ๋ง ๋น์ ์ด๋ฒคํธ ๋ผ์ดํ์ฌ์ดํด
์คํ๋ง์ ์์กด๊ด๊ณ ์ฃผ์ ์ด ์๋ฃ๋๋ฉด ์คํ๋ง ๋น์๊ฒ ์ฝ๋ฐฑ ๋ฉ์๋๋ฅผ ํตํด์ ์ด๊ธฐํ ์์ ์ ์๋ ค์ฃผ๋ ๋ค์ํ ๊ธฐ๋ฅ์ ์ ๊ณตํ๋ค.
๋ํ ์คํ๋ง์ ์คํ๋ง ์ปจํ ์ด๋๊ฐ ์ข ๋ฃ๋๊ธฐ ์ง์ ์ ์๋ฉธ ์ฝ๋ฐฑ์ ์ค๋ค. ๋ฐ๋ผ์ ์์ ํ๊ฒ ์ข ๋ฃ ์์ ์ ์งํํ ์ ์๋ค.
์คํ๋ง์ปจํ ์ด๋์์ฑ -> ์คํ๋ง๋น์์ฑ -> ์์กด๊ด๊ณ์ฃผ์ -> ์ด๊ธฐํ ์ฝ๋ฐฑ -> ์๋ฉธ์ ์ฝ๋ฐฑ -> ์คํ๋ง ์ข ๋ฃ
์ด๊ธฐํ ์ฝ๋ฐฑ: ๋น์ด ์์ฑ๋๊ณ , ๋น์ ์์กด๊ด๊ณ ์ฃผ์ ์ด ์๋ฃ๋ ํ ํธ์ถ
์๋ฉธ์ ์ฝ๋ฐฑ: ๋น์ด ์๋ฉธ๋๊ธฐ ์ง์ ์ ํธ์ถ
์ฐธ๊ณ : ๊ฐ์ฒด์ ์์ฑ๊ณผ ์ด๊ธฐํ๋ฅผ ๋ถ๋ฆฌํ์.
์์ฑ์๋ ํ์ ์ ๋ณด(ํ๋ผ๋ฏธํฐ)๋ฅผ ๋ฐ๊ณ , ๋ฉ๋ชจ๋ฆฌ๋ฅผ ํ ๋นํด์ ๊ฐ์ฒด๋ฅผ ์์ฑํ๋ ์ฑ ์์ ๊ฐ์ง๋ค.
๋ฐ๋ฉด์ ์ด๊ธฐํ๋ ์ด๋ ๊ฒ ์์ฑ๋ ๊ฐ๋ค์ ํ์ฉํด์ ์ธ๋ถ ์ปค๋ฅ์ ์ ์ฐ๊ฒฐํ๋๋ฑ ๋ฌด๊ฑฐ์ด ๋์์ ์ํํ๋ค.
๋ฐ๋ผ์ ์์ฑ์ ์์์ ๋ฌด๊ฑฐ์ด ์ด๊ธฐํ ์์ ์ ํจ๊ป ํ๋ ๊ฒ ๋ณด๋ค๋
๊ฐ์ฒด๋ฅผ ์์ฑํ๋ ๋ถ๋ถ๊ณผ ์ด๊ธฐํ ํ๋ ๋ถ๋ถ์ ๋ช ํํ๊ฒ ๋๋๋ ๊ฒ์ด ์ ์ง๋ณด์ ๊ด์ ์์ ์ข๋ค.
๋ฌผ๋ก ์ด๊ธฐํ ์์ ์ด ๋ด๋ถ ๊ฐ๋ค๋ง ์ฝ๊ฐ ๋ณ๊ฒฝํ๋ ์ ๋๋ก ๋จ์ํ ๊ฒฝ์ฐ์๋ ์์ฑ์์์ ํ๋ฒ์ ๋ค ์ฒ๋ฆฌํ๋๊ฒ ๋ ๋์ ์ ์๋ค.
์ฑ๊ธํค ๋น๋ค์ ์คํ๋ง ์ปจํ ์ด๋๊ฐ ์ข ๋ฃ๋ ๋ ์ฑ๊ธํค ๋น๋ค๋ ํจ๊ป ์ข ๋ฃ๋๊ธฐ ๋๋ฌธ์
์คํ๋ง ์ปจํ ์ด๋๊ฐ ์ข ๋ฃ๋๊ธฐ ์ง์ ์ ์๋ฉธ์ ์ฝ๋ฐฑ์ด ์ผ์ด๋๋ค.
๋ค์์ ์ค๋ช ํ๊ฒ ์ง๋ง ์ฑ๊ธํค ์ฒ๋ผ ์ปจํ ์ด๋์ ์์๊ณผ ์ข ๋ฃ๊น์ง ์์กดํ๋ ๋น๋ ์์ง๋ง,
์๋ช ์ฃผ๊ธฐ๊ฐ ์งง์ ๋น๋ค๋ ์๋๋ฐ ์ด ๋น๋ค์ ์ปจํ ์ด๋์ ๋ฌด๊ดํ๊ฒ ํด๋น ๋น์ด ์ข ๋ฃ๋๊ธฐ ์ง์ ์ ์๋ฉธ์ ์ฝ๋ฐฑ์ด ์ผ์ด๋๋ค.
์์ธํ ๋ด์ฉ์ ์ค์ฝํ์์ ์์๋ณด๊ฒ ๋ค.
์คํ๋ง์ ํฌ๊ฒ 3๊ฐ์ง ๋ฐฉ๋ฒ์ผ๋ก ๋น ์๋ช ์ฃผ๊ธฐ ์ฝ๋ฐฑ์ ์ง์ํ๋ค.
- ์ธํฐํ์ด์ค(InitializingBean, DisposableBean)
- ์ค์ ์ ๋ณด์ ์ด๊ธฐํ ๋ฉ์๋, ์ข ๋ฃ ๋ฉ์๋ ์ง์
- @PostConstruct, @PreDestroy ์ ๋ ธํ ์ด์ ์ง์
์ธํฐํ์ด์ค InitializingBean, DisposableBean
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
public class NetworkClient implements InitializingBean, DisposableBean {
InitializingBean,DisposableBean ์ธํฐํ์ด์ค
@Override
// ์์กด๊ด๊ณ ์ฃผ์
์ด ๋๋๋ฉด ํธ์ถ
public void afterPropertiesSet() throws Exception {
System.out.println("NetworkClient.afterPropertiesSet");
connect();
call("์ด๊ธฐํ ์ฐ๊ฒฐ ๋ฉ์์ง");
}
InitializingBean ์ afterPropertiesSet() ๋ฉ์๋๋ก ์ด๊ธฐํ๋ฅผ ์ง์ํ๋ค.
@Override
// ๋น์ด ์ข
๋ฃ๋ ๋ ํธ์ถ
public void destroy() throws Exception {
System.out.println("NetworkClient.destroy");
disconnect();
}
DisposableBean ์ destroy() ๋ฉ์๋๋ก ์๋ฉธ์ ์ง์ํ๋ค.
์ถ๋ ฅ ๊ฒฐ๊ณผ๋ฅผ ๋ณด๋ฉด ์ด๊ธฐํ ๋ฉ์๋๊ฐ ์ฃผ์ ์๋ฃ ํ์ ์ ์ ํ๊ฒ ํธ์ถ ๋ ๊ฒ์ ํ์ธํ ์ ์๋ค.
๊ทธ๋ฆฌ๊ณ ์คํ๋ง ์ปจํ ์ด๋์ ์ข ๋ฃ๊ฐ ํธ์ถ๋์ ์๋ฉธ ๋ฉ์๋๊ฐ ํธ์ถ ๋ ๊ฒ๋ ํ์ธํ ์ ์๋ค.
์ด๊ธฐํ, ์๋ฉธ ์ธํฐํ์ด์ค ๋จ์
์ด ์ธํฐํ์ด์ค๋ ์คํ๋ง ์ ์ฉ ์ธํฐํ์ด์ค๋ค.
ํด๋น ์ฝ๋๊ฐ ์คํ๋ง ์ ์ฉ ์ธํฐํ์ด์ค์ ์์กดํ๋ค. ์ด๊ธฐํ, ์๋ฉธ ๋ฉ์๋์ ์ด๋ฆ์ ๋ณ๊ฒฝํ ์ ์๋ค.
๋ด๊ฐ ์ฝ๋๋ฅผ ๊ณ ์น ์ ์๋ ์ธ๋ถ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ์ ์ฉํ ์ ์๋ค.
์ง๊ธ์ ๋ค์์ ๋ ๋์ ๋ฐฉ๋ฒ๋ค์ด ์์ด์ ๊ฑฐ์ ์ฌ์ฉํ์ง ์๋๋ค.
๋น ๋ฑ๋ก ์ด๊ธฐํ, ์๋ฉธ ๋ฉ์๋ ์ง์
// ์์กด๊ด๊ณ ์ฃผ์
์ด ๋๋๋ฉด ํธ์ถ
public void init() {
System.out.println("NetworkClient.init");
connect();
call("์ด๊ธฐํ ์ฐ๊ฒฐ ๋ฉ์์ง");
}
์ด๊ธฐํ ๋ฉ์๋ init
// ์ปจํ
์ด๋๊ฐ ์ข
๋ฃ๋ ๋ ํธ์ถ
public void close() {
System.out.println("NetworkClient.close");
disconnect();
}
์๋ฉธ ๋ฉ์๋ close
@Bean(initMethod = "init", destroyMethod = "close")
์ด๊ธฐํ, ์๋ฉธ ๋ฉ์๋๋ฅผ ์ง์ ํ ์ ์๋ค.
์ค์ ์ ๋ณด ์ฌ์ฉ ํน์ง
๋ฉ์๋ ์ด๋ฆ์ ์์ ๋กญ๊ฒ ์ค ์ ์๋ค.
์คํ๋ง ๋น์ด ์คํ๋ง ์ฝ๋์ ์์กดํ์ง ์๋๋ค.
์ฝ๋๊ฐ ์๋๋ผ ์ค์ ์ ๋ณด๋ฅผ ์ฌ์ฉํ๊ธฐ ๋๋ฌธ์ ์ฝ๋๋ฅผ ๊ณ ์น ์ ์๋ ์ธ๋ถ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์๋ ์ด๊ธฐํ, ์ข
๋ฃ ๋ฉ์๋๋ฅผ ์ ์ฉํ ์ ์๋ค.
์ข ๋ฃ ๋ฉ์๋ ์ถ๋ก
@Bean์ destroyMethod ์์ฑ์๋ ์์ฃผ ํน๋ณํ ๊ธฐ๋ฅ์ด ์๋ค.
๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ ๋๋ถ๋ถ close , shutdown ์ด๋ผ๋ ์ด๋ฆ์ ์ข
๋ฃ ๋ฉ์๋๋ฅผ ์ฌ์ฉํ๋ค.
@Bean์ destroyMethod ๋ ๊ธฐ๋ณธ๊ฐ์ด (inferred) (์ถ๋ก )์ผ๋ก ๋ฑ๋ก๋์ด ์๋ค.
์ด ์ถ๋ก ๊ธฐ๋ฅ์ close , shutdown ๋ผ๋ ์ด๋ฆ์ ๋ฉ์๋๋ฅผ ์๋์ผ๋ก ํธ์ถํด์ค๋ค. ์ด๋ฆ ๊ทธ๋๋ก ์ข
๋ฃ ๋ฉ์๋๋ฅผ ์ถ๋ก ํด์ ํธ์ถํด์ค๋ค.
๋ฐ๋ผ์ ์ง์ ์คํ๋ง ๋น์ผ๋ก ๋ฑ๋กํ๋ฉด ์ข
๋ฃ ๋ฉ์๋๋ ๋ฐ๋ก ์ ์ด์ฃผ์ง ์์๋ ์ ๋์ํ๋ค.
์ถ๋ก ๊ธฐ๋ฅ์ ์ฌ์ฉํ๊ธฐ ์ซ์ผ๋ฉด destroyMethod="" ์ฒ๋ผ ๋น ๊ณต๋ฐฑ์ ์ง์ ํ๋ฉด ๋๋ค.
์ ๋ ธํ ์ด์ @PostConstruct, @PreDestroy
@PostConstruct , @PreDestroy ์ด ๋ ์ ๋ ธํ ์ด์ ์ ์ฌ์ฉํ๋ฉด ๊ฐ์ฅ ํธ๋ฆฌํ๊ฒ ์ด๊ธฐํ์ ์ข ๋ฃ๋ฅผ ์คํํ ์ ์๋ค.
@PostConstruct
public void init() {
System.out.println("NetworkClient.init");
connect();
call("์ด๊ธฐํ ์ฐ๊ฒฐ ๋ฉ์์ง");
}
@PostConstruct
@PreDestroy
public void close() {
System.out.println("NetworkClient.close");
disconnect();
}
@PreDestroy
@PostConstruct, @PreDestroy ์ ๋ ธํ ์ด์ ํน์ง
์ต์ ์คํ๋ง์์ ๊ฐ์ฅ ๊ถ์ฅํ๋ ๋ฐฉ๋ฒ์ด๋ค.
์ ๋
ธํ
์ด์
ํ๋๋ง ๋ถ์ด๋ฉด ๋๋ฏ๋ก ๋งค์ฐ ํธ๋ฆฌํ๋ค.
ํจํค์ง๋ฅผ ์ ๋ณด๋ฉด javax.annotation.PostConstruct ์ด๋ค.
์คํ๋ง์ ์ข ์์ ์ธ ๊ธฐ์ ์ด ์๋๋ผ JSR-250 ๋ผ๋ ์๋ฐ ํ์ค์ด๋ค. ๋ฐ๋ผ์ ์คํ๋ง์ด ์๋ ๋ค๋ฅธ ์ปจํ ์ด๋์์๋ ๋์ํ๋ค.
์ปดํฌ๋ํธ ์ค์บ๊ณผ ์ ์ด์ธ๋ฆฐ๋ค.
์ ์ผํ ๋จ์ ์ ์ธ๋ถ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์๋ ์ ์ฉํ์ง ๋ชปํ๋ค๋ ๊ฒ์ด๋ค.
์ธ๋ถ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ด๊ธฐํ, ์ข ๋ฃ ํด์ผ ํ๋ฉด @Bean์ ๊ธฐ๋ฅ์ ์ฌ์ฉํ์.
์ ๋ฆฌ
@PostConstruct, @PreDestroy ์ ๋
ธํ
์ด์
์ ์ฌ์ฉํ์
์ฝ๋๋ฅผ ๊ณ ์น ์ ์๋ ์ธ๋ถ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ด๊ธฐํ, ์ข ๋ฃํด์ผ ํ๋ฉด @Bean ์ initMethod , destroyMethod ๋ฅผ ์ฌ์ฉํ์.