스프링 데이터 저장소는 실제로 어떻게 구현됩니까?
저는 Spring Data JPA 저장소와 오랫동안 함께 작업해 왔습니다.다음 사항을 알고 있습니다.
- 저장소 인터페이스에서 다음과 같은 메서드를 추가할 수 있습니다.
findByCustomerNameAndPhone()
(비활성화)customerName
그리고.phone
도메인 오브젝트의 필드입니다). - 다음으로 Spring은 실행 시(애플리케이션 실행 중)에 위의 저장소 인터페이스 메서드를 구현함으로써 구현을 제공합니다.
어떻게 코드화가 되었는지 궁금하고 Spring JPA 소스 코드와 API를 살펴보았지만 아래 질문에 대한 답변을 찾을 수 없었습니다.
- 저장소 구현 클래스는 런타임에 어떻게 생성되며 메서드는 어떻게 구현 및 주입됩니까?
- Spring Data JPA는 CGlib 또는 바이트 코드 조작 라이브러리를 사용하여 메서드를 구현하고 동적으로 주입합니까?
위의 질문에 대한 대응과 지원되는 문서를 제공해 주시겠습니까?
우선 코드 생성은 진행 중이 아닙니다. 즉, CGLib도 바이트 코드 생성도 전혀 없습니다.기본적인 접근법은 Spring을 사용하여 JDK 프록시 인스턴스를 프로그래밍 방식으로 작성하는 것입니다.ProxyFactory
인터페이스를 지원하는 API와MethodInterceptor
는 인스턴스에 대한 모든 콜을 대행 수신하고 메서드를 적절한 장소에 라우팅합니다.
- 저장소가 커스텀 실장 부품(자세한 내용은 참조 문서의 해당 부분 참조)으로 초기화되어 호출된 메서드가 해당 클래스에서 구현되어 있는 경우 콜은 해당 클래스로 라우팅됩니다.
- 이 방법이 쿼리 방식일 경우(그 결정 방법에 대해서는 을 참조), 스토어 고유의 쿼리 실행 메커니즘은 기동 시에 그 메서드에 대해 실행이 결정된 쿼리를 실행한다.이를 위해 다양한 장소에서 명시적으로 선언된 쿼리를 식별하기 위한 해결 메커니즘이 있습니다(사용).
@Query
메서드에서 JPA 명명된 쿼리)는 최종적으로 메서드 이름에서 파생된 쿼리로 폴백합니다.쿼리 메커니즘의 검출에 대해서는, 을 참조해 주세요.쿼리 파생 해석 로직은 에서 확인할 수 있습니다.스토어 고유의 실제 쿼리로의 변환을 에 나타냅니다. - 위의 어느 것도 적용되지 않는 경우 실행되는 메서드는 스토어 고유의 저장소 베이스 클래스(
SimpleJpaRepository
JPA의 경우)에 의해 구현된 메서드여야 하며 콜은 그 인스턴스로 라우팅됩니다.
.QueryExecutorMethodInterceptor
여기서 개략적인 라우팅 로직을 찾을 수 있습니다.
이러한 프록시의 작성은 표준 Java 기반 공장 패턴 구현으로 캡슐화됩니다.개략적인 프록시 작성은 에서 확인할 수 있습니다.스토어 고유의 구현에서는 필요한 인프라스트럭처 컴포넌트를 추가하여 JPA의 경우 다음과 같이 코드를 작성할 수 있습니다.
EntityManager em = … // obtain an EntityManager
JpaRepositoryFactory factory = new JpaRepositoryFactory(em);
UserRepository repository = factory.getRepository(UserRepository.class);
제가 이를 명시적으로 언급하는 이유는 그 핵심에서 스프링 컨테이너를 실행할 필요가 없다는 것을 명확히 해야 하기 때문입니다.클래스 패스의 라이브러리로서 Spring이 필요하지만(바퀴를 재창조하지 않는 것을 선호하기 때문에), 일반적으로 컨테이너에 의존하지 않습니다.
물론 DI 컨테이너와의 통합을 용이하게 하기 위해 Spring Java 구성, XML 네임스페이스 및 CDI 확장과의 통합을 구축하여 일반 CDI 시나리오에서 Spring 데이터를 사용할 수 있도록 했습니다.
언급URL : https://stackoverflow.com/questions/38509882/how-are-spring-data-repositories-actually-implemented
'source' 카테고리의 다른 글
MySQL과 null 값 비교 (0) | 2022.12.08 |
---|---|
URL에서 JSON 개체 가져오기 (0) | 2022.12.08 |
pyenv, virtualenv, anaconda의 차이점은 무엇입니까? (0) | 2022.12.08 |
사용자 역할에 따라 1개의 루트에 대해 다른 뷰를 로드하는 방법이 있습니까? (0) | 2022.12.08 |
스프링 부트 - 데이터베이스에 엔티티를 하나만 생성할 수 없습니다. (0) | 2022.12.08 |