spring源码01-spring容器启动流程概述

【README】

1)本文使用了spring-6.1.10制品库;

2)本文使用AnnotationConfigApplicationContext容器类型(注解配置应用容器), 基于java配置构建spring应用,无需xml配置;

3)基于spring构建应用系统分为2个阶段(或者狭义理解为spring容器启动过程分为2个阶段)

  1. 容器初始化阶段:
    1. 实例化容器,BeanDefinition读取器,类路径扫描器;
    2. 准备环境,包括注册属性bean(如os环境变量,jvm系统变量)到容器;
    3. 注册BeanFactory后置处理器并触发其后置处理方法,包括触发BeanDefinition注册后置处理器(使用扫描器与读取器读取并注册BeanDefinition到容器),触发BeanFactory后置处理器(如增强配置类);
    4. 注册Bean后置处理器到容器(用户自定义的Bean后置处理器);
    5. 注册消息源MessageSource到容器,用于国际化;
    6. 注册应用事件多播器到容器,用于发布spring各阶段事件;
    7. 注册应用监听器到容器,用于监听spring事件;
  2. bean实例化阶段:大致思想是根据BeanDefinition实例化bean

4)补充:

  • 实例化:就是创建或new的意思;
  • 初始化:可以简单理解为设置属性,装配依赖bean;

【1】基于java配置的spring容器

【JavaBasedContainerUsingSeveralJavaConfigMain】

public class JavaBasedContainerUsingSeveralJavaConfigMain {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(); // 实例化容器 
        System.out.println("before register()"); 
        context.register(AppConfig00.class, AppConfig02.class); // 注册配置类BeanDefinition 
        System.out.println("after register()");
        context.refresh(); // 刷新容器(最主要的步骤是实例化bean) 
        System.out.println("after refresh()");
        context.getBean(HelloService.class).sayHello("Musk");
        context.getBean(HelloService02.class).sayHello("Trump");
    }
}

【运行日志】

before register()
after register()
AppConfig00 构造器
AppConfig02 构造器
after refresh()
HelloService#sayHell(): hello Musk
HelloService2#sayHell():  hello Trump

【配置类】

@Configuration
public class AppConfig00 {

    public AppConfig00() {
        System.out.println("AppConfig00 构造器");
    }
    @Bean
    public HelloService helloService() {
        return new HelloService();
    }
}

【服务类】

public class HelloService {

    public void sayHello(String user) {
        System.out.println("HelloService#sayHell(): hello " + user);
    }
}

【pom.xml】 参见 pom.xml



【2】spring容器初始化代码

【2.1】实例化容器AnnotationConfigApplicationContext

1)实例化容器:AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(); // 实例化容器

【AnnotationConfigApplicationContext 】 实例化容器, BeanDefinition读取器,类路径BeanDefinition扫描器

public class AnnotationConfigApplicationContext extends GenericApplicationContext implements AnnotationConfigRegistry {
    // ... 
}
public AnnotationConfigApplicationContext() {
		StartupStep createAnnotatedBeanDefReader = getApplicationStartup().start("spring.context.annotated-bean-reader.create");
		// 实例化 BeanDefinition读取器
    	this.reader = new AnnotatedBeanDefinitionReader(this); 
		createAnnotatedBeanDefReader.end();
        // 实例化 类路径BeanDefinition扫描器 
		this.scanner = new ClassPathBeanDefinitionScanner(this); 
	}

【GenericApplicationContext】 实例化BeanFactory,类型为DefaultListableBeanFactory;

public GenericApplicationContext() {
		this.beanFactory = new DefaultListableBeanFactory();
	}


【2.2】注册配置类BeanDefinition

1)调用context.register(AppConfig00.class, AppConfig02.class); 注册配置类BeanDefinition ;

AnnotationConfigApplicationContext#register()方法接着调用this.reader.register(componentClasses);

【AnnotationConfigApplicationContext】

public void register(Class<?>... componentClasses) {
    Assert.notEmpty(componentClasses, "At least one component class must be specified");
    StartupStep registerComponentClass = getApplicationStartup().start("spring.context.component-classes.register")
          .tag("classes", () -> Arrays.toString(componentClasses));
    this.reader.register(componentClasses); // 使用BeanDefinition阅读器注册给定class的BeanDefinition 
    registerComponentClass.end();
}

【doRegisterBean】注册给定class的BeanDefinition

private <T> void doRegisterBean(Class<T> beanClass, @Nullable String name,
			@Nullable Class<? extends Annotation>[] qualifiers, @Nullable Supplier<T> supplier,
			@Nullable BeanDefinitionCustomizer[] customizers) {

    	// 实例化 BeanDefinition 
		AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(beanClass); 
		if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
			return;
		}

		abd.setAttribute(ConfigurationClassUtils.CANDIDATE_ATTRIBUTE, Boolean.TRUE);
		abd.setInstanceSupplier(supplier);
		ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
		abd.setScope(scopeMetadata.getScopeName());
		String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));
		
    	// 处理公共BeanDefinition注解(包括@Lazy, @Primary, @DependsOn, )
		AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);
		
		if (customizers != null) {
			for (BeanDefinitionCustomizer customizer : customizers) {
				customizer.customize(abd);
			}
		}
        // 实例化BeanDefinitionHolder, BeanDefinition持有器 
		BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
		definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
        // 注册BeanDefinition 
		BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
	}
// 注册BeanDefinition, registry实际就是AnnotationConfigApplicationContext(spring容器本身)
public static void registerBeanDefinition(BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry) throws BeanDefinitionStoreException {
        String beanName = definitionHolder.getBeanName();
        registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());
        String[] aliases = definitionHolder.getAliases();
        if (aliases != null) {
            String[] var4 = aliases;
            int var5 = aliases.length;

            for(int var6 = 0; var6 < var5; ++var6) {
                String alias = var4[var6];
                registry.registerAlias(beanName, alias);
            }
        }

    }


【2.3】刷新容器(主要是实例化bean)【重要】

1)调用context.refresh(); 刷新容器;

【AbstractApplicationContext#refresh()】刷新容器

public void refresh() throws BeansException, IllegalStateException {
    this.startupShutdownLock.lock();
    try {
       this.startupShutdownThread = Thread.currentThread();
       StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");

       // 1 刷新容器的准备工作,包括初始化属性源,并校验属性,保存应用监听器; 
       // Prepare this context for refreshing. 
       prepareRefresh();
		
        // 2 默认实现:获取最新容器,包括把容器hashcode赋值给BeanFactory的序列化id
        // 也可以由子类来刷新内部BeanFactory
       // Tell the subclass to refresh the internal bean factory.
       ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
	
        // 3 初始化BeanFactory 
       // Prepare the bean factory for use in this context.
       prepareBeanFactory(beanFactory);

       try {
           // 4 protected方法,允许子类自行定义BeanFactory的后置处理逻辑 
          // Allows post-processing of the bean factory in context subclasses.
          postProcessBeanFactory(beanFactory);

          StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");
           // 5 触发BeanFacotry后置处理器
          // Invoke factory processors registered as beans in the context.
          invokeBeanFactoryPostProcessors(beanFactory);
           
           // 6 注册Bean后置处理器
          // Register bean processors that intercept bean creation.
          registerBeanPostProcessors(beanFactory);
          beanPostProcess.end();

           // 7 初始化消息源 ,用于国际化 
          // Initialize message source for this context.
          initMessageSource();
		
           // 8 初始化应用事件多播器 
          // Initialize event multicaster for this context.
          initApplicationEventMulticaster();
		
           // 9 子类可以重写的模板方法,以添加特定于上下文的刷新工作。在实例化单例之前,在初始化特殊 bean 时调用;
          // Initialize other special beans in specific context subclasses.
          onRefresh();
		
           // 10 注册监听器,包括应用事件多播器
          // Check for listener beans and register them.
          registerListeners();
		
           // 11 实例化所有剩余的单例bean
          // Instantiate all remaining (non-lazy-init) singletons.
          finishBeanFactoryInitialization(beanFactory);
			
          // 12 容器刷新的收尾工作,包括清空缓存,注册生命周期处理器并执行其onRefresh(),发布ContextRefreshedEvent事件;
          // Last step: publish corresponding event.
          finishRefresh();
       }

       catch (RuntimeException | Error ex ) {          
           
           // 异常1: 销毁bean
          // Destroy already created singletons to avoid dangling resources.
          destroyBeans();
          
          // Reset 'active' flag.
          cancelRefresh(ex);

          // Propagate exception to caller.
          throw ex;
       }

       finally {
          contextRefresh.end();
       }
    }
    finally {
       this.startupShutdownThread = null;
       this.startupShutdownLock.unlock();
    }
}


【2.3.1】刷新容器步骤概述

1)刷新容器步骤:

step1)prepareRefresh():刷新容器的准备工作,包括初始化属性源,并校验属性,保存应用监听器;

step2)obtainFreshBeanFactory():获取最新容器,包括把容器hashcode赋值给BeanFactory的序列化id

step3)prepareBeanFactory(beanFactory):初始化BeanFactory,包括设置属性(类加载器,属性编辑器注册器),注册单例(environment,systemProperties系统属性,systemEnvironment环境变量),新增BeanPostProcessor(ApplicationContextAwareProcessor,ApplicationListenerDetector)

step4)postProcessBeanFactory(beanFactory):protected方法,允许子类自行定义BeanFactory的后置处理逻辑;

step5)invokeBeanFactoryPostProcessors(beanFactory):触发BeanFacotry后置处理器,包括触发BeanDefinition注册后置处理器(注册配置类及其方法的BeanDefinition),触发BeanFactory后置处理器(增强配置类,新增Bean后置处理器ImportAwareBeanPostProcessor,新增事件监听器方法处理器EventListenerMethodProcessor)

step6)registerBeanPostProcessors(beanFactory): 注册Bean后置处理器;

step7)initMessageSource(): 初始化消息源,包括注册name=messageSource且类型=DelegatingMessageSource的bean;

step8)initApplicationEventMulticaster(): 初始化应用事件多播器,包括注册name=applicationEventMulticaste且类型=SimpleApplicationEventMulticaster的bean;

step9)onRefresh():可以重写的模板方法,以添加特定于上下文的刷新工作。在实例化单例之前,在初始化特殊 bean 时调用;

step10)registerListeners():注册监听器,包括应用事件多播器(ApplicationEventMulticaster)添加应用监听器(ApplicationListener)及多播应用事件;

step11)finishBeanFactoryInitialization(): 实例化所有剩余的单例bean, 包括新增嵌入值解析器(如PropertySourcesPlaceholderConfigurer),冻结配置信息,实例化单例bean

step12)finishRefresh(): 容器刷新的收尾工作,包括清空缓存,注册生命周期处理器DefaultLifecycleProcessor(name=lifecycleProcessor)并执行其onRefresh(),发布ContextRefreshedEvent事件;

2)刷新容器步骤小结:

  • 初始化BeanFactory,包括设置属性,注册属性单例,注册Bean后置处理器;
  • 触发BeanFactory后置处理器, 包括触发BeanDefinition注册后置处理器以注册BeanDefinition,BeanFactory后置处理器;
  • 注册Bean后置处理器;
  • 初始化MessageSource,用于国际化;
  • 实例化应用事件多播器,应用监听器,用于发布spring启动事件通知订阅者;
  • 根据BeanDefinition实例化bean(最重要)-finishBeanFactoryInitialization()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值