java spring spring-data repository-pattern ddd-repositories

java - ¿Cómo se implementan realmente los repositorios de Spring Data?



spring-data repository-pattern (1)

En primer lugar, no hay generación de código en curso, lo que significa: sin CGLib, sin generación de código de bytes. El enfoque fundamental es que una instancia de proxy JDK se crea mediante programación utilizando la API ProxyFactory de Spring para respaldar la interfaz y un MethodInterceptor intercepta todas las llamadas a la instancia y enruta el método a los lugares apropiados:

  1. Si el repositorio se ha inicializado con una parte de implementación personalizada (consulte esa parte de la documentación de referencia para obtener detalles), y el método invocado se implementa en esa clase, la llamada se enruta allí.
  2. Si el método es un método de consulta (consulte DefaultRepositoryInformation para DefaultRepositoryInformation cómo se determina eso), el mecanismo de ejecución de consultas específicas de la tienda se DefaultRepositoryInformation y ejecuta la consulta determinada para ejecutarse para ese método en el inicio. Para eso, existe un mecanismo de resolución que intenta identificar las consultas declaradas explícitamente en varios lugares (usando @Query en el método, consultas con nombre JPA) eventualmente @Query a la derivación de la consulta desde el nombre del método. Para la detección del mecanismo de consulta, vea JpaQueryLookupStrategy . La lógica de análisis para la derivación de la consulta se puede encontrar en PartTree . La traducción específica de la tienda en una consulta real se puede ver, por ejemplo, en JpaQueryCreator .
  3. Si ninguno de los anteriores se aplica, el método ejecutado debe ser uno implementado por una clase base de repositorio específica de la tienda ( SimpleJpaRepository en el caso de JPA) y la llamada se enruta a una instancia de eso.

El interceptor de métodos que implementa esa lógica de enrutamiento es QueryExecutorMethodInterceptor , la lógica de enrutamiento de alto nivel se puede encontrar here .

La creación de esos proxies se encapsula en una implementación estándar de patrones Factory basada en Java. La creación de proxy de alto nivel se puede encontrar en RepositoryFactorySupport . Las implementaciones específicas de la tienda luego agregan los componentes de infraestructura necesarios para que para JPA pueda seguir adelante y simplemente escribir código como este:

EntityManager em = … // obtain an EntityManager JpaRepositoryFactory factory = new JpaRepositoryFactory(em); UserRepository repository = factory.getRepository(UserRepository.class);

La razón por la que menciono eso explícitamente es que debería quedar claro que, en esencia, nada de ese código requiere un contenedor Spring para ejecutarse en primer lugar. Necesita Spring como una biblioteca en el classpath (porque preferimos no reinventar la rueda), pero en general es independiente del contenedor.

Para facilitar la integración con los contenedores DI, por supuesto, hemos creado integración con la configuración Spring Java, un espacio de nombres XML, pero también una extensión CDI , para que Spring Data pueda usarse en escenarios CDI simples.

He estado trabajando con el repositorio Spring Data JPA en mi proyecto durante algún tiempo y conozco los siguientes puntos:

  • En las interfaces del repositorio, podemos agregar los métodos como findByCustomerNameAndPhone() (suponiendo que customerName y phone son campos en el objeto de dominio).
  • Luego, Spring proporciona la implementación mediante la implementación de los métodos de interfaz del repositorio anteriores en tiempo de ejecución (durante la ejecución de la aplicación).

Estoy interesado en cómo se ha codificado esto y he examinado el código fuente y las API de Spring JPA, pero no pude encontrar las respuestas a las siguientes preguntas:

  1. ¿Cómo se genera e inyecta la clase de implementación del repositorio en tiempo de ejecución y los métodos?
  2. ¿Spring Data JPA utiliza CGlib o alguna biblioteca de manipulación de bytecode para implementar los métodos e inyectar dinámicamente?

¿Podría ayudarme con las consultas anteriores y también proporcionar documentación respaldada?