๋ฌธ์ ๋ฐ์ ์
ํ๊ต ์ ๋ฐฐ ๋ถ๊ป ์ข์ ๊ธฐํ๋ก ์คํ๋ง์ ๋ํด ๋ฉํ ๋ง์ ๋ฐ์ ์ ์๊ฒ ๋์ด, ๋ฉํ ๋ง ๊ณผ์ ๋ก ๊ฐ๋จํ ๊ฒ์ํ๋ถํฐ ๋ง๋ค์ด๋ณด๊ณ ์์์ต๋๋ค.
๋ฌธ์ ๋ฐ์
๊ฒ์๊ธ (Board)์ ๋ํ ๋ฆฌํฌ์งํ ๋ฆฌ๋ฅผ ์์ฑํ๋ ๋์ค, ์ํ ์ฐธ์กฐ ์ด์๊ฐ ๋ฐ์ํ์ต๋๋ค.
์ ๋ ๊ฒ์๊ธ์ ๊ด๋ จ๋ ๋ฆฌํฌ์งํ ๋ฆฌ์ ๊ตฌํ์ฒด๋ค์ ์ฌ๋ฌ ๊ฐ๋ก ๋๊ณ ์ถ์ด, ์์ ํ ์ถ์ํ๋ ์ธํฐํ์ด์ค์ธ BoardRepository๋ฅผ ๋ง๋ค๊ณ , ์คํ๋ง ๋ฐ์ดํฐ JPA ์ธํฐํ์ด์ค๋ก BoardJpaRepository๋ฅผ ๋ง๋ค์์์ต๋๋ค. ๊ทธ๋ฆฌ๊ณ ์คํ๋ง ๋ฐ์ดํฐ ํ๊ฒฝ์์ BoardRepository๋ฅผ ๊ตฌํํ๋ BoardJpaRepositoryImpl์ ๋ง๋ค์์ต๋๋ค.
์ฆ, ์ฝ๋๋ก ๋ํ๋ด๋ฉด ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
public interface BoardRepository {
Long save(final Board board);
...
}
@Repository
@RequiredArgsConstructor
public class BoardJpaRepositoryImpl implements BoardRepository {
private final BoardJpaRepository boardJpaRepository;
@Override
public Long save(final Board board) {
boardJpaRepository.save(board);
...
}
}
public interface BoardJpaRepository extends JpaRepository<Board, Long> {
}
์๋๋ ๋ฐ์ํ ์๋ฌ ๋ก๊ทธ์
๋๋ค.
The dependencies of some of the beans in the application context form a cycle:
boardController defined in file [/Users/hyunjoonchoi/Desktop/2024/2024-mju-mentoring/build/classes/java/main/com/mju/mentoring/board/controller/BoardController.class]
โ
boardService defined in file [/Users/hyunjoonchoi/Desktop/2024/2024-mju-mentoring/build/classes/java/main/com/mju/mentoring/board/service/BoardService.class]
โโโโโโโ
| boardJpaRepositoryImpl defined in file [/Users/hyunjoonchoi/Desktop/2024/2024-mju-mentoring/build/classes/java/main/com/mju/mentoring/board/infrastructure/BoardJpaRepositoryImpl.class]
โโโโโโโ
์ฒ์ ๊ฐ์ง ์๋ฌธ์ , ํด๊ฒฐ๋ฒ
์ฒ์์๋ ๊น์ํ ๋์ ์คํ๋ง ๋ฐ์ดํฐ JPA ๊ฐ์์, ์คํ๋ง ๊ณต์ ๋ฌธ์๋ฅผ ๋ดค์ ๋ ์ ๊ฐ ์๋ชปํ๊ฑฐ๋ ๋์น ๊ฒ์ด ์๋ ์ค ์์์ต๋๋ค.
๊น์ํ ๋์ ๊ฒฝ์ฐ์์๋ ์ฌ์ฉ์ ์ ์ ์ธํฐํ์ด์ค๋ก MemberRepositoryCustom์ ๋ง๋ค๊ณ , ๊ทธ๊ฒ์ ๊ตฌํ์ฒด๋ก MemberRepositoryImpl, ๊ทธ๋ฆฌ๊ณ ์คํ๋ง ๋ฐ์ดํฐ JPA ์ธํฐํ์ด์ค๋ก MemberRepository (JpaRepository์ MemberRepositoryCustom์ ๋ค์ค ์์๋ฐ์)๋ก ์ค๊ณํด์ ์ด๋ฆ๋ง ๋ดค์ ๋๋ ๋ฌธ์ ๊ฐ ์๋ ๊ฒ์ผ๋ก ์๊ฐํ์ต๋๋ค. ๊ณต์ ๋ฌธ์์์๋ ๊ทธ๋ ๊ณ ์.
๊ทธ๋์ ์ฌ์ ํ ์๋ฌธ์ด ๋จ์ ์ง์ ์คํ๋ง ๋ฐ์ดํฐ JPA ๋ฆฌํฌ์งํ ๋ฆฌ์ ์ด์๋ฅผ ์์ฑํ์์ต๋๋ค.
![](https://blog.kakaocdn.net/dn/TuXt4/btsDGwGos5E/DfGFFqr3k5VCNTJL1Kvot1/img.png)
๋ฉ์ธํ ์ด๋ ๋ถ์ ๋ฆฌ๋ทฐ
์ผ๋ง ์ง๋์ง ์์ ๋ฉ์ธํ ์ด๋ ๋ถ๊ป์ ๋ฆฌ๋ทฐํด ์ฃผ์ จ์ต๋๋ค.
You cannot inject a repository facade into its own repository fragment as this creates a circular dependency. You could make the repository @Lazy or inject an ObjectProvider<BoardJpaRepository> to defer object resolution to a time after the objects are constructed.
์์ ์ ์ ์ฅ์ ์กฐ๊ฐ์ ์ ์ฅ์ ํ์ฌ๋๋ฅผ ์ฝ์ ํ๋ฉด ์ํ ์ข ์์ฑ์ด ์์ฑ๋๋ฏ๋ก ์ ์ฅ์ ํ์ฌ๋๋ฅผ ์ฝ์ ํ ์ ์์ต๋๋ค. ์ ์ฅ์ @Lazy๋ฅผ ๋ง๋ค๊ฑฐ๋ ObjectProvider<BoardJpaRepository>๋ฅผ ์ฝ์ ํ์ฌ ๊ฐ์ฒด๋ฅผ ๊ตฌ์ฑํ ํ ์๊ฐ์ผ๋ก ๊ฐ์ฒด ํด๊ฒฐ์ ์ฐ๊ธฐํ ์ ์์ต๋๋ค.
@Lazy, ObjectProvider ๋ฑ ์์ง์ ์ ์๊ฒ ์์ํ ๊ฐ๋
์ด๊ธฐ๋ ํ๊ณ , ๊ณต์ ๋ฌธ์์์๋ ๊ทธ์ ๊ด๋ จ๋ ๋ด์ฉ์ ๋ ์ฐพ์ ์ ์์ด ์ถ๊ฐ์ ์ธ ์ง๋ฌธ์ ํ์์ต๋๋ค. (๊ทธ๋ฐ๋ฐ ๋ฐ๋ก closed ๋ ์ด์..)
2์ฐจ (์ต์ข ) ํด๊ฒฐ๋ฒ
EnableJpaRepositories์ ๋ํด ์ดํด๋ณด๋ค
๊ทธ๋ฌ๋ ๋์ค, ์ด์ ๊ด๋ จ์ด ์๋ EnableJpaRepositories ์ด๋
ธํ
์ด์
์ ๋ํด ์ดํด๋ณด๊ธฐ๋ก ํ์ต๋๋ค. ๊น์ํ ๋์ ์คํ๋ง ๋ฐ์ดํฐ JPA์์๋ ์ด ์ด๋
ธํ
์ด์
์์์ ์ค์ ์ ๋ฐ๊ฟ์ผ๋ก์จ ๊ตฌํ์ฒด๋ฅผ ์๋์ผ๋ก ์ธ์ํ๋ ๊ฒ์ ๋ฐ๊ฟ ์ ์๋ค๊ณ ํ์์ต๋๋ค.
![](https://blog.kakaocdn.net/dn/cMTPvk/btsDGMhRLEi/mgYf4AYBOtZSJwKcdoO600/img.png)
์ฌ๊ธฐ์์ repositoryImplementationPostfix์ ๋ํด ํ์ธํด ๋ณด์๋ฉด, ์คํ๋ง ๋ฐ์ดํฐ JPA๋ ์ปค์คํ
๊ตฌํ์ฒด๊ฐ ์์ฑ๋ ์ ๊ธฐ๋ณธ์ ์ผ๋ก ์คํ๋ง ๋ฐ์ดํฐ JPA ์ธํฐํ์ด์ค์ ์ด๋ฆ ๋ค์ ์ ๋ฏธ์ฌ๋ก Impl์ด ๋ถ์ ๊ฒ์ ๊ตฌํ์ฒด๋ก ์ธ์ํ๋ค๋ ๊ฒ์ ์ ์ ์์ต๋๋ค.
์ด๋ ๊ณต์ ๋ฌธ์์๋ ๋์์๋ ๋ด์ฉ์
๋๋ค.
![](https://blog.kakaocdn.net/dn/2RTTr/btsDDc2UEqX/UiqYSoBse3XToMOD4lH7q0/img.png)
์ฝ๋ ์ฌํ์ธ, ๊นจ๋ฌ์ ๋ฐ ํด๊ฒฐ๋ฒ
๊ทธ๋ผ ๋ค์ ํ๋ฒ ๋ฌธ์ ์ฝ๋๋ฅผ ๋ณด๊ฒ ์ต๋๋ค.
@Repository
@RequiredArgsConstructor
public class BoardJpaRepositoryImpl implements BoardRepository {
private final BoardJpaRepository boardJpaRepository;
@Override
public Long save(final Board board) {
boardJpaRepository.save(board);
...
}
}
๋ฌธ์ ์ ์ ์์๊ฒ ๋์?
BoardJpaRepository๋ ์คํ๋ง ๋ฐ์ดํฐ JPA ์ธํฐํ์ด์ค์
๋๋ค. ๊ทธ๋ฆฌ๊ณ , ์ถ๊ฐ์ ์ผ๋ก ๊ฑด๋ค์ง ์์ ๊ฒฝ์ฐ ๊ตฌํ์ฒด๊ฐ ์๋ค๋ฉด ์์ ์ ์ด๋ฆ ๋ค์ Impl์ด ๋ถ์ ๊ฒ์ ๊ตฌํ์ฒด๋ก ์ผ์ต๋๋ค.
๊ทธ๋ฐ๋ฐ ๊ทธ๋ ๊ฒ ๋ ๊ตฌํ์ฒด์ ์ด๋ฆ์ด BoardJpaRepositoryImpl์ธ๋ฐ, ์ด ํด๋์ค๋ BoardJpaRepository๋ฅผ ์ฐธ์กฐํ๊ณ ์์ต๋๋ค. ๋ฐ๋ผ์, ๊ตฌํ์ฒด๊ฐ ์์ ์ ์ธํฐํ์ด์ค๋ฅผ ์ฐธ์กฐํ๊ฒ ๋ ๊ผด์
๋๋ค. ์
ํ ์ฐธ์กฐ๊ฐ ๋ฐ์๋๊ฒ ๋ ๊ฑฐ์ฃ .
๊ทธ๋์ ๋ก๊ทธ ๋ํ ์ด๋ ๊ฒ BoardJpaRepositoryImpl ์์์๋ง ๊ณ์ ์ํ ์ฐธ์กฐ๊ฐ ๋ฐ์๋๋ค๊ณ ํ๋ ๊ฒ์ผ๋ก ์ถ์ธก๋ฉ๋๋ค.
โโโโโโโ
| boardJpaRepositoryImpl defined in file [/Users/hyunjoonchoi/Desktop/2024/2024-mju-mentoring/build/classes/java/main/com/mju/mentoring/board/infrastructure/BoardJpaRepositoryImpl.class]
โโโโโโโ
๋ฐ๋ผ์ ์ด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ณ ์ถ์ผ์๋ค๋ฉด (์ ์ฒ๋ผ ์คํ๋ง ๋ฐ์ดํฐ JPA ์ธํฐํ์ด์ค๋ฅผ ์ฃผ์
๋ฐ๋๋ก ํ์ค ๋ถ๋ค) ์ด๋ฆ์ ๋ค๋ฅด๊ฒ ํ์
์ผ ํฉ๋๋ค!
์ ๋ฆฌ
๊ฒฐ๊ตญ์๋ ์ ๊ฐ ์๋ชป๋ ๋ค์ด๋ฐ ์ ๋ต์ ์ฌ์ฉํ๊ธฐ ๋๋ฌธ์ ๋ฐ์ํ ์ผ์ด์์์ ์๊ฒ ๋์ด, ๋ฉ์ธํ
์ด๋ ๋ถ๊ป ์ฃ์กํ ๋ง์์ด ๋ค์์ต๋๋ค.
ํ์ง๋ง ํํธ์ผ๋ก๋ ์คํ๋ง ๋ฐ์ดํฐ JPA์ ๋ํด ๋ ์๊ฒ ๋ ๊ท์คํ ๊ณ๊ธฐ๊ฐ ๋์๋ค๊ณ ์๊ฐํฉ๋๋ค.
์ปค์คํ
JPA ๊ตฌํ์ฒด๋ฅผ ๋ง๋ค๋ค๊ฐ ์ถฉ๋ถํ ๋ฐ์ํ ์ ์๋ ์ด์๋ผ๊ณ ์๊ฐ๋๊ธฐ๋ ํ๊ณ , "๊ณต์ ๋ฌธ์์์๋ ์ด๋ฅผ ์ด๋ป๊ฒ ์๋ ค์ฃผ๊ณ ์์๊น?", "๋ค๋ฅธ ์ฌ๋๋ค์ ์ด๋ป๊ฒ ํด๊ฒฐํ์๊น?"๋ฅผ ์๊ฐํด ๋ณด๋ฉฐ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํด ๋ณด๋ ค๊ณ ๋ค์ํ ๋ฐฉ๋ฒ์ ํ์ฉํ๊ธฐ๋ ํ์ต๋๋ค.
๊ทธ๋ฆฌ๊ณ ๋ปํ์ง ์๊ฒ ์คํ๋ง ๋ฐ์ดํฐ JPA ๋ ํฌ์งํ ๋ฆฌ์ ์ง์ ์ด์๋ฅผ ๋จ๊ธฐ๊ฒ ๋์๊ธฐ๋ ํ์์ฃ .
![](https://blog.kakaocdn.net/dn/dOaH3N/btsDBx7CQk3/GfEl8tsjvhBkbTnMd28FcK/img.png)
๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ฑฐ๋ ๊ณต๋ถ๋ฅผ ํ๋ค๊ฐ ๊ถ๊ธํ ๊ฒ ์๋ค๋ฉด ์ด๋ ๊ฒ ํด๊ฒฐํ๊ธฐ ์ ๊น์ง ์์ ์ด ํ ์ ์๋ ๋ชจ๋ ๋ฐฉ๋ฒ์ ๋์ํด์ ์๋ํด ๋ณด๋ ๊ฒ ๋น ๋ฅด๊ฒ ํด๊ฒฐํ ์ ์๋ ๋ฐฉ๋ฒ์ด๋ผ๋ ๊ฒ์ ๋ค์๊ธ ๊นจ๋ฌ์ ์ ์์์ต๋๋ค.
(๋ง์ง๋ง์ผ๋ก ์์ด์ ๋ํด ์ง์ง ๋๋ฌด ์ฝํ ์ํ๋ผ๋ ๊ฒ์ ์๊ฒ ๋์์ต๋๋ค. ๊ณต๋ถ๋ฅผ ๋ ํ๊ธด ํ์ง๋ง ์์ด๊ถ ๋ถ๋ค๊ณผ ์์ฌ์ํตํ ๋ ์ด ์ ๋๋ ์๋์๋ ๊ฒ ๊ฐ์๋ฐ, ์ด ์ ์ ๋ํด์๋ ๋ฐ์ฑํ๊ฒ ๋๋ค์.)
Reference
'๐ฃ ์ด์ ํด๊ฒฐ ๊ธฐ๋ก' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[Spring MVC] DTO๋ฅผ ์ฌ์ฉํ์ฌ ํ๋ผ๋ฏธํฐ๋ก ์ ๋ฌ๋ฐ์ ๋๋ @RequestBody๋ฅผ ๊ผญ ์ ์ฉํ์! (0) | 2024.01.19 |
---|