Spring source code analysis (process combing)

Preface

In the recent Chinese New Year, I’m waiting for a job at home. I want to be idle and I’m still idle. Just charge and play with Spring's source code. Whenever Spring is mentioned, IOC and AOP will appear in my mind. I
Insert picture description here
need to get the IOC first. IOC first understand it. Then understanding AOP is even simpler!

IOC

Summary
Most people know that IOC is a container, which translates to inversion of control, which means that we manually create Java objects to Spring to manage.
Insert picture description here
When we write Java code, we need new. What kind of object we need is the new object. This is not a problem in itself, but the operation efficiency of new every time is low, or that the new operation is generated by ourselves, we ourselves To generate this new operation, if we need 10 objects, then we need new 10 times, and if we need 100 times, we need new 100 times, which is relatively inefficient. Then we can leave this operation to Spring to complete, then use Spring IOC container to complete. The container is to store Java objects, that is, Beans, then these Beans are stored in a series of Java collections, such as Map, List, etc., then the underlying implementation principle of the IOC container is actually reflection. @Autowired completes bean injection through reflection

reflection

public class UserService {
    
    
}

public class UserController {
    
    

    private UserService userService;

    public UserService getUserService() {
    
    
        return userService;
    }

    public void setUserService(UserService userService) {
    
    
        this.userService = userService;
    }
}

public class MyTestList {
    
    

    @Test
    public void test() throws Exception {
    
    

        UserController userController=new UserController();
        Class<? extends UserController> clazz = userController.getClass();
        //创建对象
        UserService userService = new UserService();
        System.out.println(userService);
        //获取属性
        Field serviceField = clazz.getDeclaredField("userService");
        serviceField.setAccessible(true);//设置为可访问私有属性
        //只有通过方法才能够设置具体的属性值
        String name = serviceField.getName();
        //拼接方法的名称
        name = name.substring(0, 1).toUpperCase() + name.substring(1, name.length());
        String setMethodName = "set" + name;
        //通过方法注入属性的对象--这里还没注入,只是在构建入参和需要执行的方法
        Method method = clazz.getMethod("setUserService", UserService.class);
        //反射--也就是执行ssetUserService这个方法
        method.invoke(userController, userService);
        System.out.println(userController.getUserService());
    }
}

Reflection implementation @Autowired

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
@Inherited/
@Documented
public @interface MyAutowired {
    
    
}


public class UserService {
    
    
}


public class UserController {
    
    

    @MyAutowired
    private UserService userService;

    public UserService getUserService() {
    
    
        return userService;
    }
}

public class Test2 {
    
    
    public static void main(String[] args)  {
    
    
        UserController userController=new UserController();
        Class<? extends UserController> clazz = userController.getClass();

        获取所有属性,并遍历
        Stream.of(clazz.getDeclaredFields()).forEach(field->{
    
    
            MyAutowired annotation = field.getAnnotation(MyAutowired.class);
            if (annotation!=null){
    
    
                field.setAccessible(true);
                //得到属性的类型
                Class<?> type = field.getType();
                try {
    
    
                    //创建这个属性类型的对象
                    Object o = type.newInstance();
                    //设置属性值
                    field.set(userController,o);
                } catch (InstantiationException e) {
    
    
                    e.printStackTrace();
                } catch (IllegalAccessException e) {
    
    
                    e.printStackTrace();
                }
            }
        });
        System.out.println(userController.getUserService());
    }

}

The above demonstrates two reflection cases. Now back to the IOC part. IOC is a container that can help us complete the overall creation of objects. After creation, we can directly obtain Java objects in the IOC container, which is easy to understand. IOC is how we obtain specific objects. The simple understanding of these objects is that they are stored in the Map, and the value in the Map can be obtained directly according to the key. Then let's see how he creates and stores the object in the IOC! Below is the general flow chart
Insert picture description here

  • The above group of xml and annotation is generally called BeanDefinition. BeanDefinition describes a bean instance with attribute values, constructor parameter values, and further information provided by the specific implementation.

  • Read the Bean BeanDefinitionfor storage through this BeanDefinitionReader interface

After reading the information of Bean, we start to instantiate it. Of course, Spring is not just a framework, but also an ecology. In order to support more flexible and efficient upper-layer applications, for Spring, we need to consider more scalability and extensibility. , Scalability, and scalability make it impossible to simply instantiate here!

  • When the Bean object is created, it is created BeanFunctionby obtaining the BeanDefinition and using reflection.
  • BeanFactoryPostProcessor, This interface is inherited to complete the expansion operation. For example, when we read the Bean, we need to call a specific method, then we can use this interface to complete
  • 实例化和初始化, Instantiation is to call the corresponding construction method, and then open up a memory space, but the properties inside have not completed the assignment operation, then after the instantiation is completed, a series of initialization operations need to be completed, then instantiate here—>initialize—> When the initialization is complete, then AOP is formed, which also includes BeanPostProcessorthis interface
  • EnvironmentA series of system environment values ​​are encapsulated in this interface, and you can call them directly if you need to get them in the code.

Difference between BeanFactory and FactoryBean

There are two ways to create objects, one is BeanFactory and the other is FactoryBean. In general, our regular objects are created with BeanFactory. When some special objects need to be customized, then FactoryBean needs to be used. To complete, then you can use getObject to customize the processing when using FactoryBean to implement it, and implement it as you want, and feign uses this method of implementation.

public class MyFactoryBean implements FactoryBean {
    
    
    @Override
    public Object getObject() throws Exception {
    
    
        TestMain testMain = new TestMain();
        System.out.println("----------一系列而外的定制操作-----------");
        //以直接通过getObject方法来完成定制化的Bran,无需使用BeanFactory一步一步按流程生成!
        return testMain;
    }
   
    @Override
    public Class<?> getObjectType() {
    
    
        return null;
    }

    @Override
    public boolean isSingleton() {
    
    
        return true;
    }
}

Guess you like

Origin blog.csdn.net/CSDN877425287/article/details/113760260