[Spring] 8.๋น ์๋ช ์ฃผ๊ธฐ ์ฝ๋ฐฑ
1. ๋น ์๋ช ์ฃผ๊ธฐ ์ฝ๋ฐฑ ์์
- DB ์ปค๋ฅ์ ํ / ๋คํธ์ํฌ ์์ผ์ฒ๋ผ ์ ํ๋ฆฌ์ผ์ด์ ์์ ์์ ์ ํ์ํ ์ฐ๊ฒฐ์ ๋ฏธ๋ฆฌ ํด๋๊ณ , ์ ํ๋ฆฌ์ผ์ด์ ์ข ๋ฃ ์์ ์ ์ฐ๊ฒฐ์ ๋ชจ๋ ์ข ๋ฃํ๋ ์์ ์ ์งํํ๋ ค๋ฉด [๊ฐ์ฒด์ ์ด๊ธฐํ]์ [์ข ๋ฃ ์์ ]์ด ํ์
ex) ๊ฐ๋จํ๊ฒ ์ธ๋ถ ๋คํธ์ํฌ์ ๋ฏธ๋ฆฌ ์ฐ๊ฒฐํ๋ ๊ฐ์ฒด๋ฅผ ํ๋ ์์ฑํ๋ค๊ณ ๊ฐ์
์ค์ ๋ก ๋คํธ์ํฌ์ ์ฐ๊ฒฐํ๋ ๊ฒ์ ์๋๊ณ , ๋จ์ํ ๋ฌธ์๋ง ์ถ๋ ฅ
NetworkClient ๋ ์ ํ๋ฆฌ์ผ์ด์ ์์ ์์ ์ connect() ๋ฅผ ํธ์ถํด์ ์ฐ๊ฒฐ์ ๋งบ์ด๋์ด์ผ ํ๊ณ , ์ ํ๋ฆฌ์ผ์ด์ ์ด ์ข ๋ฃ๋๋ฉด disConnect() ๋ฅผ ํธ์ถํด์ ์ฐ๊ฒฐ์ ๋์ด์ผ ํจ
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);
}
}
์คํ๋ง ํ๊ฒฝ์ค์ ๊ณผ ์คํ
public class BeanLifeCycleTest {
@Test
public void lifeCycleTest() {
ConfigurableApplicationContext ac = new AnnotationConfigApplicationContext(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 = null
connect: null call: null message = ์ด๊ธฐํ ์ฐ๊ฒฐ ๋ฉ์์ง |
์์ฑ์ ๋ถ๋ถ์ ๋ณด๋ฉด url ์ ๋ณด ์์ด connect๊ฐ ํธ์ถ
๊ฐ์ฒด๋ฅผ ์์ฑํ๋ ๋จ๊ณ์๋ url์ด ์๊ณ , ๊ฐ์ฒด๋ฅผ ์์ฑํ ๋ค์์ ์ธ๋ถ์์ ์์ ์ ์ฃผ์
์ ํตํด์ setUrl() ์ด ํธ์ถ๋์ด์ผ url์ด ์กด์ฌํ๊ฒ ๋จ
<์คํ๋ง ๋น์ ๋ผ์ดํ ์ฌ์ดํด>
๊ฐ์ฒด ์์ฑ -> ์์กด๊ด๊ณ ์ฃผ์
์คํ๋ง ๋น์ ๊ฐ์ฒด๋ฅผ ์์ฑํ๊ณ , ์์กด๊ด๊ณ ์ฃผ์
์ด ๋ค ๋๋ ๋ค์์์ผ ํ์ํ ๋ฐ์ดํฐ๋ฅผ ์ฌ์ฉํ ์ ์๋ ์ค๋น๊ฐ ์๋ฃ๋๋ค.
๋ฐ๋ผ์ ์ด๊ธฐํ ์์ ์ ์์กด๊ด๊ณ ์ฃผ์ ์ด ๋ชจ๋ ์๋ฃ๋๊ณ ๋ ๋ค์์ ํธ์ถํด์ผ ํ๋ค. ๊ทธ๋ฐ๋ฐ ๊ฐ๋ฐ์๊ฐ ์์กด๊ด๊ณ ์ฃผ์ ์ด ๋ชจ๋ ์๋ฃ๋ ์์ ์ ์ด๋ป๊ฒ ์ ์ ์์๊น? ์คํ๋ง์ ์์กด๊ด๊ณ ์ฃผ์ ์ด ์๋ฃ๋๋ฉด ์คํ๋ง ๋น์๊ฒ ์ฝ๋ฐฑ ๋ฉ์๋๋ฅผ ํตํด์ ์ด๊ธฐํ ์์ ์ ์๋ ค์ฃผ๋ ๋ค์ํ ๊ธฐ๋ฅ์ ์ ๊ณตํ๋ค. ๋ํ ์คํ๋ง์ ์คํ๋ง ์ปจํ ์ด๋๊ฐ ์ข ๋ฃ๋๊ธฐ ์ง์ ์ ์๋ฉธ ์ฝ๋ฐฑ์ ์ค๋ค. ๋ฐ๋ผ์ ์์ ํ๊ฒ ์ข ๋ฃ ์์ ์ ์งํํ ์ ์๋ค. |
์์ธ) ์์ฑ์ ์ฃผ์ (๊ฐ์ฒด ๋ง๋ค๋ ์ด๋ฏธ ํ๋ผ๋ฏธํฐ์ ์คํ๋ง ๋น์ด ๋ค์ด์์ผํ๊ธฐ ๋๋ฌธ์ ์์กด๊ด๊ณ ๋์์)
์คํ๋ง ๋น์ ์ด๋ฒคํธ ๋ผ์ดํ์ฌ์ดํด
[์คํ๋ง ์ปจํ ์ด๋ ์์ฑ] -> [์คํ๋ง ๋น ์์ฑ] -> [์์กด๊ด๊ณ ์ฃผ์ ] -> [์ด๊ธฐํ ์ฝ๋ฐฑ] -> [์ฌ์ฉ] -> [์๋ฉธ์ ์ฝ๋ฐฑ] -> [์คํ๋ง ์ข ๋ฃ]
- ์ด๊ธฐํ ์ฝ๋ฐฑ : ๋น์ด ์์ฑ๋๊ณ ๋น์ ์์กด๊ด๊ณ ์ฃผ์ ์ด ์๋ฃ๋ ํ ํธ์ถ
- ์๋ฉธ์ ์ฝ๋ฐฑ : ๋น์ด ์๋ฉธ๋๊ธฐ ์ง์ ์ ํธ์ถ
์คํ๋ง์ ๋ค์ํ ๋ฐฉ์์ผ๋ก ์๋ช ์ฃผ๊ธฐ ์ฝ๋ฐฑ์ ์ง์
์ฐธ๊ณ : ๊ฐ์ฒด์ ์์ฑ๊ณผ ์ด๊ธฐํ๋ฅผ ๋ถ๋ฆฌํ์
์์ฑ์๋ ํ์ ์ ๋ณด(ํ๋ผ๋ฏธํฐ)๋ฅผ ๋ฐ๊ณ , ๋ฉ๋ชจ๋ฆฌ๋ฅผ ํ ๋นํด์ ๊ฐ์ฒด๋ฅผ ์์ฑํ๋ ์ฑ
์์ ๊ฐ์ง๋ค. ๋ฐ๋ฉด์ ์ด๊ธฐํ๋ ์ด๋ ๊ฒ ์์ฑ๋ ๊ฐ๋ค์ ํ์ฉํด์ ์ธ๋ถ ์ปค๋ฅ์ ์ ์ฐ๊ฒฐํ๋๋ฑ ๋ฌด๊ฑฐ์ด ๋์์ ์ํํ๋ค. ๋ฐ๋ผ์ ์์ฑ์ ์์์ ๋ฌด๊ฑฐ์ด ์ด๊ธฐํ ์์ ์ ํจ๊ป ํ๋ ๊ฒ ๋ณด๋ค๋, ๊ฐ์ฒด๋ฅผ ์์ฑํ๋ ๋ถ๋ถ๊ณผ ์ด๊ธฐํ ํ๋ ๋ถ๋ถ์ ๋ช ํํ๊ฒ ๋๋๋ ๊ฒ์ด ์ ์ง๋ณด์ ๊ด์ ์์ ์ข๋ค. ๋ฌผ๋ก ์ด๊ธฐํ ์์ ์ด ๋ด๋ถ ๊ฐ๋ค๋ง ์ฝ๊ฐ ๋ณ๊ฒฝํ๋ ์ ๋๋ก ๋จ์ํ ๊ฒฝ์ฐ์๋ ์์ฑ์์์ ํ๋ฒ์ ๋ค ์ฒ๋ฆฌํ๋๊ฒ ๋ ๋์ ์ ์๋ค |
์ฐธ๊ณ :
์ฑ๊ธํค ๋น๋ค์ ์คํ๋ง ์ปจํ
์ด๋๊ฐ ์ข
๋ฃ๋ ๋ ์ฑ๊ธํค ๋น๋ค๋ ํจ๊ป ์ข
๋ฃ๋๊ธฐ ๋๋ฌธ์ ์คํ๋ง ์ปจํ
์ด๋๊ฐ ์ข
๋ฃ๋๊ธฐ ์ง์ ์ ์๋ฉธ์ ์ฝ๋ฐฑ์ด ์ผ์ด๋๋ค. ์ฑ๊ธํค ์ฒ๋ผ ์ปจํ ์ด๋์ ์์๊ณผ ์ข ๋ฃ๊น์ง ์์กดํ๋ ๋น๋ ์์ง๋ง, ์๋ช ์ฃผ๊ธฐ๊ฐ ์งง์ ๋น๋ค๋ ์๋๋ฐ - ์ด ๋น๋ค์ ์ปจํ ์ด๋์ ๋ฌด๊ดํ๊ฒ ํด๋น ๋น์ด ์ข ๋ฃ๋๊ธฐ ์ง์ ์ ์๋ฉธ์ ์ฝ๋ฐฑ์ด ์ผ์ด๋๋ค. ์์ธํ ๋ด์ฉ์ ์ค์ฝํ์์ ์์๋ณด๊ฒ ๋ค. |
์คํ๋ง์ ํฌ๊ฒ 3๊ฐ์ง ๋ฐฉ๋ฒ์ผ๋ก ๋น ์๋ช ์ฃผ๊ธฐ ์ฝ๋ฐฑ์ ์ง์ํ๋ค.
1) ์ธํฐํ์ด์ค(InitializingBean, DisposableBean)
2) ์ค์ ์ ๋ณด์ ์ด๊ธฐํ ๋ฉ์๋, ์ข
๋ฃ ๋ฉ์๋ ์ง์
3) @PostConstruct, @PreDestroy ์ ๋ ธํ ์ด์ ์ง์
2. ๋น ์๋ช ์ฃผ๊ธฐ ์ฝ๋ฐฑ ์ง์ 1 - ์ธํฐํ์ด์ค(initializingBean, DisposableBean)
- DB ์ปค๋ฅ์ ํ / ๋คํธ์ํฌ ์์ผ์ฒ๋ผ ์ ํ๋ฆฌ์ผ์ด์ ์์ ์์ ์ ํ์ํ ์ฐ๊ฒฐ์ ๋ฏธ๋ฆฌ ํด๋๊ณ , ์ ํ๋ฆฌ์ผ์ด์ ์ข ๋ฃ ์์ ์ ์ฐ๊ฒฐ์ ๋ชจ๋ ์ข ๋ฃํ๋ ์์ ์ ์งํํ๋ ค๋ฉด [๊ฐ์ฒด์ ์ด๊ธฐํ]์ [์ข ๋ฃ ์์ ]์ด ํ์
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 |
- ์ด๊ธฐํ ๋ฉ์๋๊ฐ ์ฃผ์ ์๋ฃ ํ ์ ์ ํ๊ฒ ํธ์ถ ๋จ
- ์คํ๋ง ์ปจํ ์ด๋์ ์ข ๋ฃ๊ฐ ํธ์ถ๋์ ์๋ฉธ ๋ฉ์๋ ํธ์ถ ๋จ
[์ด๊ธฐํ, ์๋ฉธ ์ธํฐํ์ด์ค ๋จ์ ]
- ์คํ๋ง ์ ์ฉ (์คํ๋ง ์ ์ฉ ์ธํฐํ์ด์ค์ ์์กด)
- ์ด๊ธฐํ, ์๋ฉธ ๋ฉ์๋ ์ด๋ฆ ๋ณ๊ฒฝ ๋ถ๊ฐ
- ๋ด๊ฐ ์ฝ๋ ๊ณ ์น ์์๋ ์ธ๋ถ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ์ ์ฉ ๋ถ๊ฐ
์ฐธ๊ณ ) ์ธํฐํ์ด์ค๋ฅผ ์ด๊ธฐํ,์ข ๋ฃ ๋ฐฉ๋ฒ์ ์คํ๋ง ์ด์ฐฝ๊ธฐ ๋ฐฉ๋ฒ / ์ง๊ธ์ ๋ ๋์ ๋ฐฉ๋ฒ์ด ์์ด ๊ฑฐ์ ์ฌ์ฉ X
3. ๋น ์๋ช ์ฃผ๊ธฐ ์ฝ๋ฐฑ ์ง์ 2 - ๋น ๋ฑ๋ก ์ด๊ธฐํ, ์๋ฉธ ๋ฉ์๋ ์ง์
- ์ค์ ์ ๋ณด์ @Bean(initMethod = "init", destroyMethod = "close") ์ฒ๋ผ ์ด๊ธฐํ, ์๋ฉธ ๋ฉ์๋๋ฅผ ์ง์ ํ ์ ์๋ค.
์ค์ ์ ๋ณด๋ฅผ ์ฌ์ฉํ๋๋ก ๋ณ๊ฒฝ
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
static class LifeCycleConfig {
@Bean(initMethod = "init", destroyMethod = "close")
public NetworkClient networkClient() {
NetworkClient networkClient = new NetworkClient();
networkClient.setUrl("http://hello-spring.dev");
return networkClient;
}
}
์ค์ ์ ๋ณด ์ฌ์ฉ ํน์ง
1) ๋ฉ์๋ ์ด๋ฆ์ ์์ ๋กญ๊ฒ ์ค ์ ์๋ค.
2) ์คํ๋ง ๋น์ด ์คํ๋ง ์ฝ๋์ ์์กดํ์ง ์๋๋ค. 3) ์ฝ๋๊ฐ ์๋๋ผ ์ค์ ์ ๋ณด๋ฅผ ์ฌ์ฉํ๊ธฐ ๋๋ฌธ์ ์ฝ๋๋ฅผ ๊ณ ์น ์ ์๋ ์ธ๋ถ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์๋ ์ด๊ธฐํ, ์ข ๋ฃ ๋ฉ์๋๋ฅผ ์ ์ฉํ ์ ์๋ค |
์ข ๋ฃ ๋ฉ์๋ ์ถ๋ก
- @Bean์ destroyMethod ์์ฑ์๋ ์์ฃผ ํน๋ณํ ๊ธฐ๋ฅ์ด ์๋ค.
- ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ ๋๋ถ๋ถ close , shutdown ์ด๋ผ๋ ์ด๋ฆ์ ์ข ๋ฃ ๋ฉ์๋๋ฅผ ์ฌ์ฉํ๋ค. - @Bean์ destroyMethod ๋ ๊ธฐ๋ณธ๊ฐ์ด (inferred) (์ถ๋ก )์ผ๋ก ๋ฑ๋ก๋์ด ์๋ค. - ์ด ์ถ๋ก ๊ธฐ๋ฅ์ close , shutdown ๋ผ๋ ์ด๋ฆ์ ๋ฉ์๋๋ฅผ ์๋์ผ๋ก ํธ์ถํด์ค๋ค. ์ด๋ฆ ๊ทธ๋๋ก ์ข ๋ฃ ๋ฉ์๋๋ฅผ ์ถ๋ก ํด์ ํธ์ถํด์ค๋ค. - ๋ฐ๋ผ์ ์ง์ ์คํ๋ง ๋น์ผ๋ก ๋ฑ๋กํ๋ฉด ์ข ๋ฃ ๋ฉ์๋๋ ๋ฐ๋ก ์ ์ด์ฃผ์ง ์์๋ ์ ๋์ํ๋ค. - ์ถ๋ก ๊ธฐ๋ฅ์ ์ฌ์ฉํ๊ธฐ ์ซ์ผ๋ฉด destroyMethod="" ์ฒ๋ผ ๋น ๊ณต๋ฐฑ์ ์ง์ ํ๋ฉด ๋๋ค. |
4. ๋น ์๋ช ์ฃผ๊ธฐ ์ฝ๋ฐฑ ์ง์ 3 - @PostConstruct, @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;
}
}
javax.annotaion.PostConstruct
javax.annotaion.PreDestroy
-> javax ์์ํ๋ฉด ์๋ฐ ์ง์์์ ๊ณต์์ ์ผ๋ก ์ง์
@PostConstruct, @PreDestroy ์ ๋ ธํ ์ด์ ํน์ง
- ์ต์ ์คํ๋ง์์ ๊ฐ์ฅ ๊ถ์ฅํ๋ ๋ฐฉ๋ฒ์ด๋ค.
- ์ ๋ ธํ ์ด์ ํ๋๋ง ๋ถ์ด๋ฉด ๋๋ฏ๋ก ๋งค์ฐ ํธ๋ฆฌํ๋ค. - ํจํค์ง๋ฅผ ์ ๋ณด๋ฉด javax.annotation.PostConstruct ์ด๋ค. ์คํ๋ง์ ์ข ์์ ์ธ ๊ธฐ์ ์ด ์๋๋ผ JSR-250 ๋ผ๋ ์๋ฐ ํ์ค์ด๋ค. ๋ฐ๋ผ์ ์คํ๋ง์ด ์๋ ๋ค๋ฅธ ์ปจํ ์ด๋์์๋ ๋์ํ๋ค. - ์ปดํฌ๋ํธ ์ค์บ๊ณผ ์ ์ด์ธ๋ฆฐ๋ค. - ์ ์ผํ ๋จ์ ์ ์ธ๋ถ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์๋ ์ ์ฉํ์ง ๋ชปํ๋ค๋ ๊ฒ์ด๋ค. ์ธ๋ถ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ด๊ธฐํ, ์ข ๋ฃ ํด์ผ ํ๋ฉด @Bean์ ๊ธฐ๋ฅ์ ์ฌ์ฉํ์. |
์ ๋ฆฌ
@PostConstruct, @PreDestroy ์ ๋
ธํ
์ด์
์ ์ฌ์ฉํ์ ์ฝ๋๋ฅผ ๊ณ ์น ์ ์๋ ์ธ๋ถ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ด๊ธฐํ, ์ข ๋ฃํด์ผ ํ๋ฉด @Bean ์ initMethod , destroyMethod ๋ฅผ ์ฌ์ฉํ์. |
'๐จโ๐ป Web Development > Spring - ๊ธฐ๋ณธ' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[Spring] 9.๋น ์ค์ฝํ (0) | 2023.03.01 |
---|---|
[Spring] 7.๋ค์ํ ์์กด๊ด๊ณ ์ฃผ์ ๋ฐฉ๋ฒ (0) | 2023.02.28 |
[Spring] 6.์ปดํฌ๋ํธ ์ค์บ (0) | 2023.02.24 |
[Spring] 5.์ฑ๊ธํค ์ปจํ ์ด๋ (0) | 2023.02.22 |
[Spring] 4.์คํ๋ง ์ปจํ ์ด๋์ ์คํ๋ง ๋น (0) | 2023.02.20 |
์ต๊ทผ๋๊ธ