程序入口:#
接着上一篇博客中看完了在AnnotationConfigApplicationContext
的构造函数中的register(annotatedClasses);
将我们传递进来的主配置类添加进了BeanFactory
, 本片博客继续跟进refresh();
看看Spring如何继续初始化Spring的环境
public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) { this(); register(annotatedClasses) refresh(); }
跟进refresh()
, 源码如下: 主要做了如下几件工作
- 刷新的预准备
- 比如: 设置时间的锚点,加载上下文环境变量
- 获取BeanFactory
- 执行所有的
BeanFactoryPostProcessor
- 执行所有的
BeanPostProcessor
- ...
public void refresh() throws BeansException, IllegalStateException { synchronized (this.startupShutdownMonitor) { // Prepare this context for refreshing. //准备刷新 prepareRefresh(); //获取BeanFactory ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); // 准备BeanFactory prepareBeanFactory(beanFactory); try { // 方法中没有任何实现的逻辑 postProcessBeanFactory(beanFactory); // invoke BeanFactoryPostprocessor, 执行bean工厂的后置处理器 //如果我们没有手动往Spring中注入bean工厂的后置处理器,那么此时仅有一个,也是beanFactoryMap中的第一个RootBeanDefinition-> ConfigurationClassPostProcessor invokeBeanFactoryPostProcessors(beanFactory); // 注册 bean的后置处理器, 这些处理器可以在bean的构造方法执行之后再执行init()方法前后执行指定的逻辑 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. finishBeanFactoryInitialization(beanFactory); // Last step: publish corresponding event. finishRefresh(); } } }
刷新的准备工作#
这个方法没啥可看的重要逻辑,记录了下开始的时间,然后为Spring的上下文加载可用的环境变量
protected void prepareRefresh() { this.startupDate = System.currentTimeMillis(); this.closed.set(false); this.active.set(true); if (logger.isInfoEnabled()) { logger.info("Refreshing " + this); } // 这个是protected类型的方法,目前还没有任何实现 initPropertySources(); // 校验所有需要的properties是否都被解析过了 // getEnvironment() 得到系统环境, 后续的@Profile使用 getEnvironment().validateRequiredProperties(); this.earlyApplicationEvents = new LinkedHashSet<>(); }
获取BeanFactory
#
获取出BeanFactory
,接下来的工作重点是去扫描出程序员提供的类,然后将它们放进BeanFactoryMap
中,在此过程中穿插执行BeanFactoryPostProcessor
和BeanPostPorcessor
, 不难看出后续工作的进展都离不开这个BeanFactoryMap
,这个map在哪里呢? 就在我们的beanFactory
中,因此在刷新的最开始,获取出bean工厂
当前类是AbstractApplicationContext
,上图是它的继承类图,通过上图可以看到,它是入口AnnotationConfigApplicationContext
和
GenericApplicationContext
的父类,而Spring的BeanFactory
是在GenericApplicationContext
中实例化的,故, 获取beanFactory
的逻辑肯定在当前方法中被设计成抽象的方法,而由自己具体实现,源码如下:
@Override public abstract ConfigurableListableBeanFactory getBeanFactory() throws IllegalStateException;
准备beanFactory
#
上面的逻辑是获取出BeanFactory
, 那什么是准备BeanFactory
呢? 看它的注解解释是: 为BeanFactory
配置上它应该具有的所有特征, 那BeanFactory应该有什么特征呢? 类加载器 , bean表达式的解析器 , property与对象的转换器 , bean的后置处理器 , 添加禁止用户注入的bean的信息 , 注入bean的替换 , 添加默认的和环境相关的bean
源码如下:它的解析我们写在下面
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) { // 添加类加载器 beanFactory.setBeanClassLoader(getClassLoader()); // 设置bean标签的解析器, 一般我们使用spel标签比较多,但是Spring也有自己的Bean标签 beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader())); // </property ref="XXX"> 解析转换xxx 替换成对象 beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment())); // 添加bean的后置处理器,很显然这里添加的是Spring自己的后置处理器 beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this)); // 当用户企图注入下面类型的对象时, 会被Spring忽略 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.class , 那Spring会将她替换成beanFactory beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory); beanFactory.registerResolvableDependency(ResourceLoader.class, this); beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this); beanFactory.registerResolvableDependency(ApplicationContext.class, this); // Register early post-processor for detecting inner beans as ApplicationListeners. beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this)); // Detect a LoadTimeWeaver and prepare for weaving, if found. if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) { beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory)); // Set a temporary ClassLoader for type matching. beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader())); } // 意思是如果自定义的Bean中没有名为"systemProperties"和"systemEnvironment"的Bean, // 则注册两个Bena,Key为"systemProperties"和"systemEnvironment",Value为Map, // 这两个Bean就是一些系统配置和系统环境信息 // 注册默认的和环境相关的 bean Sping会检测,我们自己注册进来的Bean中有没有下面的名字叫下面三个串的对象, 没有的话就帮我们注入进来 if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) { // environment_bean_name beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment()); } if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {// system_properties_bean_name beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties()); } if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {// system_environment_bean_name beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment()); } }
如上代码的作用就是为BeanFactory
初始化了Spring规定的几个必须的配置属性,其中比较值得注意的地方就是它添加的BeanPostProcessor
, 虽然这是Spring原生的bean的后置处理器,但是也是第一次出现,很有意义,配置expressContext等工作, 这个后置处理器会在Bean的构造的构造过程中,动态的拦截插手
此外,添加了忽略注入的对象,当程序员向注入Spring启动时,依赖的原生对象时,会被忽略注入,企图注入BeanFactory,资源解析器,事件发布器,应用上下文时,被Spring使用原生的对象替换掉