Background:
The set method in the entity class involves business logic. Therefore, the set method cannot be used in the process of assigning values to objects. In order to realize functions, the reflection mechanism is used to assign values to object attributes. Therefore, the reflection mechanism is analyzed in two points:
- Advantages and disadvantages of reflection
- Application scenario of reflection
Advantages and disadvantages of reflection
In fact, the reflection mechanism is the God model. If the method call is the correct way to open Java, the reflection mechanism is the back door secretly opened by God. As long as there is a corresponding class, everything can be called.
Static and dynamic concepts:
- Static compilation: determine the type and bind objects at compile time
- Dynamic compilation: determine the type and bind objects at run time
The difference between the two is that dynamic compilation can support polymorphism to the greatest extent, and the greatest significance of polymorphism is to reduce the coupling of classes. Therefore, the advantages of reflection are obvious: decoupling and improving the flexibility of code.
Therefore, the advantages and disadvantages of reflection are:
- advantage
- Runtime type judgment, dynamic class loading: improve code flexibility
- inferiority
- Performance bottleneck: reflection is equivalent to a series of interpretation operations to inform the JVM of what to do. The performance is much slower than that of direct Java code.
Application scenario of reflection
Reflection mechanism is rarely used in normal development, but many designs are related to reflection mechanism, such as modular development, which calls the corresponding bytecode through reflection; The dynamic proxy design pattern also adopts the reflection mechanism. For example, spring / Hibernate and other frameworks are implemented by using the CGLIB reflection mechanism. Examples are as follows:
JDBC database connection
During JDBC operation, database connection must be completed according to the following steps:
- Pass class Forname() loads the driver of the database (loaded through reflection, provided that the relevant jar package is introduced)
- Load the database through the DriverManager class. When connecting, enter the link address, user name, password, etc. of the database
- Receive connection via Conection interface
package com.mp.day02; import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; public class ConnectionJDBC { public static final String DBDRIVER = "org.mariadb.jdbc.Driver"; public static final String DBURL = "jdbc:mariadb://localhost:3306/test"; public static final String DBUSER = "root"; public static final String DBPASS = "root"; public static void main(String[] args) throws ClassNotFoundException, SQLException { Connection conn = null; Class.forName(DBDRIVER); // Use the CLASS class to load the driver and reflect the mechanism conn = DriverManager.getConnection(DBURL, DBUSER, DBPASS); System.out.println(conn); conn.close(); } }
Use of Spring framework
Reflection mechanism is the cornerstone of Java framework. Many open source frameworks have been basically encapsulated, such as Hibernate and Spring. The most classic is the xml configuration mode.
Spring loads beans through XML configuration patterns as follows:
- Load all XML or Properties configuration files in the program into memory
- The Java class parses the contents in xml or Properties to get the bytecode string of the corresponding entity class and related property information
- Use the reflection mechanism to obtain the Class instance of a Class according to this string
- Dynamically configure the properties of an instance
Spring has the following advantages:
- You don't have to go to new or do other things in the code every time
- If you want to modify it later, you can directly modify the configuration file, which is convenient for code maintenance
- Sometimes, in order to use some requirements, other methods may not be called directly in Java classes, but can be implemented through reflection mechanism
Example: simulate Spring to load an XML configuration file
package com.mp.day02; public class BeanFactory { private Map<String, Object> beanMap = new HashMap<>(); /** * bean Factory initialization * * @param xml */ public void init(String xml) { try { // Introducing Dom4j jar SAXReader reader = new SAXReader(); ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); // Get the specified xml file from the class directory InputStream ins = classLoader.getResourceAsStream(xml); Document doc = reader.read(ins); Element root = (Element) doc.getRootElement(); Element foo; //Traversal bean for (Iterator i = root.elementIterator("bean"); i.hasNext(); ) { foo = (Element) i.next(); //Get the attribute id and class of the bean Attribute id = foo.attribute("id"); Attribute cls = foo.attribute("class"); //Use the java reflection mechanism to obtain the class object through the name of the class Class bean = Class.forName(cls.getText()); //Get the information of the corresponding class java.beans.BeanInfo info = java.beans.Introspector.getBeanInfo(bean); //Get its property description java.beans.PropertyDescriptor pd[] = info.getPropertyDescriptors(); //Method of setting value Method mSet = null; //Create an object Object obj = bean.newInstance(); //Traverse the property property of the bean for (Iterator ite = foo.elementIterator("property"); ite.hasNext(); ) { Element foo2 = (Element) ite.next(); //Get the name property of the property Attribute name = foo2.attribute("name"); String value = null; //Gets the value of the child element value of the property for (Iterator ite2 = foo2.elementIterator("value"); ite2.hasNext(); ) { Element node = (Element) ite2.next(); value = node.getText(); break; } for (int k = 0; k < pd.length; k++) { if (pd[k].getName().equalsIgnoreCase(name.getText())) { mSet = pd[k].getWriteMethod(); //Use Java's reflection mechanism to call a set method of the object and set the value mSet.invoke(obj, value); } } } //Put the object into beanMap, where key is the id value and value is the object beanMap.put(id.getText(), obj); } } catch (Exception e) { System.out.println(e.toString()); } } }