
CRUD, findById, findAll, DB에서 PK로 검색하는 기능이findByName(), findByEmail() 등은 비지니스가 다르므로 공통 정의❌Reflection 기술 사용📂 SpringDataJpaMemberRepository
public interface SpringDataJpaMemberRepository extends JpaRepository<Member, Long>, MemberRepository {
// MemberRepository의 findByName() 오버라이딩
// 'select m from Member m where m.name = ?' JPQL -> SQL로 변환돼 실행
@Override
Optional<Member> findByName(String name);
}
📂 SpringConfig
@Configuration
public class SpringConfig {
private final MemberRepository memberRepository;
// DI -> Spring Data JPA가 만든 구현체가 등록됨
// 스프링 컨테이너에서 MemberRepository를 찾음 -> 근데 등록한게 없잖아? 사실 하나 있음 SpringDataJpaMemberRepository
// SpringDataJpaMemberRepository는 JpaRepository를 상속, 스프링 데이터JPA 인터페이스에 대한 구현체를 만들어서 스프링 빈에 등록
@Autowired
public SpringConfig(MemberRepository memberRepository) {
this.memberRepository = memberRepository;
}
@Bean
public MemberService memberService(){
return new MemberService(memberRepository);
}
}
스프링 데이터 JPA에서 구현체 없이 인터페이스만으로 개발이 가능한 이유는
스프링이 런타임 시점에 프록시 객체를 자동으로 생성하고,
내부적으로 JPA API를 호출하도록 위임해주기 때문
1. 프록시 기반 동적 구현
JpaRepository 인터페이스를 기반으로 프록시 객체를 만들어 동작을 위임2. Query 메서드 자동 분석
JPQL 쿼리를 자동 생성3. 스프링 컨테이너가 구현체 주입
@Autowired로 주입 가능@SpringBootApplication을 통해 자동으로 패키지를 스캔@Component, @Controller, @Service, @Repository 등으로JpaRepository를 상속받는 인터페이스는 실제 구현체가 없으므로,JDK Dynamic Proxy 또는 CGLIB Proxy를 통해 생성