How SpringBoot uses reflection to simulate IOC and getBean
Spring basic idea IOC
The second is java reflection. The reflection mechanism is an important implementation core of spring. Today when I looked at spring’s third-level cache to solve the problem of circular references, I discovered the life cycle of a bean. It is highly similar to the generation process of Java objects. Then I went over the bean creation process and found that the process of a bean instance from scratch is very interesting. Spring uses extremely elegant code to realize the use of reflection and various methods. This map data structure realizes the pipeline production of beans, which is very elegant, so I tried to use reflection to write a gadget that reversely generates instance objects.
Then you need to understand the process of generating an object beforehand:
I summarize the object creation process as:
Check whether there is a symbolic reference to the object in the constant pool and determine Whether it has gone through the class loading process, if not, the class loading process will be carried out.
Allocate memory for new objects (two methods: pointer collision and free list
Set the object header.
Object initialization, this is the process of executing your constructor method and assigning the values you want to define to the fields you need.
Add some details: In the process of allocating memory for new objects, first of all, the memory size required by an object after the class loading is completed is completely determined. The process of allocating memory is actually in the Java heap. Divide a memory of equal size to it, but how to divide it? If the memory layout of the Java heap is allocated in a strict order, that is, one side is used and the other side is free, then the memory will be allocated by pointer collision. The so-called pointer is collected at the dividing line between the free area and the used area. When memory is required, the pointer moves backward until the length covered by the move is equal to the memory size required by the java object and stops and allocates. But what if the memory layout of the Java heap is fragmented and discontinuous? We can only maintain a list, which records the size and location information of all Java heap free areas. When allocating, we only need to find the most suitable area allocation for new objects.
The ability of the garbage collector and whether it can perform space compression and sorting determine whether the Java heap is regular. When the collectors we use are Serial and Parnew, they are allocated by pointer collision. When we use the CMS garbage collector, we need to use the troublesome free area table allocation.
Here we focus on filling in the properties and methods: the soul of an object is its properties and methods:
The core properties used by the entire tool:
private static volatile Constructor<?> constructor;
private static volatile Object newInstance;
private static volatile Map<String, Method> methodMap;Let’s first look at the functions of these methods:
public static Constructor<?> getConstructor(Object dataType) {
Class<?> typeClass = dataType.getClass();
try {
Constructor<?> constructor = typeClass.getConstructor();
constructor.setAccessible(true);
return constructor;
} catch (NoSuchMethodException e) {
e.printStackTrace();
return null;
}
}Get the constructor of the type. Note that this is a no-parameter construct. If you don’t have a no-parameter construct, it is very likely to report an error, because we don’t know either. How many attributes does it have, right? (Always remember that we are reverse engineering!!! We don’t know what is in this type!!! Everything is information brought by reflection)
public static void fillValueToNewInstance(Object dataType, Map<String, Object> initialMap) throws Exception {
constructor = getConstructor(dataType);
Class<?> typeClass = dataType.getClass();
Field[] declaredFields = typeClass.getDeclaredFields();
Iterator<Field> fieldIterator = Arrays.stream(declaredFields).iterator();
newInstance = constructor.newInstance();
while (fieldIterator.hasNext()) {
Field field = fieldIterator.next();
field.setAccessible(true);
if (initialMap != null)
field.set(newInstance, initialMap.get(field.getName()));
}
}Get the attributes and fill in the attribute values, The attributes are also included here.
public static Method[] getMethodArray(Object dataType) {
return dataType.getClass().getDeclaredMethods();
}Get all methods to form a method array.
public static void fillMethodMap(Object dataType) {
methodMap = new HashMap<>();
Method[] methodArray = getMethodArray(dataType);
Iterator<Method> iterator = Arrays.stream(methodArray).iterator();
while (iterator.hasNext()) {
Method method = iterator.next();
method.setAccessible(true);
methodMap.put(method.getName(), method);
}
}Save the method into the method collection for storage.
public static Object useMethod(String methodName, @Nullable Object... parameters) throws Exception {
return methodMap.get(methodName).invoke(newInstance, parameters);
}The method of use is to pass the name.
@SneakyThrows
public static Object getBean(Object dataType, Map<String, Object> parameterMap) {
fillValueToNewInstance(dataType, parameterMap);
fillMethodMap(dataType);
return newInstance;
}getBean method.
public static void main(String[] args) throws Exception {
Map<String,Object> map = new HashMap<>();
map.put("name","xu");
map.put("age",Integer.valueOf(18));
map.put("sex",'女');
Person bean = (Person) getBean(new Person(), map);
System.out.println(bean.toString());
System.out.println(useMethod("toString"));
}Test method. The type information is as follows:
class Person {
private String name;
private Integer age;
private Character sex;
//无参构造绝对不能少
public Person() {
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
", sex=" + sex +
'}';
}
}The test results are as follows:

Here we do not use Person person = new Person(); to instantiate the object, use Reflection implements the instantiation of objects.
I will list the reflection methods used in it:
getDeclaredFields Get the domain attribute object
getName Get the attribute name
getType Get the word of the attribute type Section code file
setAccessible(true) Set brute force cracking and obtain the use of private attributes
getDeclaredMethods Get all method arrays
getClass Get bytecode file
getConstructor Get the parameterless constructor
The above is the detailed content of How SpringBoot uses reflection to simulate IOC and getBean. For more information, please follow other related articles on the PHP Chinese website!
Hot AI Tools
Undress AI Tool
Undress images for free
Undresser.AI Undress
AI-powered app for creating realistic nude photos
AI Clothes Remover
Online AI tool for removing clothes from photos.
Clothoff.io
AI clothes remover
Video Face Swap
Swap faces in any video effortlessly with our completely free AI face swap tool!
Hot Article
Hot Tools
Notepad++7.3.1
Easy-to-use and free code editor
SublimeText3 Chinese version
Chinese version, very easy to use
Zend Studio 13.0.1
Powerful PHP integrated development environment
Dreamweaver CS6
Visual web development tools
SublimeText3 Mac version
God-level code editing software (SublimeText3)
How Springboot integrates Jasypt to implement configuration file encryption
Jun 01, 2023 am 08:55 AM
Introduction to Jasypt Jasypt is a java library that allows a developer to add basic encryption functionality to his/her project with minimal effort and does not require a deep understanding of how encryption works. High security for one-way and two-way encryption. , standards-based encryption technology. Encrypt passwords, text, numbers, binaries... Suitable for integration into Spring-based applications, open API, for use with any JCE provider... Add the following dependency: com.github.ulisesbocchiojasypt-spring-boot-starter2. 1.1Jasypt benefits protect our system security. Even if the code is leaked, the data source can be guaranteed.
How to use Redis to implement distributed locks in SpringBoot
Jun 03, 2023 am 08:16 AM
1. Redis implements distributed lock principle and why distributed locks are needed. Before talking about distributed locks, it is necessary to explain why distributed locks are needed. The opposite of distributed locks is stand-alone locks. When we write multi-threaded programs, we avoid data problems caused by operating a shared variable at the same time. We usually use a lock to mutually exclude the shared variables to ensure the correctness of the shared variables. Its scope of use is in the same process. If there are multiple processes that need to operate a shared resource at the same time, how can they be mutually exclusive? Today's business applications are usually microservice architecture, which also means that one application will deploy multiple processes. If multiple processes need to modify the same row of records in MySQL, in order to avoid dirty data caused by out-of-order operations, distribution needs to be introduced at this time. The style is locked. Want to achieve points
How SpringBoot customizes Redis to implement cache serialization
Jun 03, 2023 am 11:32 AM
1. Customize RedisTemplate1.1, RedisAPI default serialization mechanism. The API-based Redis cache implementation uses the RedisTemplate template for data caching operations. Here, open the RedisTemplate class and view the source code information of the class. publicclassRedisTemplateextendsRedisAccessorimplementsRedisOperations, BeanClassLoaderAware{//Declare key, Various serialization methods of value, the initial value is empty @NullableprivateRedisSe
How to solve the problem that springboot cannot access the file after reading it into a jar package
Jun 03, 2023 pm 04:38 PM
Springboot reads the file, but cannot access the latest development after packaging it into a jar package. There is a situation where springboot cannot read the file after packaging it into a jar package. The reason is that after packaging, the virtual path of the file is invalid and can only be accessed through the stream. Read. The file is under resources publicvoidtest(){Listnames=newArrayList();InputStreamReaderread=null;try{ClassPathResourceresource=newClassPathResource("name.txt");Input
How to use the @Import annotation in SpringBoot
May 31, 2023 pm 06:25 PM
1. @Import introduces ordinary classes @Import introduces ordinary classes can help us define ordinary classes as Beans. @Import can be added to the classes corresponding to @SpringBootApplication (startup class), @Configuration (configuration class), and @Component (component class). Note: @RestController, @Service, and @Repository all belong to @Component@SpringBootApplication@Import(ImportBean.class)//ImportBean through the @Import annotation
How to implement Springboot+Mybatis-plus without using SQL statements to add multiple tables
Jun 02, 2023 am 11:07 AM
When Springboot+Mybatis-plus does not use SQL statements to perform multi-table adding operations, the problems I encountered are decomposed by simulating thinking in the test environment: Create a BrandDTO object with parameters to simulate passing parameters to the background. We all know that it is extremely difficult to perform multi-table operations in Mybatis-plus. If you do not use tools such as Mybatis-plus-join, you can only configure the corresponding Mapper.xml file and configure The smelly and long ResultMap, and then write the corresponding sql statement. Although this method seems cumbersome, it is highly flexible and allows us to
How SpringBoot integrates Redisson to implement delay queue
May 30, 2023 pm 02:40 PM
Usage scenario 1. The order was placed successfully but the payment was not made within 30 minutes. The payment timed out and the order was automatically canceled. 2. The order was signed and no evaluation was conducted for 7 days after signing. If the order times out and is not evaluated, the system defaults to a positive rating. 3. The order is placed successfully. If the merchant does not receive the order for 5 minutes, the order is cancelled. 4. The delivery times out, and push SMS reminder... For scenarios with long delays and low real-time performance, we can Use task scheduling to perform regular polling processing. For example: xxl-job Today we will pick
Comparison and difference analysis between SpringBoot and SpringMVC
Dec 29, 2023 am 11:02 AM
SpringBoot and SpringMVC are both commonly used frameworks in Java development, but there are some obvious differences between them. This article will explore the features and uses of these two frameworks and compare their differences. First, let's learn about SpringBoot. SpringBoot was developed by the Pivotal team to simplify the creation and deployment of applications based on the Spring framework. It provides a fast, lightweight way to build stand-alone, executable


