우선, 진행중인 코드 생성이 없습니다. 즉, CGLib도없고 바이트 코드도 생성되지 않습니다. 기본적인 접근 방식은 JDK 프록시 인스턴스가 Spring의 ProxyFactory
API를 사용하여 프로그래밍 방식으로 생성 되어 인터페이스 MethodInterceptor
를 지원하고 인스턴스에 대한 모든 호출을 가로 채서 메서드를 적절한 위치로 라우팅하는 것입니다.
- 리포지토리가 사용자 지정 구현 부분 (자세한 내용 은 참조 문서의 해당 부분 참조)으로 초기화되고 호출 된 메서드가 해당 클래스에서 구현 된 경우 호출이 여기로 라우팅됩니다.
- 메서드가 쿼리 메서드 인 경우 (확인 방법 참조
DefaultRepositoryInformation
) 저장소 별 쿼리 실행 메커니즘은 시작시 해당 메서드에 대해 실행되도록 결정된 쿼리를 시작하고 실행합니다. 이를 위해 다양한 위치에서 명시 적으로 선언 된 쿼리를 식별하려는 해결 메커니즘이 마련되어 있습니다 ( @Query
메소드에서 JPA 명명 된 쿼리 사용). 결국 메서드 이름에서 파생 된 쿼리로 대체됩니다. 쿼리 메커니즘 검색에 대해서는을 참조하십시오 JpaQueryLookupStrategy
. 쿼리 파생에 대한 구문 분석 논리는에서 찾을 수 있습니다 PartTree
. 실제 쿼리에 대한 상점 별 번역은에서 볼 수 있습니다 JpaQueryCreator
.
- 위의 어느 것도 적용되지 않는 경우 실행되는 메소드는 저장소 별 저장소 기본 클래스 (
SimpleJpaRepository
JPA의 경우)에 의해 구현 된 메소드 여야 하며 호출은 해당 인스턴스로 라우팅됩니다.
라우팅 로직을 구현하는 메소드 인터셉터는 여기QueryExecutorMethodInterceptor
에서 높은 수준의 라우팅 로직을 찾을 수 있습니다 .
이러한 프록시의 생성은 표준 Java 기반 Factory 패턴 구현으로 캡슐화됩니다. 고급 프록시 생성은에서 찾을 수 있습니다 RepositoryFactorySupport
. 그런 다음 상점 별 구현은 필요한 인프라 구성 요소를 추가하여 JPA에 대해 계속 진행하여 다음과 같은 코드를 작성할 수 있습니다.
EntityManager em = … // obtain an EntityManager
JpaRepositoryFactory factory = new JpaRepositoryFactory(em);
UserRepository repository = factory.getRepository(UserRepository.class);
내가 명시 적으로 언급 한 이유는 핵심에서 해당 코드의 어떤 것도 처음에 실행되는 Spring 컨테이너를 필요로하지 않는다는 것이 분명 해져야하기 때문입니다. 클래스 패스의 라이브러리로 Spring이 필요하지만 (바퀴를 재발 명하지 않기를 원하기 때문에) 일반적으로 컨테이너에 구애받지 않습니다.
DI 컨테이너와의 통합을 용이하게하기 위해 우리는 물론 Spring Java 구성, XML 네임 스페이스 및 CDI 확장 과의 통합을 구축하여 SpringData 를 일반 CDI 시나리오에서 사용할 수 있도록했습니다.
@Repository
애노테이션이있는 인터페이스를 처음 발견하는 방법에 대해 자세히 설명해 주 시겠습니까? 보면RepositoryFactorySupport#getRepository()
이 다른 곳을 검색해야합니다 그래서 쇼는, 매개 변수로 인터페이스 클래스를 걸립니다. 저는 특히 주석이 달린 인터페이스를 찾고 인터페이스를 구현하는 JDK 프록시 빈을 자동으로 생성하는 방법을 알아 내려고 노력하고 있습니다. 이는 스프링 데이터와 매우 유사하지만 리포지토리와 관련이없는 애플리케이션 특정 목적을위한 것입니다.