侧边栏壁纸
博主头像
敢敢雷博主等级

永言配命,自求多福

  • 累计撰写 57 篇文章
  • 累计创建 0 个标签
  • 累计收到 2 条评论

目 录CONTENT

文章目录

Spring原理---refresh()方法

敢敢雷
2020-03-16 / 0 评论 / 0 点赞 / 208 阅读 / 1,328 字
温馨提示:
部分素材来自网络,若不小心影响到您的利益,请联系我删除。

最近想看下Spring Framework的源码,平时使用Spring的时候,都是直接按照规范直接使用,不知道原理和底层实现,之前也知道Spring底层源码很复杂.有句话说得好,站在巨人的肩膀上才能看的更远,这段时间将会根据前辈们的博客,自己去Spring底层摸索一番.

启动Spring

在使用Spring的时候,我们一般都会使用以下代码

ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        Student student = (Student) applicationContext.getBean("Student");
        System.out.println(student);

仅仅通过两行代码,就可以完成Spring的使用,Spring的强大与复杂可见一斑
我们都知道ApplicationContext和BeanFactory他们都可代表Spring容器,Spring容器是生成Bean实例的工厂,并且管理容器中的Bean,其中ApplicationContext是BeanFactory的子接口也称为Spring的上下文
image.png
下面就以ClassPathXmlApplicationContext(“applicationContext.xml”)为我们的学习入口,进入

public ClassPathXmlApplicationContext(String configLocation) throws BeansException {
		this(new String[] {configLocation}, true, null);
	}

是一个有参构造方法,继续进入this方法

public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent)
			throws BeansException {

		super(parent);
		setConfigLocations(configLocations);
		if (refresh) {
			refresh();
		}
	}

调用父类的构造方法,但是parent在我们的上一步设置的为null,接着set入了我们的配置文件,标题代码refresh来了
进入refresh方法

refresh方法

@Override
	public void refresh() throws BeansException, IllegalStateException {
 
		//加锁 防止 fresh还没结束  就又进入改方法 导致容器初始化错乱
		synchronized (this.startupShutdownMonitor) {
			// Prepare this context for refreshing.
			//准备工作  初始化spring状态 使spring处于运行状态
			prepareRefresh();
 
			// Tell the subclass to refresh the internal bean factory.
			//这一步主要作用是将配置文件定义解析成beanDefine 注册到beanFactory中
			//但是这里的bean并没有初始化出来 只是提取配置信息 定义相关的属性
			//将这些信息保存到beanDefineMap中(beanName->beanDefine)对应的map
			ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
 
			// Prepare the bean factory for use in this context.
			//设置BeanFactory的类加载器,添加几个BeanPostProcessor 手动注册几个特殊的bean
			prepareBeanFactory(beanFactory);
 
			try {
				// Allows post-processing of the bean factory in context subclasses.
				//重要
				postProcessBeanFactory(beanFactory);
 
                // Invoke factory processors registered as beans in the context.
				// 重要 在spring的环境中执行已经被注册的factory processors
				// 设置执行自定义的ProcessBeanFactory 和 spring内部的定义的
				invokeBeanFactoryPostProcessors(beanFactory);
 
				// Register bean processors that intercept bean creation.
				registerBeanPostProcessors(beanFactory);
 
				// Initialize message source for this context.
				initMessageSource();
 
				// Initialize event multicaster for this context.
				initApplicationEventMulticaster();
 
				// Initialize other special beans in specific context subclasses.
				onRefresh();
 
				// Check for listener beans and register them.
				registerListeners();
 
				// Instantiate all remaining (non-lazy-init) singletons.
				// 初始化所有的singleton beans 到目前为止 我们已经完成了beanFactory的创建
				// 如果没有设置懒加载 spring会为我们初始化所有的bean
				finishBeanFactoryInitialization(beanFactory);
 
				// Last step: publish corresponding event.
				finishRefresh();
                } catch (BeansException 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();
			}
		}
	}

refresh()方法是贯穿spring整个初始化的方法,一共调用了12个方法

  1. prepareRefresh();
    容器刷新前的准备,设置上下文状态,获取属性,验证必要的属性等

  2. obtainFreshBeanFactory();
    获取新的beanFactory,销毁原有beanFactory、为每个bean生成BeanDefinition等,但是这里的bean并没有初始化出来 只是提取配置信息 定义相关的属性

  3. prepareBeanFactory(beanFactory);
    配置标准的beanFactory,设置ClassLoader,设置SpEL表达式解析器,添加忽略注入的接口,添加bean,添加bean后置处理器等

  4. postProcessBeanFactory(beanFactory);
    模板方法,此时,所有的beanDefinition已经加载,但是还没有实例化。
    允许在子类中对beanFactory进行扩展处理。比如添加ware相关接口自动装配设置,添加后置处理器等,是子类扩展prepareBeanFactory(beanFactory)的方法

  5. invokeBeanFactoryPostProcessors(beanFactory);
    实例化并调用所有注册的beanFactory后置处理器(实现接口BeanFactoryPostProcessor的bean,在beanFactory标准初始化之后执行)。
    例如:
    PropertyPlaceholderConfigurer(处理占位符)

  6. registerBeanPostProcessors(beanFactory);
    实例化和注册beanFactory中扩展了BeanPostProcessor的bean。
    例如:
    AutowiredAnnotationBeanPostProcessor(处理被@Autowired注解修饰的bean并注入)
    RequiredAnnotationBeanPostProcessor(处理被@Required注解修饰的方法)
    CommonAnnotationBeanPostProcessor(处理@PreDestroy、@PostConstruct、@Resource等多个注解的作用)等。

  7. initMessageSource();
    初始化国际化工具类MessageSource

  8. initApplicationEventMulticaster();
    初始化事件广播器

  9. onRefresh();
    模板方法,在容器刷新的时候可以自定义逻辑,不同的Spring容器做不同的事情。

  10. registerListeners();
    注册监听器,广播early application events

  11. finishBeanFactoryInitialization(beanFactory);
    实例化所有剩余的(非懒加载)单例
    比如invokeBeanFactoryPostProcessors方法中根据各种注解解析出来的类,在这个时候都会被初始化。
    实例化的过程各种BeanPostProcessor开始起作用。

  12. finishRefresh();
    refresh做完之后需要做的其他事情。
    清除上下文资源缓存(如扫描中的ASM元数据)
    初始化上下文的生命周期处理器,并刷新(找出Spring容器中实现了Lifecycle接口的bean并执行start()方法)。
    发布ContextRefreshedEvent事件告知对应的ApplicationListener进行响应的操作

以上代码执行完后,就可以开始使用Spring了,以后将会主要研究里面的几个比较重要的方法

0

评论区