How to Implement spring injection and spring Injection
How to Implement spring Injection
IOC (Inverse of Control) can be translated as "Control inversion", but most people are used to calling it "dependency injection ". In Spring, you can configure implementation classes and parameter information in the corresponding configuration file through IOC. When you need to change the implementation class or parameter information, you only need to modify the configuration file. This method further reduces the coupling between classes based on the above example. We can also inject other objects required by an object, which are all done in the configuration file. The implementation principle of Spring IOC uses the reflection mechanism of Java, spring also acts as a factory, and we do not need to create a factory class by ourselves. Spring's factory class will help us read configuration files and inject Objects Using Reflection mechanisms. We can get the corresponding objects through bean names.
Define a beansrc/main/java/spring_IOC/JavaBean.java
package spring_IOC;/** * Created by tom on 2016/5/18. */public class JavaBean { String username; String password; public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; }}
Instantiate a class and inject its value using reflectionsrc/main/java/spring_IOC/SetValueByReflection.java
Package Spring_IOC;Import Java. lang. reflect. InvocationTargetException;Import Java. lang. reflect. Method;/*** Created by tom on 2016/5/18 .*/Public Class SetValueByReflection{/*** Instantiate a class and inject it into the value using reflection */Public Static VoidMain (String[]Args)Throws ClassNotFoundException,NoSuchMethodException,InvocationTargetException,IllegalAccessException{JavaBean bean =NewJavaBean (); // obtain the specified method of the specified class,ClassC =Class. ForName ("spring_IOC.JavaBean ");MethodMethod = c. getMethod ("setUsername ",New Class[]{String. Class}); // call the underlying Method represented by this method object for the specified object with the specified parameter, and call the setuserName Method of the object javaBean. The parameter is "hello world" method. invoke (bean, "hello world ");System. Out. println (bean. getUsername ());}}
Instantiate a class and use reflection to map the attribute names and values obtained in xml.src/main/java/spring_IOC/SetValueByReflectionLoop.java
Package Spring_IOC;Import Org. slf4j. Logger;Import Org. slf4j. LoggerFactory;Import Java. beans. BeanInfo;Import Java. beans. IntrospectionException;Import Java. beans. Introspector;Import Java. beans. PropertyDescriptor;Import Java. lang. reflect. InvocationTargetException;Import Java. lang. reflect. Method;Import Java. util. HashMap;Import Java. util. Map;/*** Created by tom on 2016/5/18 .*/Public Class SetValueByReflectionLoop{Static LoggerLog = LoggerFactory. getLogger (BeanFactory. class );Public Static VoidMain (String[]Args)Throws ClassNotFoundException,NoSuchMethodException,InvocationTargetException,IllegalAccessException,InstantiationException,IntrospectionException{// This map object is used to simulate the property name and value parsed for the property FileMap<String,Object> Map =New HashMap<> (); Map. put ("username", "tomLuo"); map. put ("password", "954 ");ClassBean =Class. ForName ("spring_IOC.JavaBean ");ObjectObj = bean. newInstance (); // obtain the corresponding class informationBeanInfoInfo =Introspector. GetBeanInfo (bean); // traverses attributes of a specified classPropertyDescriptor[]Propertys = info. getPropertyDescriptors ();For(IntJ = 0; j <propertys. length; j ++ ){System. Out. println ("attribute:" + propertys [j]. getName ();} // get its attribute description java. beans. PropertyDescriptor pd[]= Info. getPropertyDescriptors ();MethodMSet = null;For(IntK = 0; k <pd. length; k ++ ){If(Map. containsKey (pd [k]. getName ())){ObjectValue = map. get (pd [k]. getName (); // obtain the corresponding property value. mSet = pd [k]. getWriteMethod (); log.info ("{}{}{}", pd [k]. getName (), pd [k]. getWriteMethod (). getName (), pd [k]. getReadMethod (). getName (); // password setPassword getPassword mSet. invoke (obj, value); // inject 567 to bean Using Reflection. In this experiment, set the value of each set method to 567} // put the object in beanMap, key is the id value, and value is the object JavaBean javaBean1 = (JavaBean) obj;System. Out. println ("userName =" + javaBean1.getUsername ());System. Out. println ("password =" + javaBean1.getPassword ());}}
Load xml files and inject values using reflectionsrc/main/resources/config.xml
<?xml version="1.0" encoding="utf-8" ?><beans xmlns="http://www.springframework.org/schema/beans"> <bean id="javaBean" class="spring_IOC.JavaBean"> <property name="username" value="tom"/> <property name="password" value="123"/> </bean></beans>
Bean Factory is mainly used to parse xml files, get attribute names and values, and then inject values using reflection.src/main/java/spring_IOC/BeanFactory.java
Package Spring_IOC;Import Org. dom4j. Attribute;Import Org. dom4j. Document;Import Org. dom4j. Element;Import Org. dom4j. io. SAXReader;Import Org. slf4j. Logger;Import Org. slf4j. LoggerFactory;Import Java. io. InputStream;Import Java. lang. reflect. Method;Import Java. util. HashMap;Import Java. util. Iterator;Import Java. util. Map;/*** Created by tom on 2016/5/18 .*/Public Class BeanFactory{Static LoggerLog = LoggerFactory. getLogger (BeanFactory. class );Private Map<String,Object> BeanMap =New HashMap<String,Object> ();/*** Bean Factory initialization ** @ param xml */Public VoidInit (StringXml ){Try{// Read the specified configuration file SAXReader reader =NewSAXReader (); // obtain the specified configuration file from the class directoryClassLoaderClassLoader =Thread. CurrentThread (). getContextClassLoader ();InputStreamInputStream = classLoader. getResourceAsStream (xml); // read the xml fileDocumentDocument = reader. read (inputStream); // get the heel NodeElementRoot = document. getRootElement (); // traverse bean nodesElementFoo;For(IteratorIteBean = root. elementIterator ("bean"); iteBean. hasNext ();) {foo = (Element) IteBean. next (); // obtain the bean property id and classAttributeId = foo. attribute ("id ");AttributeCls = foo. attribute ("class"); // uses the java reflection mechanism to obtain the class Object log using the Class name. debug ("{}", cls. getText ());ClassBean =Class. ForName (cls. getText (); // get the corresponding class information java. beans. beanInfo info = java. beans. introspector. getBeanInfo (bean); // get its attribute description java. beans. propertyDescriptor pd[]= Info. getPropertyDescriptors (); // method for setting the valueMethodMSet = null; // create an object (create a new instance of the Class represented by this Class object. This class is instantiated using a new expression with an empty parameter list. If the class has not been initialized, initialize the class .)ObjectObj = bean. newInstance (); // traverses the property attribute of the bean.For(IteratorIteProperty = foo. elementIterator ("property"); iteProperty. hasNext ();){ElementElementProperty = (Element) IteProperty. next (); // obtain the name attribute of the property.AttributeName = elementProperty. attribute ("name"); // read the attribute valueStringValue = elementProperty. attribute ("value "). getText (); // String value = null; // obtain the value of the sub-element value of the property // for (Iterator iteValue = elementProperty. elementIterator ("value"); iteValue. hasNext ();) {// Element elementValue = (Element) iteValue. next (); // value = elementValue. getText (); // break ;//}For(IntK = 0; k <pd. length; k ++) {log.info (pd [k]. getName ());If(Pd [k]. getName (). equalsIgnoreCase (name. getText () {mSet = pd [k]. getWriteMethod (); // log.info (mSet. getName (); // call a set method of the object using the reflection mechanism of Java, and set the value to mSet. invoke (obj, value); // call a specific method of a specific object through the invoke method. The implementation principle is based on the Java reflection mechanism }}// put the object into beanMap, key is the id value, and value is the object beanMap. put (id. getText (), obj );}}Catch(ExceptionE) {e. printStackTrace () ;}/ *** use the bean id to obtain the bean object. ** @ param beanName bean id * @ return returns the corresponding object */Public ObjectGetBean (StringBeanName ){ObjectObj = beanMap. get (beanName );ReturnObj ;}Public Static VoidMain (String[]Args) {BeanFactory factory =NewBeanFactory (); factory. init ("config. xml"); JavaBean javaBean = (JavaBean) factory. getBean ("javaBean ");System. Out. println ("userName =" + javaBean. getUsername ());System. Out. println ("password =" + javaBean. getPassword ());}}
As you can see, although the attribute is not assigned a value in the main () method, the attribute value has been injected. In the BeanFactory Class, Class bean = Class. forName (cls. getText (); get the corresponding class through the class name, mSet. invoke (obj, value); the invoke method is used to call a specific method of a specific object. The implementation principle is based on the Java reflection mechanism.
Source browsing: https://github.com/tomlxq/job-test/tree/master/java-base/src/main/java/spring_IOC