spring5.3 十一:spring启动过程源码分析

spring启动过程源码分析

当我们执行AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);这行代码的时候相当于spring容器启动。
在这里插入图片描述
先执行this方法:

public AnnotationConfigApplicationContext() {
		//调用该构造方法时,会先调用父类的构造方法 创建一个beanFactory
		StartupStep createAnnotatedBeanDefReader = this.getApplicationStartup().start("spring.context.annotated-bean-reader.create");
		
		this.reader = new AnnotatedBeanDefinitionReader(this);
		createAnnotatedBeanDefReader.end();
		//spring 扫描器  通过调用该类的scan方法进行扫描
		this.scanner = new ClassPathBeanDefinitionScanner(this);
	}
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) {
		Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
		Assert.notNull(environment, "Environment must not be null");
		//registry就是GenericApplicationContext的beanFactory
		this.registry = registry;
		//构建@Conditional注解的解析器
		this.conditionEvaluator = new ConditionEvaluator(registry, environment, null);
		//把BeanPostProcessor类型的BeanDefinition,注册到BeanFactory
		AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
	}

AnnotationConfigApplicationContext继承GenericApplicationContext所以先调用GenericApplicationContext的构造方法创建一个this.beanFactory = new DefaultListableBeanFactory()。然后接着创建了AnnotatedBeanDefinitionReader和ClassPathBeanDefinitionScanner。
在构造AnnotatedBeanDefinitionReader的时候额外的把BeanPostProcessor类型的BeanDefinition注册到BeanFactory中,同时添加环境变量到Environment中。基本上this()的流程就是这些。

this()执行完后 register(componentClasses)就是把传进来的类注册到BeanFactory。重点是refresh()方法
refresh()

public void refresh() throws BeansException, IllegalStateException {
		synchronized (this.startupShutdownMonitor) {
			StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");
			// Prepare this context for refreshing.
			//环境参数和监听器相关的准备
			prepareRefresh();
			// Tell the subclass to refresh the internal bean factory.
			//如果有创建新的beanFactory就返回新的beanFactory ,如果没有就返回之前的beanFactory
			ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
			// Prepare the bean factory for use in this context.
			// 准备BeanFactory
			// 1. 设置BeanFactory的类加载器、表达式解析器、类型转化注册器
			// 2. 添加三个BeanPostProcessor,注意是具体的BeanPostProcessor实例对象
			// 3. 记录ignoreDependencyInterface
			// 4. 记录ResolvableDependency
			// 5. 添加三个单例和环境变量有关的Bean
			prepareBeanFactory(beanFactory);
			try {
				// Allows post-processing of the bean factory in context subclasses.
				// 子类来设置一下BeanFactory
				postProcessBeanFactory(beanFactory);
				StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");
				// Invoke factory processors registered as beans in the context.
				// BeanFactory准备好了之后,执行BeanFactoryPostProcessor,开始对BeanFactory进行处理
				// 默认情况下:
				// 此时beanFactory的beanDefinitionMap中有6个BeanDefinition,5个基础BeanDefinition+AppConfig的BeanDefinition
				// 而这6个中只有一个BeanFactoryPostProcessor:ConfigurationClassPostProcessor
				// 这里会执行ConfigurationClassPostProcessor进行@Component的扫描,扫描得到BeanDefinition,并注册到beanFactory中
				// 注意:扫描的过程中可能又会扫描出其他的BeanFactoryPostProcessor,那么这些BeanFactoryPostProcessor也得在这一步执行
				invokeBeanFactoryPostProcessors(beanFactory);
				// Register bean processors that intercept bean creation.
				// 将扫描到的BeanPostProcessors实例化并排序,并添加到BeanFactory的beanPostProcessors属性中去
				registerBeanPostProcessors(beanFactory);
				beanPostProcess.end();
				// Initialize message source for this context
				// 国际化的初始化.
				// 设置ApplicationContext的MessageSource,要么是用户设置的,要么是DelegatingMessageSource
				initMessageSource();
				// Initialize event multicaster for this context.
				// 事件发布器的初始化
				// 设置ApplicationContext的applicationEventMulticaster,么是用户设置的,要么是SimpleApplicationEventMulticaster
				initApplicationEventMulticaster();
				// Initialize other special beans in specific context subclasses.
				// 给子类的模板方法
				onRefresh();
				// Check for listener beans and register them.
				//事件监听器的初始化
				// 把定义的ApplicationListener的Bean对象,设置到ApplicationContext中去,并执行在此之前所发布的事件
				registerListeners();
				// Instantiate all remaining (non-lazy-init) singletons.
				//实例化非懒加载的bean
				finishBeanFactoryInitialization(beanFactory);
				// Last step: publish corresponding event.
				//spring容器启动完成后的后续操作 添加程序员定义的容器生命周期监听器, 发布容器启动成功事件等
				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();
				// Reset 'active' flag.
				cancelRefresh(ex);
				// Propagate exception to caller.
				throw ex;
			}
			finally {
				// Reset common introspection caches in Spring's core, since we
				// might not ever need metadata for singleton beans anymore...
				resetCommonCaches();
				contextRefresh.end();
			}
		}
	}

refresh()的大致流程注释中已经说明,下面针对spring的启动做一个流程总结

spring启动流程总结

spring启动底层原理流程图:https://www.processon.com/view/link/5f60a7d71e08531edf26a919
以AnnotationConfigApplicationContext为例子。
一:在调用AnnotationConfigApplicationContext的构造方法之前,会调用父类GenericApplicationContext的无参构造方法,会构造一个BeanFactory,为DefaultListableBeanFactory。
二:构造AnnotatedBeanDefinitionReader(主要作用添加一些基础的PostProcessor,同时可以通过reader进行BeanDefinition的注册),同时对BeanFactory进行设置和添加PostProcessor(后置处理器)

  • 设置dependencyComparator:AnnotationAwareOrderComparator,它是一个Comparator,是用来进行排序的,会获取某个对象上的Order注解或者通过实现Ordered接口所定义的值进行排序,在日常开发中可以利用这个类来进行排序。
  • 设置autowireCandidateResolver:ContextAnnotationAutowireCandidateResolver,用来解析某个Bean能不能进行自动注入,比如某个Bean的autowireCandidate属性是否等于true
  • 向BeanFactory中添加ConfigurationClassPostProcessor对应的BeanDefinition,它是一个BeanDefinitionRegistryPostProcessor,并且实现了PriorityOrdered接口
  • 向BeanFactory中添加AutowiredAnnotationBeanPostProcessor对应的BeanDefinition,它是一个InstantiationAwareBeanPostProcessorAdapter,MergedBeanDefinitionPostProcessor
  • 向BeanFactory中添加CommonAnnotationBeanPostProcessor对应的BeanDefinition,它是一个InstantiationAwareBeanPostProcessor,InitDestroyAnnotationBeanPostProcessor
  • 向BeanFactory中添加EventListenerMethodProcessor对应的BeanDefinition,它是一个BeanFactoryPostProcessor,SmartInitializingSingleton
  • 向BeanFactory中添加DefaultEventListenerFactory对应的BeanDefinition,它是一个EventListenerFactory

三:构造ClassPathBeanDefinitionScanner(主要作用可以用来扫描得到并注册BeanDefinition),同时进行设置:

  • 设置this.includeFilters = AnnotationTypeFilter(Component.class)
  • 设置environment
  • 设置resourceLoader

四:利用reader注册AppConfig为BeanDefinition,类型为AnnotatedGenericBeanDefinition
五:接下来就是调用refresh方法
六:prepareRefresh()

  • 记录启动时间
  • 可以允许子容器设置一些内容到Environment中
  • 验证Environment中是否包括了必须要有的属性

七:obtainFreshBeanFactory():进行BeanFactory的refresh,在这里会去调用子类的refreshBeanFactory方法,具体子类是怎么刷新的得看子类,然后再调用子类的getBeanFactory方法,重新得到一个BeanFactory
八:prepareBeanFactory(beanFactory):

  • 设置beanFactory的类加载器
  • 设置表达式解析器:StandardBeanExpressionResolver,用来解析Spring中的表达式
  • 添加PropertyEditorRegistrar:ResourceEditorRegistrar,PropertyEditor类型转化器注册器,用来注册一些默认的PropertyEditor
  • 添加一个Bean的后置处理器:ApplicationContextAwareProcessor,是一个BeanPostProcessor,用来执行EnvironmentAware、ApplicationEventPublisherAware等回调方法
  • 添加ignoredDependencyInterface:可以向这个属性中添加一些接口,如果某个类实现了这个接口,并且这个类中的某些set方法在接口中也存在,那么这个set方法在自动注入的时候是不会执行的
  • 添加resolvableDependencies:在byType进行依赖注入时,会先从这个属性中根据类型找bean
    BeanFactory.class:当前BeanFactory对象
    ResourceLoader.class:当前ApplicationContext对象
    ApplicationEventPublisher.class:当前ApplicationContext对象
    ApplicationContext.class:当前ApplicationContext对象
  • 添加一个Bean的后置处理器:ApplicationListenerDetector,是一个BeanPostProcessor,用来判断某个Bean是不是ApplicationListener,如果是则把这个Bean添加到ApplicationContext中去,注意一个ApplicationListener只能是单例的
  • 添加一个Bean的后置处理器:LoadTimeWeaverAwareProcessor,是一个BeanPostProcessor,用来判断某个Bean是不是实现了LoadTimeWeaverAware接口,如果实现了则把ApplicationContext中的loadTimeWeaver回调setLoadTimeWeaver方法设置给该Bean。
  • 添加一些单例bean到单例池
    environment":Environment对象
    “systemProperties”:System.getProperties()返回的Map对象
    “systemEnvironment”:System.getenv()返回的Map对象

九:postProcessBeanFactory(beanFactory) : 提供给AbstractApplicationContext的子类进行扩展,具体的子类,可以继续向BeanFactory中再添加一些东西
十:invokeBeanFactoryPostProcessors(beanFactory):执行BeanFactoryPostProcessor

  • 此时在BeanFactory中会存在一个BeanFactoryPostProcessor:ConfigurationClassPostProcessor,它也是一个BeanDefinitionRegistryPostProcessor
  • 第一阶段
  • 从BeanFactory中找到类型为BeanDefinitionRegistryPostProcessor的beanName,也就是ConfigurationClassPostProcessor, 然后调用BeanFactory的getBean方法得到实例对象
  • 执行ConfigurationClassPostProcessor的postProcessBeanDefinitionRegistry方法:
    解析AppConfig类
    扫描得到BeanDefinition并注册
    解析@Import,@Bean等注解得到BeanDefinition并注册
  • 执行其他BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry方法
  • 执行所有BeanDefinitionRegistryPostProcessor的postProcessBeanFactory方法
  • 第二阶段
  • 从BeanFactory中找到类型为BeanFactoryPostProcessor的beanName,而这些BeanFactoryPostProcessor包括了上面的BeanDefinitionRegistryPostProcessor
  • 执行还没有执行过的BeanFactoryPostProcessor的postProcessBeanFactory方法

十一:到此,所有的BeanFactoryPostProcessor的逻辑都执行完了,主要做的事情就是得到BeanDefinition并注册到BeanFactory中
十二:registerBeanPostProcessors(beanFactory):因为上面的步骤完成了扫描,这个过程中程序员可能自己定义了一些BeanPostProcessor,在这一步就会把BeanFactory中所有的BeanPostProcessor找出来并实例化得到一个对象,并添加到BeanFactory中去(属性beanPostProcessors),最后再重新添加一个ApplicationListenerDetector对象(之前其实就添加了过,这里是为了把ApplicationListenerDetector移动到最后)
十三:initMessageSource():如果BeanFactory中存在一个叫做"messageSource"的BeanDefinition,那么就会把这个Bean对象创建出来并赋值给ApplicationContext的messageSource属性,让ApplicationContext拥有国际化的功能
十四:initApplicationEventMulticaster():如果BeanFactory中存在一个叫做"applicationEventMulticaster"的BeanDefinition,那么就会把这个Bean对象创建出来并赋值给ApplicationContext的applicationEventMulticaster属性,让ApplicationContext拥有事件发布的功能
十五:onRefresh():提供给AbstractApplicationContext的子类进行扩展,没用
十六:registerListeners():从BeanFactory中获取ApplicationListener类型的beanName,然后添加到ApplicationContext中的事件广播器applicationEventMulticaster中去,到这一步因为FactoryBean还没有调用getObject()方法生成Bean对象,所以这里要在根据类型找一下ApplicationListener,记录一下对应的beanName
十七:inishBeanFactoryInitialization(beanFactory):完成BeanFactory的初始化,主要就是实例化非懒加载的单例Bean。在生命周期部分分析过
十八:finishRefresh():BeanFactory的初始化完后,就到了Spring启动的最后一步了
十九:设置ApplicationContext的lifecycleProcessor,默认情况下设置的是DefaultLifecycleProcessor
二十:调用lifecycleProcessor的onRefresh()方法,如果是DefaultLifecycleProcessor,那么会获取所有类型为Lifecycle的Bean对象,然后调用它的start()方法,这就是ApplicationContext的生命周期扩展机制
二十一:发布ContextRefreshedEvent事件

spring的扩展点

事件发布和监听

如果发布事件的是一个String类型

//定义一个service 用来发布事件
@Service
public class GoodsServiceImpl{
	@Autowired
	private ApplicationContext context;

@PostConstruct
	public void goodsTest() {
		System.out.println("GoodsServiceImpl----@PostConstruct---初始化前执行");
		User user = new User(this);
		user.setAge(18);
		user.setName("aaaaaaa");
		context.publishEvent(user.toString());
	}
}

//定义事件监听器 要加入到spring中
@Component
public class MyEventListen implements ApplicationListener {
	@Override
	public void onApplicationEvent(ApplicationEvent applicationEvent) {
		PayloadApplicationEvent event = (PayloadApplicationEvent) applicationEvent;
		System.out.println("事件打印:"+event.getPayload());
	}
}

上述的定义事件监听器 也可以通过注解来实现

@Service
public class UserServiceImpl {
	@EventListener
	public void enentTest(ApplicationEvent event){
		PayloadApplicationEvent user = (PayloadApplicationEvent)event;
		System.out.println("UserServiceImpl---EventListener:"+user.getPayload());
	}
}

如果发布事件具有泛型
定义一个事件类型作为泛型

//定义一个事件类型作为泛型
public class User extends ApplicationEvent implements Serializable {
	private String name;

	private int age;

	public User() {
		super(null);
	}

	public User(Object source) {
		super(source);
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getAge() {
		return age;
	}

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

	@Override
	public String toString() {
		return "User{" +
				"name='" + name + '\'' +
				", age=" + age +
				'}';
	}
}

定义事件监听

@Component
public class MyEventListen implements ApplicationListener<User> {
	@Override
	public void onApplicationEvent(User user) {
		System.out.println("事件打印:"+user);
	}
}

定义service进行事件发布

@Service
public class GoodsServiceImpl{
	@Autowired
	private ApplicationContext context;
	@PostConstruct
	public void goodsTest() {
		System.out.println("GoodsServiceImpl----@PostConstruct---初始化前执行");
		User user = new User(this);
		user.setAge(18);
		user.setName("aaaaaaa");
		context.publishEvent(user);
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值