(error) Parameter 0 of constructor in ~~required a bean of type ~~ that could not be found.

전성영·2022년 7월 31일
1

Error

목록 보기
16/16

spring을 처음 공부할 때부터 지금까지 꾸준히 났던 에러이다.
예전에는 그냥 구글링하고 이해하려고 하지 않아서 정리하지 않았던 것 같다.

에러가 난 이유
TodorepsoitoryImpl에 있는 private final JPAQueryFactory queryFactory; 이 JPAQueryFactory 라는 친구가 빈 등록이 안되어 있어서 의존성(DI) 주입을 할 때 문제가 생긴 것이다. 찾지 못하니깐~~


해결 방안
@Configuration과 @Bean으로 직접 빈 등록을 해주었다.

JPAQueryFactory를 빈 등록을 해야한다.
JPAQueryFactory는 EntityManager를 필요로 한다.

스프링에서는 영속성 관리를 위해 EntityManager가 존재한다고 한다.
그래서 스프링 컨테이너가 시작될 때 EntityManager를 만들어서 빈으로 등록해둡니다.

위 설명대로 해주는 것이 @PersistenceContext 어노테이션 이다.

참고: 동시성 문제는 걱정하지 않아도 된다.
여기서 스프링이 주입해주는 엔티티매니저(em)는 실제 동작 시점에 진짜 엔티티 매니저를 찾아주는 프록시용 가짜 엔티티 매니저이다.


전체 코드

위에서 했던 설명 + EntityManager를 DI 해준 모습이다.


또 다른 예시

DI 방법 세 가지

필드주입 - 필드에 @Autowired 어노테이션만 붙여주면 자동으로 의존성 주입된다.
사용법이 간단하나 외부에서 변경하기 힘들고 프레임 워크에 의존적이며 객체지향적으로 좋지 않다.

생성자 주입 - 클래스의 생성자가 하나이고, 그 생성자로 주입받을 객체가 빈으로 등록되어 있다면  @Autowired를 생략 할 수 있다.

세터 주입 - Setter 메소드에 @Autowired 어노테이션을 붙이는 방법입니다.
수정자 주입을 사용하면 setXXX 메서드를 public으로 열어두어야 하기 때문에 언제 어디서든 변경이 가능한 것이 단점이다.

생성자 주입을 하면 순환참조를 방지할 수 있다.
생성자로 의존성을 주입할 때 final로 선언할 수 있고, 이로인해 런타임에서 의존성을 주입받는 객체가 변할 일이 없어지게 됩니다.

하지만 수정자 주입이나 일반 메소드 주입을 이용하게되면 불필요하게 수정의 가능성을 열어두게 되고, 이는 OOP의 5가지 원칙 중 OCP(Open-Closed Principal, 개방-폐쇄의 원칙)를 위반하게 된다고 한다.
그러므로 생성자 주입을 통해 변경의 가능성을 배제하고 불변성을 보장하는 것이 좋다.
또한, 필드 주입 방식은 null이 만들어질 가능성이 있는데, final로 선언한 생성자 주입 방식은 null이 불가능합니다.

생성자 주입 쵝오!

profile
Slow and Steady

0개의 댓글