์คํ๋ง ์ํ์ฐธ์กฐ ๋ฌธ์
์คํ๋ง์ผ๋ก ํ๋ก์ ํธ๋ฅผ ์งํํ๋ค๋ณด๋ฉด ์ฌ๋ฌ ๋น๋ค์ ์ํ์ฐธ์กฐ๋ก ์ธํด ์ฑ ๊ธฐ๋์ด ์๋๋ ์ํฉ์ ์ข ์ข ๋ง๋ฑ๋๋ฆฌ๊ฒ ๋ฉ๋๋ค. ์ต๊ทผ์ ์ ํจ์ค๋ก ๋น๋ํ ์ฑ์ด ์ํ์ฐธ์กฐ ๋ฌธ์ ๋ก ์ธํด ์ ์์ ์ผ๋ก ๊ธฐ๋์ด ๋์ง ์๋ ๋ฌธ์ ๊ฐ ๋ฐ์ํ์ต๋๋ค. ๊ทธ๋ฐ๋ฐ ์๊ธด๊ฑด ๋ก์ปฌํ๊ฒฝ์์๋ ์๋ฌด๋ฐ ๋ฌธ์ ์์ด ์ ๋์๊ฐ๋ค๋ ๊ฒ์ด์์ฃ . ๊ฒฐ๊ตญ ๋ด๋น์์ ํ์ธํ์ ์ ํจ์ค์ ํ์ดํ๋ผ์ธ ์ต์ ์ค์ ์ผ๋ก ํด๊ฒฐ์ ํ์ต๋๋ค๋ง, setter injection (field injection) ์ด๋ผ๋ ์ํ์ฐธ์กฐ๊ฐ ๋ฐ์ํ๋ ๋์์ธ์ ์ข์ง ์์ฃ . ๊ทธ๋์ ๊ด๋ จ๋ด์ฉ์ ์์๋ณด๋ค๊ฐ ๋์ ์ฌ๋ด ๋๋ค.
์ํ์ฐธ์กฐ๋? (What is Circular Reference ? )
์ํ์ฐธ์กฐ๋ ์๋ก ๋ค๋ฅธ ์ฌ๋ฌ ๋น๋ค์ด ์๋ก ๋ฌผ๊ณ ๋์ด์ ธ์ ๊ณ์ ์ฐ๊ฒฐ๋์ด ์์์ ์๋ฏธํฉ๋๋ค.
์ฆ, ์๋์ฒ๋ผ A๋ B์์ ํ์ํ๋ฐ B๋ ๋ A์์ ํ์ํ ์ํ๋ฅผ ๋งํฉ๋๋ค.
Bean A → Bean B → Bean A
๋ง์ฝ Bean A -> Bean B -> Bean C ์ฒ๋ผ ์ฐ๊ฒฐ๋์ด์๋ค๋ฉด ์คํ๋ง์ A๋ฅผ ๋จผ์ ๋ง๋ค๊ณ A๋ฅผ ํ์๋ก ํ๋ B๋ฅผ ๋ง๋ค๊ณ B๋ฅผ ํ์๋ก ํ๋ C๋ฅผ ๋ง๋ค๊ฒ ๋ฉ๋๋ค. ํ์ง๋ง ์ํ์ฐธ์กฐ๊ฐ ๋ฐ์ํ๋ฉด ์คํ๋ง์ ์ด๋ ๋น์ ๋จผ์ ์์ฑํด์ผํ ์ง ๊ฒฐ์ ํ์ง ๋ชปํ๊ฒ๋๊ณ ์ํ์ฐธ์กฐ ์ค๋ฅ๊ฐ ๋ฐ์ํ๊ฒ ๋ฉ๋๋ค. ์ด๋ ๊ฒ ์ํ์ฐธ์กฐ๊ฐ ๋ฐ์ํ๋ค๋๊ฑด ๊ฒฐ๊ตญ ์ค๊ณ๊ฐ ์๋ชป๋์๋ค๋ ๊ฒ์ ๋๋ค. ํ์ง๋ง ๊ทธ๋ ๋ค๊ณ ์ค๊ณ๋ฅผ ๋ค ๋ฏ์ด๊ณ ์น์๋ ๋น์ฉ์ด ๋๋ฌด ๋ง์ด ๋ค์ด๊ฐ ์๋ ์์ฃ . ์ํ์ฐธ์กฐ ์ค๋ฅ๋ ์ฐธ๊ณ ๋ก ์คํ๋ง์ ์์กด์ฑ ์ฃผ์ ๋ฐฉ๋ฒ ์ค์์๋ ํนํ ์์ฑ์ ์ฃผ์ ๋ฐฉ๋ฒ์ ์ฌ์ฉํ์ ๋ ๋ฐ์ํฉ๋๋ค. ๋น ์์ฑ์ ํ์ํ ๋ค๋ฅธ ๋น์ด ์๋ก ๋ฌผ๊ณ ๋์ด์ ธ ์์ผ๋ ์ด๋ค ๋น๋ ์์ฑ์ด ๋ถ๊ฐ๋ฅํ ์ํฉ์ด ๋์ด๋ฒ๋ฆฌ๋ ๊ฒ์ด์ฃ .
์ํ์ฐธ์กฐ ๋ฌธ์ ํด๊ฒฐ๋ฐฉ๋ฒ
์ํ์ฐธ์กฐ๋ ๋ฐ์ํ์ง ์๋๋ก ํด์ฃผ๋๊ฒ ์ ์ผ ์ข๊ธด ํ์ง๋ง ์ด์ฉ ์ ์๋ ์ํฉ์ ๊ผญ ์๊ธฐ๊ธฐ ๋ง๋ จ์ ๋๋ค. ๊ทธ๋ผ ์ด๋ป๊ฒ ์ํ์ฐธ์กฐ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ ์ ์์๊น์? ๊ฐ์ฅ ์ฐ์ ์ ํด์ผํ ๊ฒ์ ์ํ์ฐธ์กฐ์ ๊ณ ๋ฆฌ๋ฅผ ๋์ด๋ฒ๋ฆฌ๋ ๊ฒ์ ๋๋ค. ์ด๊ฒ์ด ์คํ๋ง์์ ๊ถ์ฅํ๋ ๋ฐฉ๋ฒ์ด๋ฉฐ ์ค๊ณ๋ฅผ ์กฐ๊ธ๋ง ๋ฐ๊ฟ์ ํด๊ฒฐ์ด ๊ฐ๋ฅํ ๊ฒฝ์ฐ๊ฐ ์ด์ ํด๋นํฉ๋๋ค. ํ์ง๋ง ๋ง์ฝ ์ค๊ณ์ ๋ณ๊ฒฝ์ด ํ๋ ๊ฒฝ์ฐ๋ผ๋ฉด @Lazy ์ด๋ ธํ ์ด์ ์ ์ฌ์ฉ ํด๋ณผ ์ ์์ต๋๋ค. (ํด๋ณผ ์ ์๋ค ๋ผ๊ณ ์๊ธฐํ ์ด์ ๋ ์๋์ ๋์ต๋๋ค)
@Component
public class BeanA {
private BeanB beanB;
@Autowired
public BeanA(BeanB beanB) {
this.beanB = beanB;
}
}
์ด๋ ๊ฒ ๋์ด์๋ ์ฝ๋๋ฅผ ์๋์ฒ๋ผ ๋ฐ๊ฟ์ฃผ๋ ๊ฒ์ด์ฃ .
@Component
public class BeanA {
private BeanB beanB;
@Autowired
public BeanA(@Lazy BeanB beanB) {
this.beanB = beanB;
}
}
ํ์ง๋ง ์ด๋ฐ ์ ๊ทผ ๋ฐฉ์์ ๋ฌธ์ ๊ฐ ์์ต๋๋ค. Lazy initialization ์ ๋ํ ๋ฌธ์ ๋ Spring ๊ณต์๋ฌธ์(Lazy Initialization)๋ฅผ ์ฐธ๊ณ ํ์๋ฉด ๋๊ฒ ์ต๋๋ค. ๊ฐ๋จํ ๋ง์๋๋ฆฌ๋ฉด ์ฑ ๊ธฐ๋์์ ์ด ์๋ ์ค์ ํด๋น ๋น์ด ํ์ํ ์์ ์ ๋น์ ์์ฑํ๊ธฐ ๋๋ฌธ์ ํน์ http ์์ฒญ์ ๋ฐ์์ ๋ ํ๋ฉ๋ชจ๋ฆฌ๊ฐ ์ฆ๊ฐํ ์ ์์ผ๋ฉฐ ๋ฉ๋ชจ๋ฆฌ๊ฐ ์ถฉ๋ถํ์ง ์์ ์ํฉ์ด์๋ค๋ฉด ์ฅ์ ๋ก ์ด์ด์ง ์ ์๋ค๋ ์๊ธฐ์ฃ . ์๋ฌดํผ ์คํ๋ง์์ ๊ถ์ฅํ์ง ์๋ ๋ฐฉ์์ด๋ ์ฌ์ฉํ์ง ์์ผ์๋ฉด ๋ฉ๋๋ค.
๋ ๋ค๋ฅธ ๋ฐฉ๋ฒ์ ์์ฑ์ ์ฃผ์ ๋ฐฉ๋ฒ ๋์ ์ setter ์ฃผ์ ๋ฐฉ๋ฒ์ ์ฌ์ฉํ์๋ฉด ๋ฉ๋๋ค.
์๋ setter ์ฃผ์ ์์ ๋ฅผ ํ๋ฒ ๋ณด์์ฃ .
@Component
public class BeanA {
private BeanB beanB;
@Autowired
public void setBeanB(BeanB beanB) {
this.beanB = beanB;
}
public BeanB getBeanB() {
return beanB;
}
}
@Component
public class BeanB {
private BeanA beanA;
@Autowired
public void setBeanA(BeanA beanA) {
this.beanA = beanA;
}
}
ํน์๋ ์ฃผ์ ๋ฐฉ๋ฒ์ ๋ค์ ํ๋ฒ ์ง๊ณ ๋์ด๊ฐ๊ณ ์ถ์ผ์๋ค๋ฉด ์คํ๋ง ์์กด์ฑ ์ฃผ์ ํฌ์คํ ์ ์ฐธ๊ณ ํ์๊ธฐ ๋ฐ๋๋๋ค.
Conclusion
์คํ๋ง์ผ๋ก ๊ฐ๋ฐ์ ํ๋ค๊ฐ ์ํ์ฐธ์กฐ๊ฐ ๋ฐ์ํ๋ค๋ฉด ๊ฐ์ฅ ์ข์ ํด๊ฒฐ์ฑ ์ ์ํ์ฐธ์กฐ์ ์ฐ๊ฒฐ๊ณ ๋ฆฌ๋ฅผ ๋์ด๋ฒ๋ฆฌ๋ ๊ฒ์ด๋ฉฐ ๊ทธ๋ ๊ฒ ํ๋ ๊ฒ์ด ๊น๋ํ๊ฒ ์ค๊ณ๋ ๋์์ธ์ด๋ผ๊ณ ํ ์ ์์ต๋๋ค. ์คํ๋ง์์๋ ๊ถ์ฅํ๋ ๋ฐฉ์์ด์ฃ . ๊ทธ๋์ setter์ฃผ์ ์ด ์๋ ์์ฑ์ ์ฃผ์ ๋ฐฉ์์ ์ฌ์ฉํ๋ ๊ฒ์ด ๊ถ์ฅ๋ฉ๋๋ค. ์ฐํ์ ์ผ๋ก ์ํ์ฐธ์กฐ๋ฅผ ์ ์ ํผํ๋ค ํ๋๋ผ๋ ์ธ์ ๋ ๋๊ฐ์ ๋ฌธ์ ๊ฐ ๋ฐ์ํ ์ง ์๋ฌด๋ ์ ์ ์์ผ๋ฉฐ ๋ฉ๋ชจ๋ฆฌ ๋ถ์กฑ(lazy initialization์ ๊ฒฝ์ฐ) ํ์์ด ๋ฐ์ํ ์๋ ์๊ธฐ ๋๋ฌธ์ ๊ฐ๊ธ์ ์ํ์ฐธ์กฐํด์ผํ๋ ์ค๊ณ๋ ํผํ๋๋ก ํ๋ ๊ฒ์ด ์ข๊ฒ ์ต๋๋ค.
Reference
- www.baeldung.com/circular-dependencies-in-spring
- docs.spring.io/spring-framework/docs/current/reference/html/core.html#beans-dependencies
'๐ป Programming' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
SpringBoot 2 http response utf-8 ์ค์ ํ๊ธฐ (0) | 2021.03.11 |
---|---|
[5๋ถ ์ฝ๋ฉ] Spring4 + JCache (feat. Ehcache) (0) | 2020.12.17 |
์คํ๋ง ์์กด์ฑ ์ฃผ์ (DI) (0) | 2020.12.10 |
[์๋ฃ๊ตฌ์กฐ] AVL ํธ๋ฆฌ ํ์ ํ๊ธฐ (rotation of AVL tree) (1) | 2020.12.04 |
[์๋ฃ๊ตฌ์กฐ] AVL ํธ๋ฆฌ ํน์ง ๋ฐ ๋กํ ์ด์ ๊ธฐ์ค (1) | 2020.11.29 |