์ธํ๋ฐ ๊น์ํ๋์ ์คํ๋ง ํต์ฌ ์๋ฆฌ - ๊ธฐ๋ณธํธ ๊ฐ์ ๋ด์ฉ์ ๋ฐํ์ผ๋ก ์์ฑํ ๊ธ์ ๋๋ค.
1. ์ด๊ธฐํ ์์ ์ ํ์์ฑ
๋ฐ์ดํฐ๋ฒ ์ด์ค์์ ์ปค๋ฅ์ ์ ์ฐ๊ฒฐ์ ์ค์ ํ๋ ๋ฐ ์ค๋ ๊ฑธ๋ฆฌ๊ธฐ ๋๋ฌธ์, ์ ํ๋ฆฌ์ผ์ด์ ์๋ฒ์ DB ์ฌ์ด์ ์ปค๋ฅ์ ์ ๋ฏธ๋ฆฌ ์์ฑํด๋๋ค. ๊ทธ๋ฆฌ๊ณ DB ์ฐ๊ฒฐ ์์ฒญ์ด ์ค๋ฉด ์ฐ๊ฒฐํด๋์๋ ์ปค๋ฅ์ ์ ๋น๋ ค์ฃผ๋ ๋ฐฉ์์ผ๋ก ๋์ํ๋ค.
์ด ์ปค๋ฅ์ ์ ๋ณดํต ์ ํ๋ฆฌ์ผ์ด์ ์ด ์์๋๋ ์์ ์ ์์ฑ๋๊ณ , ์ ํ๋ฆฌ์ผ์ด์ ์ด ์ข ๋ฃ๋ ๋ ํจ๊ป ์ข ๋ฃ๋๋ค. ๋๋ฌธ์ ์ด๊ธฐํ์ ์ข ๋ฃ ์์ ์ด ํ์ํ๋ค.
๐ก์ด๊ธฐํ ์์ ์ ์์ฑ์์์ ์งํํ๋ฉด ์๋๋ ์ด์ ?
์์ฑ์๋ ์ด๋ฆ ๊ทธ๋๋ก ๊ฐ์ฒด ์์ฑ์ ์ํ ๋ฉ์๋์ด๋ค. ์์ฑ์๋ ์ด๊ธฐํ ์์ ๋ณด๋จ ๊ฐ์ฒด ์์ฑ์ ์ง์คํ๋ ๊ฒ์ด SRP์ ๋ ์๋ง๊ณ , ์ ์ง๋ณด์์ ์ธ ์ธก๋ฉด์์ ์ข๋ค. ์ด๊ธฐํ ์์ ์๋ ์ธ๋ถ ์ปค๋ฅ์ ์ฐ๊ฒฐ ๋ฑ ๋ฌด๊ฒ๊ณ ์์ธ๋ฅผ ๋ฐ์์ํฌ ์ ์๋ ์์ ์ด ํฌํจ๋๊ธฐ ๋๋ฌธ์ด๋ค. ์ด๋ฌํ ์ด์ ๋ก ์์ฑ์์์ ์ด๊ธฐํ ์์ ์ ๋ชจ๋ ์ํํด์ค ์ ์๊ธฐ ๋๋ฌธ์, ๋ณ๋์ ์ด๊ธฐํ ๋ฉ์๋๊ฐ ํ์ํ๋ค.
์์ ๊ฐ์ ์ด์ ๋ก, ์ปค๋ฅ์
url ๋ฑ์ ์ด๊ธฐํ ๋ฉ์๋๋ฅผ ํตํด ๋ณ๋๋ก ์ธํ
ํด์ฃผ์ด์ผ ํ๋ค.
์ด์ ์ฝ๋๋ฅผ ํตํด ์น ์๋ฒ๊ฐ ๋ ์๋ ์ํ์์, url๋ก ์์ฒญ์ด ๋ค์ด์จ ์ํฉ์ ์ดํด๋ณด์.
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();
}
@Configuration
static class LifeCycleConfig {
@Bean
public NetworkClient networkClient() {
NetworkClient networkClient = new NetworkClient();
networkClient.setUrl("http://hello-spring.dev");
return networkClient;
}
}
}
๐ก ConfigurableAppicationContext?
close()๋ ์ ์ฐ์ง ์๋ ๋ฉ์๋๋ผ์, ApplicationContext ์ธํฐํ์ด์ค์์๋ ์ ๊ณตํด์ฃผ์ง ์๋๋ค. ConfigurableApplicationContext๋ AnnotationConfigApplicationContext ์ธํฐํ์ด์ค๋ก ๊ต์ฒดํ์.
์ ์ฝ๋๋ฅผ ์คํํ๋ฉด ์๋์ ๊ฐ์ ๊ฒฐ๊ณผ๊ฐ ๋์จ๋ค.
๋น์ฐํ ๊ฒฐ๊ณผ๋ค. NetworkClient
์ ์์ฑ์๊ฐ ์คํ๋๋ ์์ ์์๋ url ์ ๋ณด๊ฐ ์๊ณ , ์ธ์คํด์ค ์์ฑ ํ์์ผ ์ธ๋ถ์์ ์์ ์ ์ฃผ์
์ ํตํด url์ ๋ฃ์ด์ฃผ๊ณ ์๊ธฐ ๋๋ฌธ์ด๋ค.
2. ์คํ๋ง ๋น์ ๋ผ์ดํ์ฌ์ดํด
์ด์ฒ๋ผ ์คํ๋ง ๋น์ ๊ฐ์ฒด๋ฅผ ๋ค ์์ฑํ๊ณ , ์์กด๊ด๊ณ ์ฃผ์ ์ ๋๋ธ ๋ค์์ผ ํ์ํ ๋ฐ์ดํฐ๋ฅผ ์ฌ์ฉํ ์ ์๋ค. ๊ทธ๋์ ์ด๊ธฐํ ์์ ์ ์์กด๊ด๊ณ ์ฃผ์ ์ดํ์ ์งํ๋๋ค.
๊ฐ๋ฐ์๋ ์์กด๊ด๊ณ ์ฃผ์
์ด ์ธ์ ์๋ฃ๋๋์ง ์ ์ ์๋ค. ๊ทธ๋์ ๊ฐ๋ฐ์๊ฐ ์์กด๊ด๊ณ ์ฃผ์
๋๋๋ฉด ์ด ๋ฉ์๋ ์คํํด์ค!
๋ผ๋ ์๋ฏธ๋ก ๋ฉ์๋๋ฅผ ๋ง๋ค์ด๋๋ฉด, ์์กด๊ด๊ณ ์ฃผ์
์ด ์๋ฃ๋ ์์ ์ ์คํ๋ง์ด ํด๋น ๋ฉ์๋๋ฅผ ํธ์ถํ์ฌ ์ด๊ธฐํ ์์
์ ์งํํ๋ค. ์ด๋ฌํ ๋ฉ์๋๋ฅผ ์ฝ๋ฐฑ ํจ์๋ผ๊ณ ํ๋๋ฐ, ์ด๊ธฐํ ์์
๋ ์คํ๋๋ ๋ฉ์๋๋ฅผ ์ด๊ธฐํ ์ฝ๋ฐฑ, ๋น ์๋ฉธ ๋ ์คํ๋๋ ๋ฉ์๋๋ฅผ ์๋ฉธ์ ์ฝ๋ฐฑ์ด๋ผ๊ณ ํ๋ค.
์ ๋ฆฌํ๋ฉด, ์คํ๋ง ๋น์ ์๋์ ๊ฐ์ ๋ผ์ดํ ์ฌ์ดํด์ ๊ฐ์ง๋ค. (๋จ, ์์ฑ์ ์ฃผ์
์ ๊ฐ์ฒด๋ฅผ ์์ฑํ ๋ ํ๋ผ๋ฏธํฐ๋ก ์คํ๋ง ๋น์ ๋ฐ๊ธฐ ๋๋ฌธ์, ๊ฐ์ฒด ์์ฑ๊ณผ ์์กด๊ด๊ณ ์ฃผ์
์ด ๋์์ ์ผ์ด๋๋ค.)
์คํ๋ง ์ปจํ
์ด๋ ์์ฑ → ์คํ๋ง ๋น ์์ฑ → ์์กด๊ด๊ณ ์ฃผ์
→ ์ด๊ธฐํ ์ฝ๋ฐฑ → ์ฌ์ฉ → ์๋ฉธ ์ ์ฝ๋ฐฑ → ์คํ๋ง ์ข
๋ฃ
์คํ๋ง์์๋ ํฌ๊ฒ 3๊ฐ์ง ๋ฐฉ์์ผ๋ก ์ฝ๋ฐฑ์ ์ง์ํ๋ค.
- ์ธํฐํ์ด์ค(InitializingBean, DisposableBean)
- ์ค์ ์ ๋ณด์ ์ด๊ธฐํ ๋ฉ์๋, ์ข ๋ฃ ๋ฉ์๋ ์ง์
- @PostConstruct, @PreDestory ์ด๋ ธํ ์ด์
3. InitinalizingBean, DisposableBean ์ธํฐํ์ด์ค
public class ExampleBean implements InitializingBean, DisposableBean {
@Override
public void afterPropertiesSet() throws Exception {
// ์์กด๊ด๊ณ ์ฃผ์
์ด ๋๋๋ฉด ํธ์ถ๋๋ ๋ฉ์๋
}
@Override
public void destroy() throws Exception {
// ๋น์ด ์ข
๋ฃ๋๊ธฐ ์ง์ ์ ํธ์ถ๋๋ ๋ฉ์๋
}
์ฒซ ๋ฒ์งธ ๋ฐฉ๋ฒ์ ์ธํฐํ์ด์ค๋ฅผ ์์๋ฐ์ ์ฝ๋ฐฑ ๋ฉ์๋๋ฅผ ๊ตฌํํ๋ ๊ฒ์ด๋ค.InitializingBean
์ afterPropertiesSet()
๋ฉ์๋๋ก ์ด๊ธฐํ๋ฅผ ์ง์ํ๊ณ , DisposableBean
์ destroy()
๋ฉ์๋๋ก ์๋ฉธ์ ์ง์ํ๋ค.
๋จ์
- ์ด ์ธํฐํ์ด์ค๋ค์ ์คํ๋ง ์ ์ฉ ์ธํฐํ์ด์ค์ด๊ธฐ ๋๋ฌธ์, ์คํ๋ง ํ๋ ์์ํฌ์ ์ข ์๋๋ค.
- ๊ฐ๋ฐ์๊ฐ ์ด๊ธฐํ ๋ฉ์๋, ์๋ฉธ ๋ฉ์๋์ ์ด๋ฆ์ ๋ณ๊ฒฝํ ์ ์๋ค.
- ์ธ๋ถ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ์ ์ฉํ ์ ์๋ค. ์ธ๋ถ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ ๊ฐ๋ฐ์๊ฐ ์ฝ๋๋ฅผ ์์ ํ์ง ๋ชปํ๋ฏ๋ก ์ธํฐํ์ด์ค๋ฅผ ์์๋ฐ๋๋ก ํ ์ ์๊ธฐ ๋๋ฌธ์ด๋ค.
4. ๋น ๋ฑ๋ก ์ ์ด๊ธฐํ, ์๋ฉธ ๋ฉ์๋ ์ง์
์ค์ ํ์ผ์์ ๋น์ ๋ฑ๋กํ ๋, @Bean(initMethod = "init", destroyMethod = "close")
์ฒ๋ผ ์์ฑ์ ์ฃผ์ด ์ด๊ธฐํ ๋ฉ์๋์ ์๋ฉธ ๋ฉ์๋๋ฅผ ์ง์ ํ ์ ์๋ค. ์์ ์ฝ๋๋ก ์ดํด๋ณด์.
public class ExampleBean {
String url;
public ExampleBean() {
System.out.println("create ExampleBean, url = " + url);
}
public void setUrl(String url) {
this.url = url;
}
public void init() throws Exception {
System.out.println("ExampleBean.init, url = " + url);
}
public void close() throws Exception {
System.out.println("ExampleBean.close, url = " + url);
}
}
public class ExampleTest {
@Test
public void exampleTest() {
ConfigurableApplicationContext ac = new AnnotationConfigApplicationContext(ExampleConfig.class);
ExampleBean exampleBean = ac.getBean(ExampleBean.class);
ac.close();
}
@Configuration
static class ExampleConfig {
// ์ด๊ธฐํ ๋ฉ์๋๋ก init(), ์๋ฉธ ๋ฉ์๋๋ก close() ์ง์
@Bean(initMethod = "init", destroyMethod = "close")
public ExampleBean exampleBean() {
ExampleBean exampleBean = new ExampleBean();
exampleBean.setUrl("exmapleUrl");
return exampleBean;
}
}
}
์์ ๊ฐ์ ์ฝ๋๋ฅผ ์คํํ๋ฉด, ์๋์ ๊ฐ์ด ์ ์์ ์ผ๋ก ์คํ๋๋ ๊ฒ์ ํ์ธํ ์ ์๋ค.
์ฅ์
- ๋ฉ์๋ ์ด๋ฆ์ ์์ ๋กญ๊ฒ ์ค์ ํ ์ ์๋ค.
- ์คํ๋ง ๋น์ด ์คํ๋ง ์ฝ๋์ ์์กดํ์ง ์๋๋ค. (์ค์ ์ ๋ณด์๋ ์์กดํจ)
- ์ค์ ์ ๋ณด๋ฅผ ํตํด ์ฝ๋ฐฑ ๋ฉ์๋๋ฅผ ์ง์ ํ๊ธฐ ๋๋ฌธ์, ์ธ๋ถ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์๋ ์ด๊ธฐํ, ์ข ๋ฃ ๋ฉ์๋๋ฅผ ์ ์ฉํ ์ ์๋ค.
์ด ๋ฐฉ๋ฒ์ ์ข
๋ฃ ๋ฉ์๋ ์ถ๋ก ๊ธฐ๋ฅ๋ ์ ๊ณตํ๋ค. ๋ผ์ด๋ธ๋ฌ๋ฆฌ์์๋ ๋๋ถ๋ถ close
, shutdown
๊ฐ์ ์ด๋ฆ์ ์ข
๋ฃ ๋ฉ์๋๋ฅผ ์ฌ์ฉํ๋๋ฐ, destroyMethod
์์ฑ์ close
, shutdown
์ด๋ผ๋ ์ด๋ฆ์ ๊ฐ์ง ๋ฉ์๋๋ฅผ ์๋์ผ๋ก ์ข
๋ฃ ๋ฉ์๋๋ก ๋ฑ๋กํด์ค๋ค.
5. @PostConstruct, @PreDestroy ์ด๋ ธํ ์ด์
์ธ ๋ฐฉ๋ฒ ์ค์ ๊ฐ์ฅ ๊ถ์ฅ๋๋ ๋ฐฉ๋ฒ์ผ๋ก, ๋น ์ด๊ธฐํ ์ ํธ์ถํ๊ณ ์ถ์ ๋ฉ์๋์ @PostConstruct
์ด๋
ธํ
์ด์
์, ๋น ์๋ฉธ ์ง์ ์ ํธ์ถํ๊ณ ์ถ์ ๋ฉ์๋์ @PreDestroy
์ด๋
ธํ
์ด์
์ ์ถ๊ฐํ๋ ๋ฐฉ๋ฒ์ด๋ค. ๋ง์ฐฌ๊ฐ์ง๋ก ์์ ์ฝ๋๋ฅผ ํตํด ํ์ธํด๋ณด์.
package hello.core.lifecycle;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
public class ExampleBean {
String url;
public ExampleBean() {
System.out.println("create ExampleBean, url = " + url);
}
public void setUrl(String url) {
this.url = url;
}
// ์ด๊ธฐํ ๋ฉ์๋
@PostConstruct
public void init() throws Exception {
System.out.println("ExampleBean.init, url = " + url);
}
// ์๋ฉธ ๋ฉ์๋
@PreDestroy
public void close() throws Exception {
System.out.println("ExampleBean.close, url = " + url);
}
}
public class ExampleTest {
@Test
public void exampleTest() {
ConfigurableApplicationContext ac = new AnnotationConfigApplicationContext(ExampleConfig.class);
ExampleBean exampleBean = ac.getBean(ExampleBean.class);
ac.close();
}
@Configuration
static class ExampleConfig {
@Bean
public ExampleBean exampleBean() {
ExampleBean exampleBean = new ExampleBean();
exampleBean.setUrl("exmapleUrl");
return exampleBean;
}
}
}
์๋์ ๊ฐ์ด ์ ์์ ์ผ๋ก ์คํ๋๋ ๊ฒ์ ํ์ธํ ์ ์๋ค.
์ฅ์
- ์คํ๋ง์์ ๊ฐ์ฅ ๊ถ์ฅํ๋ ๋ฐฉ๋ฒ
- ๋งค์ฐ ํธ๋ฆฌํ๋ค.
javax
ํจํค์ง์ ์ํ ์ด๋ ธํ ์ด์ ์ด๊ธฐ ๋๋ฌธ์, ์คํ๋ง์ ์ข ์์ ์ด์ง ์๋ค.
(=์คํ๋ง์ด ์๋ ๋ค๋ฅธ ์ปจํ ์ด๋์์๋ ๋์ํ๋ค.)
๋จ์
- ์ธ๋ถ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์๋ ์ ์ฉํ ์ ์๋ค.
๊ฒฐ๋ก ์ ์ผ๋ก ์ธ๋ถ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ์ด๊ธฐํ ๋ฐ ์ข
๋ฃ ๋ฉ์๋๋ฅผ ์ ์ฉํด์ผ ํ๋ค๋ฉด @Bean
์ initMethod
,destoryMethod
์์ฑ์ ์ฌ์ฉํ๊ณ , ๊ทธ ์ธ์๋ @PostConstruct, @PreDestroy ์ด๋
ธํ
์ด์
์ ์ฌ์ฉํ๋ ๊ฒ์ด ์ข๋ค.
'๐๐ฉ๐ซ๐ข๐ง๐ > ๐๐๐ฌ๐ข๐' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
์ฑ๊ธํค ๋น์์ ํ๋กํ ํ์ ๋น ์ฌ์ฉํ๊ธฐ (0) | 2023.10.17 |
---|---|
๋น ์ค์ฝํ๋? (0) | 2023.09.12 |
์์กด๊ด๊ณ ์ฃผ์ ๋ฐฉ๋ฒ (0) | 2023.09.12 |
์ปดํฌ๋ํธ ์ค์บ (0) | 2023.09.02 |
์คํ๋ง์์์ ์ฑ๊ธํค ํจํด (0) | 2023.09.02 |