Прежде всего, генерации кода не происходит, что означает: нет CGLib, без генерации байтового кода. Фундаментальный подход является то, что прокси-экземпляр JDK создается программно с помощью ProxyFactory
API Spring, чтобы поддержать интерфейс и MethodInterceptor
перехватывает все вызовы к экземпляру и маршрутам метода в соответствующие места:
- Если репозиторий инициализирован с дополнительной частью реализации (см. that part of the reference documentation), а метод, вызванный, реализован в этом классе, вызов маршрутизируется туда.
- Если метод является методом запроса (см.
DefaultRepositoryInformation
, как это определено), механизм выполнения конкретных запросов хранилища запускает и выполняет запрос, определенный для выполнения этого метода при запуске. Для этого существует механизм разрешения, который пытается идентифицировать явно объявленные запросы в разных местах (используя метод @Query
по методу, JPA с именем запросов), в конечном итоге возвращается к выводу запроса из имени метода. Для обнаружения механизма запроса см. JpaQueryLookupStrategy
. Логику синтаксического анализа для вывода запроса можно найти в PartTree
. Конкретный перевод хранилища в фактический запрос можно увидеть, например. в JpaQueryCreator
.
- Если ни один из вышеприведенных действий не применяется, выполняемый метод должен быть реализован базовым классом репозитория, специфичным для магазина (
SimpleJpaRepository
в случае JPA), и вызов направляется в экземпляр этого.
Метод перехватчик реализация, что логика маршрутизации является QueryExecutorMethodInterceptor
, логика маршрутизации высокого уровня может быть найдена here.
Создание этих прокси-объектов инкапсулируется в стандартную реализацию шаблона Factory на основе Java. Создание прокси-сервера высокого уровня можно найти в 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 extension, так что Spring Data можно использовать в простых сценариях CDI.
Привет, Оливер, можете ли вы рассказать о том, как весна обнаруживает аннотированные интерфейсы '@ Repository' в первую очередь? Глядя на 'RepositoryFactorySupport # getRepository()', покажите, что он принимает класс интерфейса как параметр, поэтому его нужно найти где-то в другом месте. Я особенно стараюсь выяснить, как найти аннотированный интерфейс и автоматически генерировать прокси-сервер JDK, который реализует интерфейс, очень похожий на весенние данные, но для конкретной цели приложения, не связанной с репозиториями. –
Возможно, вы захотите взглянуть на ['RepositoryComponentProvider'] (https://github.com/spring-projects/spring-data-commons/blob/0237760345faa011bdc6639ec838790be3d41e9b/src/main/java/org/springframework/data/repository /config/RepositoryComponentProvider.java#L60-L79). Нет никаких автоматических событий, но просмотр компонентов для определенных типов (аннотированный или несущий аннотацию) и «FactoryBean», настроенный для каждого из них. –