spring5.x-IOC module source code learning

Above: Spring5.x introduction and matching spring source code reading environment


IOC introduction

    Spring's IOC and DI

Demonstration case

com.hong.model.User

package com.hong.model;

import org.springframework.stereotype.Component;

import java.io.Serializable;

/**
* @ClassName User
* @Description 用户
* @Author csh
* @Date 2023/1/13 14:27
*/
@Component
    public class User{
        private String userName;
        private int age;
        private String nickName;

        public String getUserName() {
            return userName;
        }

        public void setUserName(String userName) {
            this.userName = userName;
        }

        public int getAge() {
            return age;
        }

        public void setAge(int age) {
            this.age = age;
        }

        public String getNickName() {
            return nickName;
        }

        public void setNickName(String nickName) {
            this.nickName = nickName;
        }

        public User() {
            this.userName = "hong";
        }
    }

com.hong.ioc.IocConfig

package com.hong.ioc;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

/**
* @ClassName IocConfig
* @Description ioc配置
* @Author csh
* @Date 2023/1/13 14:29
*/
@Configuration
    @ComponentScan(basePackages = {"com.hong"})
    public class IocConfig {
    }

com.hong.ioc.IocSourceStudy

package com.hong.ioc;

import com.hong.model.User;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

/**
* @ClassName IocSourceStudy
* @Description ioc学习
* @Author csh
* @Date 2023/1/13 14:26
*/
public class IocSourceStudy {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(IocConfig.class);
        User user = applicationContext.getBean("user",User.class);
        System.out.println(user.getUserName());
    }
}

Results of the

16:12:26: Executing task 'IocSourceStudy.main()'...

    > Task :buildSrc:compileJava UP-TO-DATE
    > Task :buildSrc:compileGroovy NO-SOURCE
    > Task :buildSrc:pluginDescriptors UP-TO-DATE
    > Task :buildSrc:processResources UP-TO-DATE
    > Task :buildSrc:classes UP-TO-DATE
    > Task :buildSrc:jar UP-TO-DATE
    > Task :buildSrc:assemble UP-TO-DATE
    > Task :buildSrc:pluginUnderTestMetadata UP-TO-DATE
    > Task :buildSrc:compileTestJava NO-SOURCE
    > Task :buildSrc:compileTestGroovy NO-SOURCE
    > Task :buildSrc:processTestResources NO-SOURCE
    > Task :buildSrc:testClasses UP-TO-DATE
    > Task :buildSrc:test NO-SOURCE
    > Task :buildSrc:validateTaskProperties UP-TO-DATE
    > Task :buildSrc:check UP-TO-DATE
    > Task :buildSrc:build UP-TO-DATE
    > Task :spring-core:cglibRepackJar UP-TO-DATE
    > Task :spring-aop:processResources UP-TO-DATE
    > Task :spring-core:objenesisRepackJar UP-TO-DATE
    > Task :spring-hong-testing:processResources NO-SOURCE
    > Task :spring-expression:processResources UP-TO-DATE
    > Task :spring-beans:processResources UP-TO-DATE
    > Task :spring-core:processResources UP-TO-DATE
    > Task :spring-context:processResources UP-TO-DATE
    > Task :spring-instrument:compileJava UP-TO-DATE
    > Task :spring-instrument:processResources NO-SOURCE
    > Task :spring-instrument:classes UP-TO-DATE
    > Task :spring-instrument:jar UP-TO-DATE
    > Task :kotlin-coroutines:compileKotlin UP-TO-DATE
    > Task :kotlin-coroutines:compileJava NO-SOURCE
    > Task :kotlin-coroutines:processResources NO-SOURCE
    > Task :kotlin-coroutines:classes UP-TO-DATE
    > Task :spring-jcl:compileJava UP-TO-DATE
    > Task :kotlin-coroutines:inspectClassesForKotlinIC UP-TO-DATE
    > Task :spring-jcl:processResources UP-TO-DATE
    > Task :spring-jcl:classes UP-TO-DATE
    > Task :kotlin-coroutines:jar UP-TO-DATE
    > Task :spring-jcl:jar UP-TO-DATE
    > Task :spring-core:compileKotlin UP-TO-DATE
    > Task :spring-core:compileJava UP-TO-DATE
    > Task :spring-core:classes UP-TO-DATE
    > Task :spring-core:inspectClassesForKotlinIC UP-TO-DATE
    > Task :spring-core:jar UP-TO-DATE
    > Task :spring-expression:compileKotlin UP-TO-DATE
    > Task :spring-expression:compileJava UP-TO-DATE
    > Task :spring-expression:classes UP-TO-DATE
    > Task :spring-expression:inspectClassesForKotlinIC UP-TO-DATE
    > Task :spring-expression:jar UP-TO-DATE
    > Task :spring-beans:compileGroovy UP-TO-DATE
    > Task :spring-beans:compileKotlin UP-TO-DATE
    > Task :spring-beans:compileJava NO-SOURCE
    > Task :spring-beans:classes UP-TO-DATE
    > Task :spring-beans:inspectClassesForKotlinIC UP-TO-DATE
    > Task :spring-beans:jar UP-TO-DATE
    > Task :spring-aop:compileJava UP-TO-DATE
    > Task :spring-aop:classes UP-TO-DATE
    > Task :spring-aop:jar UP-TO-DATE
    > Task :spring-context:compileKotlin UP-TO-DATE
    > Task :spring-context:compileJava UP-TO-DATE
    > Task :spring-context:compileGroovy NO-SOURCE
    > Task :spring-context:classes UP-TO-DATE
    > Task :spring-context:inspectClassesForKotlinIC UP-TO-DATE
    > Task :spring-context:jar UP-TO-DATE
    > Task :spring-hong-testing:compileJava
    > Task :spring-hong-testing:classes

    > Task :spring-hong-testing:IocSourceStudy.main()
    hong

    BUILD SUCCESSFUL in 15s
    35 actionable tasks: 2 executed, 33 up-to-date
    16:12:42: Task execution finished 'IocSourceStudy.main()'.

Correlation Dependency Graph

26c2e4eaf762ed8dfa6c43d315619cff.png

IOC loading process

691b245e8b33c58b9a0a1022c8310c6b.png

Instantiate container: AnnotationConfigApplicationContext

org.springframework.context.annotation.AnnotationConfigApplicationContext#AnnotationConfigApplicationContext(java.lang.Class<?>...)

public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
    //调用无参构造方法 进行实例化AnnotationConfigApplicationContext
    this();
    //注册类 注册分两种一种是配置文件 比如.xml 还有一种就是指定的.class(bean)
    register(componentClasses);
    //刷新
    refresh();
}

1. Call this() in the constructor;

org.springframework.context.annotation.AnnotationConfigApplicationContext#AnnotationConfigApplicationContext()

public AnnotationConfigApplicationContext() {
    //初始化bean读取器
    this.reader = new AnnotatedBeanDefinitionReader(this);
    //初始化类扫描器
    this.scanner = new ClassPathBeanDefinitionScanner(this);
}

1.1 The specific implementation of this

org.springframework.context.annotation.AnnotatedBeanDefinitionReader#AnnotatedBeanDefinitionReader(org.springframework.beans.factory.support.BeanDefinitionRegistry, org.springframework.core.env.Environment)

public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) {
    Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
    Assert.notNull(environment, "Environment must not be null");
    this.registry = registry;
    //@Conditional的实始化
    this.conditionEvaluator = new ConditionEvaluator(registry, environment, null);
    //初始化相关组件 比如 @Order @lazy 与@Qualifier注解 @Autowired与@Value注解的 等 
    AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
}
1.1.1 Initialize related components such as @Order @lazy and @Qualifier annotations @Autowired and @Value annotations, etc.

org.springframework.context.annotation.AnnotationConfigUtils#registerAnnotationConfigProcessors(org.springframework.beans.factory.support.BeanDefinitionRegistry, java.lang.Object)

public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
    BeanDefinitionRegistry registry, @Nullable Object source) {
    //@EventListener的初始化
    DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
    if (beanFactory != null) {
        //解析@Order 初始化
        if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
            beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
        }
        //解析@lazy 与@Qualifier注解 初始化
        if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
            beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
        }
    }

    Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);
    //新增解析配置类的处理器
    if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
        RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
        def.setSource(source);
        beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
    }
    //新增处理@Autowired与@Value注解的后置处理器
    if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
        RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
        def.setSource(source);
        beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
    }

    // 检查是否支持JSR-250 新增处理@Resource 注解的后置处理器
    if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) {
        RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class);
        def.setSource(source);
        beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME));
    }

    // 检查是否支持JPA,将启用JPA注解支持
    if (jpaPresent && !registry.containsBeanDefinition(PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)) {
        RootBeanDefinition def = new RootBeanDefinition();
        try {
            def.setBeanClass(ClassUtils.forName(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME,
                                                AnnotationConfigUtils.class.getClassLoader()));
        }
        catch (ClassNotFoundException ex) {
            throw new IllegalStateException(
                "Cannot load optional framework class: " + PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME, ex);
        }
        def.setSource(source);
        beanDefs.add(registerPostProcessor(registry, def, PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME));
    }
    //监听器的支持@EventListener注解
    if (!registry.containsBeanDefinition(EVENT_LISTENER_PROCESSOR_BEAN_NAME)) {
        RootBeanDefinition def = new RootBeanDefinition(EventListenerMethodProcessor.class);
        def.setSource(source);
        beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_PROCESSOR_BEAN_NAME));
    }
    //指定监听器的默认实现类
    if (!registry.containsBeanDefinition(EVENT_LISTENER_FACTORY_BEAN_NAME)) {
        RootBeanDefinition def = new RootBeanDefinition(DefaultEventListenerFactory.class);
        def.setSource(source);
        beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_FACTORY_BEAN_NAME));
                     }

                     return beanDefs;
                     }

2. register(componentClasses); implementation

bab6471e1d7e37d9dc07032309f87376.png

org.springframework.context.annotation.AnnotatedBeanDefinitionReader#doRegisterBean

private <T> void doRegisterBean(Class<T> beanClass, @Nullable String name,
      @Nullable Class<? extends Annotation>[] qualifiers, @Nullable Supplier<T> supplier,
      @Nullable BeanDefinitionCustomizer[] customizers) {
    //对bean进行封装
    AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(beanClass);
    //如果为空或类型不一致则直接返回
    if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
      return;
    }
    //设置bean的回调
    abd.setInstanceSupplier(supplier);
    //解析bean的作用域 有两种类型如下:
    // @Scope("prototype") 原类型
    // @Scope("singleton"),单态类型 默认不配的情况下是这种
    ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
    //设置作用域
    abd.setScope(scopeMetadata.getScopeName());
    String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));
    //主要用于判断这个类有没有包含 Lazy Primary DependsOn Role Description 这些注释或属性有的话进行设置。
    AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);
    //如果不为空 匹配是 @Primary 或@Lazy 或@Qualifier 都进行初始化设置
    if (qualifiers != null) {
      for (Class<? extends Annotation> qualifier : qualifiers) {
        if (Primary.class == qualifier) {
          abd.setPrimary(true);
        }
        else if (Lazy.class == qualifier) {
          abd.setLazyInit(true);
        }
        else {
          abd.addQualifier(new AutowireCandidateQualifier(qualifier));
        }
      }
    }
    //如果存在个性化配置进行增加
    if (customizers != null) {
      for (BeanDefinitionCustomizer customizer : customizers) {
        customizer.customize(abd);
      }
    }
    //进行BeanDefinition的封装
    BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
    //根据作用域创建代理对象。
    //默认NO 是不创建代理对象 当然还有JDK和CGLib
    definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
    //最后注册成bean对象
    BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
  }
3. The implementation of refresh() refresh;

org.springframework.context.support.AbstractApplicationContext#refresh

@Override
  public void refresh() throws BeansException, IllegalStateException {
    synchronized (this.startupShutdownMonitor) {
      // 为刷新准备上下文,保存容器启动时间和设置关闭状态为否及运行状态启动等初始化工作
      prepareRefresh();

      // 告诉子类刷新内部bean工厂。初始化bean工厂
      ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

      //准备在此上下文中使用的bean工厂。
      prepareBeanFactory(beanFactory);

      try {
        // 允许在上下文子类中对bean工厂进行后处理。(前置处理器)
        postProcessBeanFactory(beanFactory);

        //调用上下文中注册为bean的工厂处理器。(为beanFactory注册的事件处理器)
        invokeBeanFactoryPostProcessors(beanFactory);

        //调用bean的后置处理器
        registerBeanPostProcessors(beanFactory);

        // 初始化国际化资源处理器
        initMessageSource();

        //创建事件多播器
        initApplicationEventMulticaster();

        // 初始化扩展的自定义插件 比如tomcat
        onRefresh();

        // 检查侦听器bean并注册它们。
        registerListeners();

        //实例化所有剩余的(非lazy-init)单例。
        finishBeanFactoryInitialization(beanFactory);

        //最后容器刷新 发布刷新后的事件
        finishRefresh();
      }

      catch (BeansException ex) {
        if (logger.isWarnEnabled()) {
          logger.warn("Exception encountered during context initialization - " +
              "cancelling refresh attempt: " + ex);
        }

        // destroy already created singletons to avoid dangling resources.
        destroyBeans();

        // 重置标记
        cancelRefresh(ex);

        // Propagate exception to caller.
        throw ex;
      }

      finally {
        //重置单例bean元数据(清空缓存)
        resetCommonCaches();
      }
    }
  }

Implementation of prepareBeanFactory

org.springframework.context.support.AbstractApplicationContext#prepareBeanFactory

protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
    // 告诉内部bean工厂使用上下文的类装入器等。
    beanFactory.setBeanClassLoader(getClassLoader());
    beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
    beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));

    // 使用上下文回调来配置bean工厂。
    beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
    beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
    beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
    beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
    beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
    beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
    beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);

    // 在普通工厂中,BeanFactory接口未注册为可解析类型。
    // MessageSource作为bean注册(并找到用于自动装配)。
    beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
    beanFactory.registerResolvableDependency(ResourceLoader.class, this);
    beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
    beanFactory.registerResolvableDependency(ApplicationContext.class, this);

    //将早期的后置处理器注册为应用监听器,用于检测内部bean。
    beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));

    // 检查存在loadTimeWeaver 的类型则进行设置
    if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
      beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
      //为类型匹配设置一个临时的ClassLoader。
      beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
    }

    // 注册默认环境bean。
    if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
      beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
    }
    if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
      beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
    }
    if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
      beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
    }
  }

at last

    The above is the general initialization process of IOC. A detailed understanding will help to understand other spring implementation mechanisms in depth.

References:

https://github.com/DocsHome/spring-docs/blob/master/pages/core/IoC-container.mdhttps://blog.csdn.net/weixin_43738764/article/details/124966670https://blog.csdn.net/weixin_41605937/article/details/115004381https://www.jianshu.com/p/de879b493893

Guess you like

Origin blog.csdn.net/qq_16498553/article/details/129153084