Here we will discuss on how Spring JPA Repository works.
We will mainly focus on below couple of things :
1. How Spring provides Proxies for repositories
2. How Spring resolves the repository method name when there is no JPQL provided
Before we start we need to know about some Java core API like Reflection and Proxy of (java.lang.reflect) package
Reflection API : Using this we can introspect any class and can create instance in run time and invoke any method of that instance. In a single line, we can have full control and information of that object.
Proxy API : Hep of this we can create proxy instance of any class and so that we can have full control of any method invocation. But here I am using javaassist library API for proxy creation since it has more flexibility than the core API
Secret : Here the secret is while creating proxy instance of any class the proxy API expects one MethodHandler. MethodHandler is nothing just an interface contains a call back method for which we have to provide the implementation of the method.
The call back method supplies the parameters like
- the instance on which method invoked
- Method reference to the overridden method declared in the super class or interface.
- Method reference to the forwarder method for invoking the overridden method. It is null if the overridden method is abstract or declared in the interface.
- arguments passed in the method invocation on the proxy instance
Object invoke(Object self, Method thisMethod, Method proceed,
Object[] args) throws Throwable;
Here if the method is abstract then the proceed method reference will be passed to the call back method as NULL. Then we can implement our logic to do what we want. Spring also does in the same way. It resolves the method name and do the required action. Based on the method name it fetches the entity(s) and returned back to the caller object of the repository.
Source Code :
Egineer.java (Entity class)
EngineerRepository.java
Utils.java (To create list of static entities instead of taking fro DB and stores in PersistenceUnit class)
PersistenceUnit.java (Which holds list of static entities and help to fetch required entities on query)
EngineerRepoHandler.java (This is the secret class for handling all repository method invocation)
MyProxyFactory.java (Factory class returns the proxy of a class or an interface using javassist library)
SpringDataRepositoryPOC.java (Main class)
Output:
Please feel free to comment or suggest.