In spring, we can inject parameters into a method by @Autowired annotations, so what happens behind this approach, this article will tell you how to implement a "low-distribution" dependency Injection with Java annotations and reflection.
Here are some of the things we're going to do:
- Define an annotation by @interface way
- Add this annotation to the method that you want the cup to be injected into
- Write the test code to get the method object for the annotated methods by reflection, set the method object to be accessible, create the object by reflection and call this method, and inject the dependent data
As mentioned above, we are divided into three steps to process this low distribution of dependency injection, the following is the detailed steps of each step
The structure of the code we are writing is divided into three parts:
- Autowired: Annotations for declarations
- Demo class: Contains the method of dependent injection SETSTR
- Test class: The method of getting autowired annotations by reflection and dependency Injection
One: Define Annotations
Autowired
@Retention (retentionpolicy.runtime) public @Interface autowired {
}
First we define an annotation by @interface way, and thus we can see that the status and class of annotations, similar interfaces, is a relationship of the same level
The @Retention is a meta-annotation, hence the name meaning, which is used to annotate (verb) annotations (nouns)! (noun), retentionpolicy.runtime that the annotation will be kept to the runtime so that we can process the annotations by reflection.
Two. Add annotations to the injected method
Here we add an annotation for the Setstr method
Public class Demo { private String str; @Autowired publicvoid setstr (String str) { this. str= str; } Public String getstr () { return str; }}
Three. Gets and processes the annotated method by reflection, sets the method object to be accessible, creates the object by reflection and calls the method, and injects the dependent data
Because it involves a lot of APIs about reflection, so for the reflection mechanism you can look at the article I wrote earlier: https://www.cnblogs.com/penghuwan/p/7580145.html
In this step we are going to do something:
- Call the Class.forName method, pass in the path string of a class as a parameter, get the class object
- Get an array of methods objects that declare the method by calling the Getdeclaredmethods method of the class object
- Traversing the methods array in 2, the method object is called by the Isannotationpresent method to determine whether it adds autowired annotations, and the method of adding autowired annotations to do the following processing
- By calling the method object's setaccessible (true); methods to set the object to be accessible, do not make the next call method error
- An object instance is created through the Newinstance method of the class object, which, if it is object, injects the dependent data by invoking the object's method via Method.invoke (object, "incoming data").
- Returning an object instance of 5 to object, we get an instance of the objects that are injected with the dependent data.
The code is as follows:
Test.java
Importjava.lang.reflect.InvocationTargetException;ImportJava.lang.reflect.Method; Public classTest {/*** This method injects a piece of text into the method where the @autowired annotation is added to a class and returns the instance object*/ Public StaticObject injectstrtoinstance (String classname,string str)throwsClassNotFoundException {//get the Class object for the demoClass DemoClass =Class.forName (ClassName); //Gets the method object that corresponds to the declared methods in the demo from the class objectMethod [] Methods =Democlass.getdeclaredmethods (); for(Method method:methods) {//whether the method has been added @autowired this annotation if(Method.isannotationpresent (autowired.class)) { //sets the method to a callableMethod.setaccessible (true); Try{Object Object=democlass.newinstance (); //call method to inject a str string into itMethod.invoke (OBJECT,STR); returnobject; } Catch(illegalaccessexception e) {e.printstacktrace (); } Catch(InvocationTargetException e) {e.printstacktrace (); } Catch(instantiationexception e) {e.printstacktrace (); } } } return NULL; } Public Static voidMain (String args [])throwsClassNotFoundException {//make a dependency injection and get an instance of the injected demo objectDemo Demo1 = (demo) injectstrtoinstance ("demo", "I am the text being injected"); //output and see if our text was successfully injected into it.System.out.println (Demo1.getstr ()); }}
Output Result:
I was injected into the text
So far, we've completed the dependency injection of this low-distribution version.
Java uses Java annotations and reflections to implement a "low-distribution" dependency Injection