spring源码阅读 - 容器

16 篇文章 0 订阅
13 篇文章 0 订阅

1.容器和上下文:

1.bean工厂的创建:

       DefaultListalbleBeanFactory是一个典型的bean工厂实现,这个类类图如下’:

一个bean工厂应该具备的能力:

        1.基础能力,枚举bean,分层,自动装配,独立配置

        2.注册单例bean包括beanFactory的能力

        3.注册别名的能力

spring中创建的bean默认就是单例bean。

其优势实际上就是单例自身的各种优势:

  1. 减少系统新创建实例消耗的资源
  2. 减少jvm垃圾回收
  3. 可以从缓存中快速获取到bean

单例bean也存在缺点,主要表现在在并发环境下的线程不安全。

2.扩展点

spring 提供了很多的扩展点,主要用途在spring启动的过程中任意环节进行干预,实现自己的罗技,大概流程如下:

        创建application -> 创建beanFactory-> 注册beanDefination-> 合并beanDefination->创建bean实例->填充 属性->初始化bean

        spring给我们提供的常用的扩展点称为POSTProcessor,也叫后置器。而我们最常使用的BeanFactoryPostProcessor和BeanPostProcessor。

3.ApplicationContext

一个ApplicationContext继承了五个接口,共同为一个上下文赋能,这些接口我们都已经接触过了:

  1. EnvironmentCapable:提供一个上下文环境的能力
  2. ListableBeanFactory:枚举bean工厂的bean的能力
  3. HierarchicalBeanFactory:分层的能力
  4. MessageSource:国际化的能力
  5. ApplicationEventPublisher:发布事件的能力

我们可体会一下registerShutdownHook的用法,钩子函数就是在生命周期内会自动调用的一种函数,我们自己写一个容器类继承GenericApplicationContext:

public class MyGenericApplicationContext extends GenericApplicationContext {

    private Thread shutdownHook = null;

    @Override
    public void registerShutdownHook() {
        if (this.shutdownHook == null) {
            // No shutdown hook registered yet.
            this.shutdownHook = new Thread(SHUTDOWN_HOOK_THREAD_NAME) {
                @Override
                public void run() {
                    System.out.println("容器关闭了,该干啥干啥吧!");
                }
            };
            Runtime.getRuntime().addShutdownHook(this.shutdownHook);
        }
    }
}

我们编写如下测试类,然后分析一下,我们注册的线程会在何时调用:

public class TestBeanFactory {

    @Test
    public void testXmlConfig() throws InterruptedException {
        MyGenericApplicationContext myGenericApplicationContext = new MyGenericApplicationContext();
        myGenericApplicationContext.registerShutdownHook();
        System.out.println("before");
        Thread.sleep(2000);
        System.out.println("after");
    }
}

结果:
before
after
容器关闭了,该干啥干啥吧!

所以整个apploicaitonContext的加载过程就如下所示: 先加载beandefination,然后刷新。

TODO加载beandifination的过程如下: 可以通过 xml文件的方式,带注解的bean,配置文件,类路径扫描等方式加载)

大体过程如下

public GenericXmlApplicationContext(Resource... resources) {
    // 1、加载资源
    load(resources);
    // 2、刷新容器
    refresh();
}

当然实现类内容和过程基本一致,如下

public AnnotationConfigApplicationContext(String... basePackages) {
    this();
    scan(basePackages);
    refresh();
}

4.刷新容器

        任何构建applicationContext的过程都是两步走: 获取元数据->刷新容器

        刷新容器的目的就是实例化我们的容器和容器内的bean,刷新容器是核心内容,要求在刷新前获取了全部=元数据,beanDefination也都已经准备好,保存在DefaultListableBeanFactory的map中

private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256);

刷新容器的核心能力保留在AbstractApplicationContext类中,子类也可以去扩展,如spring mvc 、springboot等:

我们可以看一下在ServletWebServerApplicationContext中的扩展如下:核心还是父类的刷新能力,仅仅在容器启动失败后,将web服务关闭:

@Override
public final void refresh() throws BeansException, IllegalStateException {
    try {
        super.refresh();
    }
    catch (RuntimeException ex) {
        WebServer webServer = this.webServer;
        if (webServer != null) {
            webServer.stop();
        }
        throw ex;
    }
}

refresh方法全貌:

@Override
public void refresh() throws BeansException, IllegalStateException {
    synchronized (this.startupShutdownMonitor) {
        //使用步骤检测应用程序标记启动。 
        StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");

        // 为刷新做准备,为当前的上下文记录状态,赋值等。
        prepareRefresh();

        // 保证获得一个新的工厂
        ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

        // 为bean工厂的启动做准备
        prepareBeanFactory(beanFactory);

        try {
            // 空方法,留给子类扩展,去修改工厂配置或新增bean定义都可
            // 和BeanFactoryPostProcessor类似
            postProcessBeanFactory(beanFactory);
            StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");
            // 调用上下文中注册为BeanFactoryPostProcessors的bean
            invokeBeanFactoryPostProcessors(beanFactory);
            // 注册bean的的后置处理器用于拦截bean的创建。(扩展点)
            registerBeanPostProcessors(beanFactory);
            beanPostProcess.end();
            // 初始化MessageSource,用于国际化i18n
            initMessageSource();
            // 初始化EventMulticaster,用于广播事件
            initApplicationEventMulticaster();
            // 给子类预留的方法,子类可以独立实现,出事化一些特定的bean
            onRefresh();
            // 检测所有的listeners bean并注册
            registerListeners();
            // 完成bean工厂的实例化,初始化所有的非懒加载的单例bean
            finishBeanFactoryInitialization(beanFactory);
            // 完成刷新,并发布相应的事件
            finishRefresh();
        } catch (BeansException ex) {
            // 销毁已经创建的单例以避免浪费资源。
            destroyBeans();
            // 重置'active'标志。
            cancelRefresh(ex);
            throw ex;
        } finally {
            // 重置Spring核心中的缓存,消除启动中所用的缓存资源, 
            // 因为我们已经不需要哪些单例bean的元数据了.
            resetCommonCaches();
            contextRefresh.end();
        }
    }
}

流程:

  1. prepareRefresh(为刷新做准备,记录当前的上下文状态,赋值等操作)
  2. 获得一个新的工厂方法,为bean工厂的启动做准备
  3. 添加扩展点 postProcessBeanFactory
  4. 调用上下文注册为beanFactoryPostProcess的bean
  5. 注册bean 的后置处理器用于拦截bean的创建
  6. 初试化messageSource初始化EventMulticaster,用于国际化和广播
  7. onRefresh 给子类预留的方法,子类可以单独实现
  8. 检测所有的listener bean 并注册
  9. 完成bean工厂的实例化,初始化所有非懒加载的单例bean
  10. 完成刷新,并发布相应的事件。

StartupStep是spring提供的步骤检测应用程序,核心容器及其基础结构组件可以使用ApplicationStartup在应用程序启动期间标记步骤,并收集关于执行上下文或其处理时间的数据,我们可以使用一个子类测试一下:

@Test
public void testApplicationStartup()  {
    BufferingApplicationStartup startup = new BufferingApplicationStartup(32);
    StartupStep startupStep = startup.start("程序即将启动!");
    startupStep.tag("第一步", "xxxx");
    startupStep.tag("第二步", "xxxx");
    startupStep.end();

    StartupStep startupStep2 = startup.start("程序即将启动2!");
    startupStep2.tag("第一步2", "xxxx");
    startupStep2.tag("第二步2", "xxxx");
    startupStep2.end();
}

通过debug我们发现,该组件将每一个步骤都在内存中保存了起来。当然,我们可以定制开发,将记录的步骤保存在任何地方

一,准备刷新阶段:

prepareRefresh(阶段)阶段

protected void prepareRefresh() {
    // 记录了启动时间和容器当前状态(非关闭、活跃中)
    this.startupDate = System.currentTimeMillis();
    this.closed.set(false);
    this.active.set(true);

    // 初始化我们定义的PropertySource
    //如果没有环境就创建一个环境,有就获得当前环境
    initPropertySources();

    // 验证所有标记为[必需]的属性都是[可解析]的
    // 简单如:通过this.getProperty(key) == null判断存在的key是否有可用的value
    getEnvironment().validateRequiredProperties();

    // 初始化一些前置刷新的监听器,默认没有,子类可以实现
    // 刷新容器【可以是从未启动到启动】,【也可以在启动中刷新】,当然像有的实现类只允许刷新一次
    // 这本质上是将监听器初始化
    if (this.earlyApplicationListeners == null) {
        this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);
    }
    else {
        // 将本地应用程序监听器器重置为刷新前状态。
        // 清空原有的,新增早期的必须的监听器
        this.applicationListeners.clear();
        this.applicationListeners.addAll(this.earlyApplicationListeners);
    }

    // 允许早期ApplicationEvents的集合,一旦多播机可用就会发布…
    this.earlyApplicationEvents = new LinkedHashSet<>();
}

1. initPropertySources

initPropertySources方法在抽象类中的默认实现为空,在GenericWebApplicationContext中,他将servlet上下文和spring上下文相关联,代码如下

@Override
protected void initPropertySources() {
   // 获取环境对象,子类中可以有不同实现,web环境下就是ApplicationServletEnvironment
   ConfigurableEnvironment env = getEnvironment();
    // 此处判断是否是web环境
   if (env instanceof ConfigurableWebEnvironment configurableWebEnv) {
       // 开始初始化环境对象
       configurableWebEnv.initPropertySources(this.servletContext, null);
   }
}

@Override
public ConfigurableEnvironment getEnvironment() {
    // 环境对象没有就直接创建一个,就是一个key->value集合
    if (this.environment == null) {
        this.environment = createEnvironment();
    }
    return this.environment;
}

public void initPropertySources(@Nullable ServletContext servletContext, @Nullable ServletConfig servletConfig) {
    WebApplicationContextUtils.initServletPropertySources(getPropertySources(), servletContext, servletConfig);
}

public static void initServletPropertySources(MutablePropertySources sources,@Nullable ServletContext servletContext, @Nullable ServletConfig servletConfig) {
    Assert.notNull(sources, "'propertySources' must not be null");
    // 将ServletConfig和ServletContext保存在当前环境中
    // 这样就可servlet容器建立了连接
    // servletContextInitParams
    String name = StandardServletEnvironment.SERVLET_CONTEXT_PROPERTY_SOURCE_NAME;
    if (servletContext != null && sources.get(name) instanceof StubPropertySource) {
        sources.replace(name, new ServletContextPropertySource(name, servletContext));
    }
    // servletConfigInitParams
    name = StandardServletEnvironment.SERVLET_CONFIG_PROPERTY_SOURCE_NAME;
    if (servletConfig != null && sources.get(name) instanceof StubPropertySource) {
        sources.replace(name, new ServletConfigPropertySource(name, servletConfig));
    }
}
@Override
protected void initPropertySources() {
   // 获取环境对象,子类中可以有不同实现,web环境下就是ApplicationServletEnvironment
   ConfigurableEnvironment env = getEnvironment();
    // 此处判断是否是web环境
   if (env instanceof ConfigurableWebEnvironment configurableWebEnv) {
       // 开始初始化环境对象
       configurableWebEnv.initPropertySources(this.servletContext, null);
   }
}

@Override
public ConfigurableEnvironment getEnvironment() {
    // 环境对象没有就直接创建一个,就是一个key->value集合
    if (this.environment == null) {
        this.environment = createEnvironment();
    }
    return this.environment;
}

public void initPropertySources(@Nullable ServletContext servletContext, @Nullable ServletConfig servletConfig) {
    WebApplicationContextUtils.initServletPropertySources(getPropertySources(), servletContext, servletConfig);
}

public static void initServletPropertySources(MutablePropertySources sources,@Nullable ServletContext servletContext, @Nullable ServletConfig servletConfig) {
    Assert.notNull(sources, "'propertySources' must not be null");
    // 将ServletConfig和ServletContext保存在当前环境中
    // 这样就可servlet容器建立了连接
    // servletContextInitParams
    String name = StandardServletEnvironment.SERVLET_CONTEXT_PROPERTY_SOURCE_NAME;
    if (servletContext != null && sources.get(name) instanceof StubPropertySource) {
        sources.replace(name, new ServletContextPropertySource(name, servletContext));
    }
    // servletConfigInitParams
    name = StandardServletEnvironment.SERVLET_CONFIG_PROPERTY_SOURCE_NAME;
    if (servletConfig != null && sources.get(name) instanceof StubPropertySource) {
        sources.replace(name, new ServletConfigPropertySource(name, servletConfig));
    }
}
  • servletContextInitParams:ServletConfigPropertySource实例,保存servletContext实例。
  • servletConfigInitParams:ServletConfigPropertySource实例,保存servletConfig实例。

这个方法是幂等的,它可以被调用很多次,但是它只会将最新传入的实例做替换,这两个实例存在于servlet环境中,这样实现可以将spring上下文和servlet上下文相关联,在spring中我们可以很容易获得这两个servlet实例,多个环境各司其职,职责分明,这是很好的体现:

2、环境校验

在默认情况下的校验规则之分简单,如下,仅仅查看有没有一些空值:

@Override
public void validateRequiredProperties() {
    MissingRequiredPropertiesException ex = new MissingRequiredPropertiesException();
    for (String key : this.requiredProperties) {
        if (this.getProperty(key) == null) {
            ex.addMissingRequiredProperty(key);
        }
    }
    if (!ex.getMissingRequiredProperties().isEmpty()) {
        throw ex;
    }
}

 2.生成一个新的工厂

obtainFreshBeanFactory()阶段

这个阶段会产生一个全新的无污染的beanFactory:

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

其内部的核心方法如下,我们以GenericApplicationContext的实现为主:

protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
    // 刷新bean工厂,并将bean工厂返回
    refreshBeanFactory();
    return getBeanFactory();
}

三、为bean工厂启动做准备

此时,我们的工厂已经创建好了,但是目前依旧是一个新鲜的工厂,我们需要对其进行一些配置,为以后的工作做准备:

protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
 
    //ConfigurableBeanFactory接口的配置项	
    beanFactory.setBeanClassLoader(getClassLoader());
    // BeanExpressionResolver接口的标准实现,使用Spring的表达式模块解析和计算Spring EL。 
    //包含其中的BeanFactory中的所有bean都可用为具有通用bean名称的预定义变量,
    //包括标准上下文bean,如“environment”、“systemProperties”和“systemEnvironment”。
    beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
    beanFactory.
        addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));

    // ConfigurableListableBeanFactory接口的配置项
    // 忽略自动装配的给定依赖接口。
    // 应用程序上下文通常使用它来注册以其他方式解析的依赖项,比如通过ApplicationContextAware解析ApplicationContext。
   // 缺省情况下,只有BeanFactoryAware接口被忽略。若要忽略其他类型,请为每种类型调用此方法
    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.ignoreDependencyInterface(ApplicationStartupAware.class);
    // 增加一个bean的后置处理器处理一些aware接口,就是上边哪些
    // 也就意味着,以上那些bean是在实例化后被注入进去,而不是属性填充时
    beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));

    // 将以下内容注册为可以解析的依赖,可以使用@Autowire注入
    // this也就是当前的上下文,它具有很多能力,我们注入这些接口时获得的实例就是上下文本身
    // @Autowire
    // BeanFactory beanFactory;
    beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
    beanFactory.registerResolvableDependency(ResourceLoader.class, this);
    beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
    beanFactory.registerResolvableDependency(ApplicationContext.class, this);

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

    // 检测一个LoadTimeWeaver是否存在,并准备织入
    if (!NativeDetector.inNative./img() && 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)) {
        // environment
        beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
    }
    if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
        // systemProperties
        beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
    }
    if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
        // systemEnvironment
        beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
    }
    if (!beanFactory.containsLocalBean(APPLICATION_STARTUP_BEAN_NAME)) {
        // applicationStartup
        beanFactory.registerSingleton(APPLICATION_STARTUP_BEAN_NAME, getApplicationStartup());
    }
}

1、ApplicationContextAwareProcessor

该类是一个bean的后置处理器,目的是在bean创建完成以后,主动调用一些aware接口。对实现了EnvironmentAware、EmbeddedValueResolverAware、ResourceLoaderAware、ApplicationEventPublisherAware、MessageSourceAware和ApplicationContextAware接口的bean提供ApplicationContext、Environment或StringValueResolver等bean的注入。

2.ApplicationListenerDetector

class ApplicationListenerDetector implements DestructionAwareBeanPostProcessor, MergedBeanDefinitionPostProcessor {

	private static final Log logger = LogFactory.getLog(ApplicationListenerDetector.class);

	private final transient AbstractApplicationContext applicationContext;

	private final transient Map<String, Boolean> singletonNames = new ConcurrentHashMap<>(256);

	public ApplicationListenerDetector(AbstractApplicationContext applicationContext) {
		this.applicationContext = applicationContext;
	}

    // beanDefintion合并以后的回调,将实现了listener接口的bean名称全部保存
	@Override
	public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
		if (ApplicationListener.class.isAssignableFrom(beanType)) {
			this.singletonNames.put(beanName, beanDefinition.isSingleton());
		}
	}

    // 初始化前的回调,不做任何的事情
	@Override
	public Object postProcessBeforeInitialization(Object bean, String beanName) {
		return bean;
	}

    // 初始化后的回调
	@Override
	public Object postProcessAfterInitialization(Object bean, String beanName) {
        // 这里告诉我们,监听器的注册
		if (bean instanceof ApplicationListener<?> applicationListener) {
		    // 配合postProcessMergedBeanDefinition来共同探测listener
             // todo://源码注解说getNamesByType的探测可能不够准确
			Boolean flag = this.singletonNames.get(beanName);
			if (Boolean.TRUE.equals(flag)) {
				// 单例bean(顶层或内部):动态注册
				this.applicationContext.addApplicationListener(applicationListener);
			}
			else if (Boolean.FALSE.equals(flag)) {
				if (logger.isWarnEnabled() && !this.applicationContext.containsBean(beanName)) {
					// 实现了ApplicationListener接口,但是由于它没有单例作用域,所以不能通过它所包含的
                      //ApplicationContext来进行事件多播。只有顶级侦听器bean允许是非单例范围。
					logger.warn("Inner bean '" + beanName + "' implements ApplicationListener interface but is not reachable for event multicasting by its containing ApplicationContext because it does not have singleton scope. Only top-level listener beans are allowed to be of non-singleton scope.");
				}
				this.singletonNames.remove(beanName);
			}
		}
		return bean;
	}

    // 销毁前的回调,将注册的监听去全部移除
	@Override
	public void postProcessBeforeDestruction(Object bean, String beanName) {
		if (bean instanceof ApplicationListener<?> applicationListener) {
			try {
				ApplicationEventMulticaster multicaster = this.applicationContext.getApplicationEventMulticaster();
				multicaster.removeApplicationListener(applicationListener);
				multicaster.removeApplicationListenerBean(beanName);
			}
			catch (IllegalStateException ex) {
				// ApplicationEventMulticaster not initialized yet - no need to remove a listener
			}
		}
	}

}

3、registerResolvableDependency该方法是将一个bean注册为可以被解析的容器的bean。

四、对bean工厂的后置处理

postProcessBeanFactory(beanFactory)阶段

抽象父类方法中同样是一个空的方法,是留给其他子类扩展的地方

看一下在GenericWebApplicationContext中的实现,这就是典型的子类扩展:

protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
    // 如果是web环境,新增一个后置处理器,并忽略一个接口
    if (this.servletContext != null) {
        beanFactory.addBeanPostProcessor(new ServletContextAwareProcessor(this.servletContext));
        beanFactory.ignoreDependencyInterface(ServletContextAware.class);
    }

    // 同时注册新的作用域,我们看到的request,session等作用域都在这里注册
    WebApplicationContextUtils.registerWebApplicationScopes(beanFactory, this.servletContext);
    // 此处注入servlet的上下文环境
    WebApplicationContextUtils.registerEnvironmentBeans(beanFactory, this.servletContext);
}

再看下注册作域的实现如下:

public static void registerWebApplicationScopes(ConfigurableListableBeanFactory beanFactory,@Nullable ServletContext sc) {
    // 注册request,session,application作用域
    beanFactory.registerScope(WebApplicationContext.SCOPE_REQUEST, new RequestScope());
    beanFactory.registerScope(WebApplicationContext.SCOPE_SESSION, new SessionScope());
    if (sc != null) {
        ServletContextScope appScope = new ServletContextScope(sc);
        beanFactory.registerScope(WebApplicationContext.SCOPE_APPLICATION, appScope);
        sc.setAttribute(ServletContextScope.class.getName(), appScope);
    }

    // 注册可以被解析的依赖项的依赖关系
    // @Autowire
    // ServletRequest servletRequest;
    beanFactory.registerResolvableDependency(ServletRequest.class, new RequestObjectFactory());
    beanFactory.registerResolvableDependency(ServletResponse.class, new ResponseObjectFactory());
    beanFactory.registerResolvableDependency(HttpSession.class, new SessionObjectFactory());
    beanFactory.registerResolvableDependency(WebRequest.class, new WebRequestObjectFactory());
    if (jsfPresent) {
        FacesDependencyRegistrar.registerFacesDependencies(beanFactory);
    }
}

五、调用beanfactory的后置处理器

invokeBeanFactoryPostProcessors(beanFactory)阶段

这是留给应用程序的扩展点,我们自行编写或第三方扩展的beanFactoryPostProcessor会在这里被调用:

protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
    // 参数一:当前的bean工厂
    // 参数二:已经注册的BeanFactoryPostProcessors,可能是子类注册的或者之前的扩展点注册
    // 该方法是核心的调用点,会从beanDefinition中寻找所有的BeanFactoryPostProcessor调用
    PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());

    // 检测LoadTimeWeaver并准备编织,这个实现需要使用spring探针,是加载时织入实现代理
    // 因为此时,bean工厂已经准备就绪,接着就是加载并实例化bean了
    // aspectj生成代理的织入时机有三个,编译时、加载时、运行时,自己可以找博客看
    // 该处的内容我们暂时不看
    if (!NativeDetector.inNative./img() && beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
        beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
        beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
    }
}

其中getBeanFactoryPostProcessors方法十分简单如下:

成员变量beanFactoryPostProcessors在之前的准备过程中,由核心准备工作,子类扩展等形式返回准备好的后置处理器:

public List<BeanFactoryPostProcessor> getBeanFactoryPostProcessors() {
    return this.beanFactoryPostProcessors;
}

成员变量的beanFactoryPostProcessors可以通过编程的方式添加,请看如下的测试用例:

@Test
public void testAddBeanFactoryPostProcessor(){
    AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
    applicationContext.scan("com.ydlclass");
    applicationContext.addBeanFactoryPostProcessor(new MyBeanFactoryPostProcessor());
    applicationContext.refresh();
}

在该方法中主要调用的后置处理器分为两类,如下:

  1. BeanDefinitionRegistryPostProcessor,他是BeanFactoryPostProcessor的子接口,给我们一个机会可以再注册更多的beanDefinition。
  2. BeanFactoryPostProcessor,给我们一个机会对目前的bean工厂做更多额外的配置。

1、注册器后置处理

该方法中,我们会首先处理这一类后置处理器,其本是也是BeanFactoryPostProcessor,结构如下:

public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor {
	void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException;

}

在这一类处理器中,我们可以获取一个BeanDefinitionRegistry,额外获得一个注册bean的机会。

2、bean工厂的后置处理器

该接口只有一个回调函数postProcessBeanFactory,他给我传入当前已经创建好的bean工厂,给我们一个机会可以做一些额外的配置:

@FunctionalInterface
public interface BeanFactoryPostProcessor {
	void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;

}

3、处理过程

后置处理器大致分类:

  1. 编程方式直接加入的,可能是准备阶段的任意地方,包括子类扩展,此处理器可以直接调用,已经实例化完毕,这是第二个参数
addBeanFactoryPostProcessor(new MyBeanFactoryPostProcessor());

        2.我们定义的后置处理器,此时仅仅处于BeanDefinition阶段,尚未实例化,无法直接调用,这样是传递第一个参数的原因

      3.对于后置处理器spring还细化出一个新的后置处理器BeanDefinitionRegistryPostProcessor,他是BeanFactoryPostProcessor的子接口,给我们一个机会再继续注册一些beanDefinition。

        4.对于后置处理器spring都提供了优先级接口(PriorityOrdered)和可排序(Ordered)接口,为后置处理器提供了顺序执行的机制。

// AbstractApplicationContext对BeanFactoryPostProcessor的委托处理类
final class PostProcessorRegistrationDelegate {

    // 工具类,负责调佣BeanFactoryPostProcessors
	public static void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
  
        // 存放已经处理过的bean
		Set<String> processedBeans = new HashSet<>();
        
//----------------------------------------------------
// 第一类后置处理器,这一类是BeanDefinitionRegistryPostProcessor
// 他们的优先级次之,在这个后置处理器中可能还会注册其他的bean            
//---------------------------------------------------            
                   
		// 如果传入的beanFactory实现了BeanDefinitionRegistry接口
        // spring还提供了BeanDefinitionRegistryPostProcessor的扩展点
		if (beanFactory instanceof BeanDefinitionRegistry registry) {
            // 存放BeanFactoryPostProcessor
			List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
			// 存放BeanDefinitionRegistryPostProcessor
            List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
            
            
            // 这里是处理参数中传递的beanFactoryPostProcessors
            // 进行归类
            // 一类是BeanDefinitionRegistryPostProcessor
            // 一类是BeanFactoryPostProcessor
			for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
				if (postProcessor instanceof BeanDefinitionRegistryPostProcessor registryProcessor) {
                    // 直接调用了
                    // BeanDefinitionRegistryPostProcessor他有两个回调
                    // 此处调用了第一个会传入一个注册器,给我们机会注册更多bean定义
					registryProcessor.postProcessBeanDefinitionRegistry(registry);
					// 放有注册器的后置处理器
                    registryProcessors.add(registryProcessor);
				} else {
                    // 放常规的后置处理器
					regularPostProcessors.add(postProcessor);
				}
			}
       
            // 这里定义了当前注册的bean
			List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();
// PriorityOrdered(优先级要求)--------------------------------------------------
			// 首先,调用实现PriorityOrdered接口的BeanDefinitionRegistryPostProcessors。
			String[] postProcessorNames =
			beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
			for (String ppName : postProcessorNames) {
                // 匹配实现了PriorityOrdered接口的beandefinition
				if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
                    // 此处调用getbean就是实例化bean
					currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                    // 同时把他加入处理过的bean当中
					processedBeans.add(ppName);
				}
			}
            // 对这些bean进行排序
			sortPostProcessors(currentRegistryProcessors, beanFactory);
            // 这个集合专门存放BeanDefinitionRegistryPostProcessor
			registryProcessors.addAll(currentRegistryProcessors);
            // postProcessBeanDefinitionRegistry方法调用
            // 这里可能会注入一些其他的bean
			invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());
            // 调用完了清理,下个阶段复用
			currentRegistryProcessors.clear();
// Ordered(有序的)---------------------------------------------------------------
			// 接下来,调用实现Ordered的BeanDefinitionRegistryPostProcessors。
			// ...中间省略了实现order接口的实现,和PriorityOrdered一模一样
            
// 没有实现Ordered和PriorityOrdered接口的其他的beandefinitionregistrypostprocessor-----
			// ...中间省略了实现其他beandefinitionregistrypostprocessor的方法,内容大致一样
            
			// 现在,调用到目前为止处理的所有处理器的postProcessBeanFactory回调。
			invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
			invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
		}  
        else {
			// 调用与上下文注册的工厂处理器。
			invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
		}

        
//------------------------------------------------------
// 第二类:普通的后置处理器,普通的实现了BeanFactoryPostProcessor的beanDefinition
//------------------------------------------------------
		String[] postProcessorNames =
				beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
        
		// 在实现PriorityOrdered、Ordered和其他的BeanFactoryPostProcessors之间进行分离。
		List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
		List<String> orderedPostProcessorNames = new ArrayList<>();
		List<String> nonOrderedPostProcessorNames = new ArrayList<>();
		for (String ppName : postProcessorNames) {
			if (processedBeans.contains(ppName)) {
				// 跳过-已经在上面的第一阶段处理
			}
			else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
                // priorityOrderedPostProcessors优先实例化了
				priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
			}
			else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
				orderedPostProcessorNames.add(ppName);
			}
			else {
				nonOrderedPostProcessorNames.add(ppName);
			}
		}

		// 首先,调用实现PriorityOrdered的BeanFactoryPostProcessors。
		sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
		invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);

		// 接下来,调用实现Ordered的BeanFactoryPostProcessors。
		List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
        // 实例化了
		for (String postProcessorName : orderedPostProcessorNames) {
			orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
		}
		sortPostProcessors(orderedPostProcessors, beanFactory);
		invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);

		// 最后,调用所有其他beanfactorypostprocessor。
		List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
		for (String postProcessorName : nonOrderedPostProcessorNames) {
			nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
		}
		invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);

		// 清除缓存的合并bean定义,因为后处理器可能有修改原始元数据,例如替换值中的占位符…
		beanFactory.clearMetadataCache();
	}
    // ----其他方法略去
}

先后顺序是:

  1. 实现了PriorityOrdered接口的BeanDefinitionRegistryPostProcessor
  2. 实现了Ordered接口的BeanDefinitionRegistryPostProcessor
  3. 其他普通的BeanDefinitionRegistryPostProcessor
  4. 实现了PriorityOrdered接口的BeanFactoryPostProcessor
  5. 实现了Ordered接口的BeanFactoryPostProcessor
  6. 其他普通的BeanFactoryPostProcessor

6.注册bean的后置处理器

registerBeanPostProcessors(beanFactory)阶段方法如下:

protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
    PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
}

核心代码如下:

public static void registerBeanPostProcessors(
    ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {

    // 获取所有实现了BeanPostProcessor接口的bean的名字
    String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);


    // 记录BeanPostProcessor数量
    // getBeanPostProcessorCount()编程的方式add进去的
    // 1 BeanPostProcessorChecker
    // postProcessorNames.length容器内没有初始化的
    int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
    // 注册BeanPostProcessorChecker,
    beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));


    // 有优先级要求的,实现了priorityOrdered接口
    List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
    // 内部的BeanPostProcessor
    List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
    // 有顺序要求的,实现了Ordered接口
    List<String> orderedPostProcessorNames = new ArrayList<>();
    // 没有顺序要求的
    List<String> nonOrderedPostProcessorNames = new ArrayList<>();

    // 循环分组
    for (String ppName : postProcessorNames) {
        if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
            BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
            priorityOrderedPostProcessors.add(pp);
            // MergedBeanDefinitionPostProcessor也是一个后置处理器
            // 我们稍后看
            if (pp instanceof MergedBeanDefinitionPostProcessor) {
                internalPostProcessors.add(pp);
            }
        }
        else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
            orderedPostProcessorNames.add(ppName);
        }
        else {
            nonOrderedPostProcessorNames.add(ppName);
        }
    }

    // 首先,注册实现PriorityOrdered的BeanPostProcessors。
    sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
    registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);

    // 接下来,实例化并注册实现Ordered接口的BeanPostProcessors。
    List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
    for (String ppName : orderedPostProcessorNames) {
        BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
        orderedPostProcessors.add(pp);
        // 这里也要筛选
        if (pp instanceof MergedBeanDefinitionPostProcessor) {
            internalPostProcessors.add(pp);
        }
    }
    sortPostProcessors(orderedPostProcessors, beanFactory);
    registerBeanPostProcessors(beanFactory, orderedPostProcessors);

    // 现在,实例化并注册其他的BeanPostProcessors。
    List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
    for (String ppName : nonOrderedPostProcessorNames) {
        BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
        nonOrderedPostProcessors.add(pp);
        // 这里也要筛选
        if (pp instanceof MergedBeanDefinitionPostProcessor) {
            internalPostProcessors.add(pp);
        }
    }
    registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);

    // 最后,注册所有的MergedBeanDefinitionPostProcessor
    sortPostProcessors(internalPostProcessors, beanFactory);
    registerBeanPostProcessors(beanFactory, internalPostProcessors);

    // ApplicationListener探测器
    beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}

主要就是如下四个list

// 有优先级要求的,实现了priorityOrdered接口
    List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
    // 内部的BeanPostProcessor
    List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
    // 有顺序要求的,实现了Ordered接口
    List<String> orderedPostProcessorNames = new ArrayList<>();
    // 没有顺序要求的
    List<String> nonOrderedPostProcessorNames = new ArrayList<>();

priorityOrderedPostProcessors ,orderedPostProcessors,nonOrderedPostProces 内部可能包含内部的BeanPostProcessor(查看是不是MergedBeanDefinitionPostProcessor)所以要筛选并放入 internalPostProcessors列表中。

1.合并beanDefinition

MergedBeanDefinition是spring获取bean流程中一个重要的处理过程,他将基础的bean处理成新的BeanDifinition对象,也就是RootBeanDefinition,后续的处理过程都依赖于这个对象。

在spring内部实际使用的BeanDefinition其实都是合并之后的RootBeanDefinition对象,通过他进行对象的实例化,注入等操作。spring同样为这个关键接待您提供了一个可供后续操作并后RootBeanDefinition的扩展点(后置处理器),通过这个扩展点,可以实现对RootBeanDefinition的操作。

和前面的beanDefinitionRegistryPostProcessor对比

扩展点用途
BeanDefinitionRegistryPostProcessor可以注册或者更改原始的BeanDefinition
MergedBeanDefinitionPostProcessor可以修改RootDefinition

具体整合过程,从传入的beanFactory中获取全部的实现了BeanPostProcess接口的bean的名字。然后不断循环分组,分成实现了priorityOrdered的,实现了Orderd接口的,包括内部的BeanPostProcessor以及没有顺序要求的。。。等等。注意internalPostProcessors 里面放入的是符合MergedBeanDefinitionPostProcessor的后置处理器。在循环分组结束之后,注册实现PriorityOrdered的BeanPostProcessor,然后是实现Ordered接口的BeanPostProcessors,再次是实例化并注册其他的BeanPostProcessors(nonOrderedPostProcessors)。最后注册所有的MergedBeanDefinitionPostProcessor

注册语句:

  sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
  registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);

2、监听器探测器

检测实现了ApplicationListener接口的bean的BeanPostProcessor。这将捕获getBeanNamesForType和仅针对顶级bean的相关操作不能可靠地检测到的bean。

class ApplicationListenerDetector implements DestructionAwareBeanPostProcessor, MergedBeanDefinitionPostProcessor {

    private static final Log logger = LogFactory.getLog(ApplicationListenerDetector.class);

    private final transient AbstractApplicationContext applicationContext;

    private final transient Map<String, Boolean> singletonNames = new ConcurrentHashMap<>(256);

    public ApplicationListenerDetector(AbstractApplicationContext applicationContext) {
        this.applicationContext = applicationContext;
    }

    // 合并bean的定义前
    @Override
    public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
        if (ApplicationListener.class.isAssignableFrom(beanType)) {
            this.singletonNames.put(beanName, beanDefinition.isSingleton());
        }
    }

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) {
        return bean;
    }

    // BeanPostProcessor的回调
    // 这里说明spring中的listener必须是单例的才能生效
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) {
        if (bean instanceof ApplicationListener<?> applicationListener) {
            // 判断是不是单例
            Boolean flag = this.singletonNames.get(beanName);
            if (Boolean.TRUE.equals(flag)) {
                // 单例bean(顶层或内部):动态注册
                this.applicationContext.addApplicationListener(applicationListener);
            }
            else if (Boolean.FALSE.equals(flag)) {
                if (logger.isWarnEnabled() && !this.applicationContext.containsBean(beanName)) {
                    // inner bean with other scope - can't reliably process events
                    logger.warn("Inner bean '" + beanName + "' implements ApplicationListener interface but is not reachable for event multicasting by its containing ApplicationContext because it does not have singleton scope. Only top-level listener beans are allowed to be of non-singleton scope.");
                }
                this.singletonNames.remove(beanName);
            }
        }
        return bean;
    }
    
    // 一个bean在销毁前的回调,从多播器中移除
    @Override
    public void postProcessBeforeDestruction(Object bean, String beanName) {
        if (bean instanceof ApplicationListener<?> applicationListener) {
            try {
                ApplicationEventMulticaster multicaster = this.applicationContext.getApplicationEventMulticaster();
                multicaster.removeApplicationListener(applicationListener);
                multicaster.removeApplicationListenerBean(beanName);
            }
            catch (IllegalStateException ex) {
                // ApplicationEventMulticaster not initialized yet - no need to remove a listener
            }
        }
    }

}

七、初始化MessageSource

initMessageSource()阶段

容器启动时,如果容器中不存在对应的Bean实例,则容器中默认创建一个DelegatingMessageSource的实例来实现国际化。DelegatingMessageSource实现的具体功能需要向上委托,否则降级处理(处理成默认字符串或者抛出异常):

public String getMessage(String code, @Nullable Object[] args, @Nullable String defaultMessage, Locale locale) {
    if (this.parentMessageSource != null) {
        return this.parentMessageSource.getMessage(code, args, defaultMessage, locale);
    }
    else if (defaultMessage != null) {
        return renderDefaultMessage(defaultMessage, args, locale);
    }
    else {
        return null;
    }
}

SpringBoot中使用【ResourceBundleMessageSource】 的实现,SpringBoot默认的自动装配的 MessageSource即就是 ResourceBundleMessageSource:

配置文件:

spring:
  messages:
    basename: i18n/messages
    encoding: UTF-8

在springboot或spring中,只需要注入这个bean直接使用即可

@Autowired
MessageSource messageSource;

八、初始化多播器

initApplicationEventMulticaster()阶段

向容器注入一个多播器实例,默认为SimpleApplicationEventMulticaster的实现:

protected void initApplicationEventMulticaster() {
    ConfigurableListableBeanFactory beanFactory = getBeanFactory();
    if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
        this.applicationEventMulticaster =
            beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
        if (logger.isTraceEnabled()) {
            logger.trace("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
        }
    }
    else {
        // 默认使用SimpleApplicationEventMulticaster进行广播事件,注册listener
        this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
        beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
        if (logger.isTraceEnabled()) {
            logger.trace("No '" + APPLICATION_EVENT_MULTICASTER_BEAN_NAME + "' bean, using " +
                         "[" + this.applicationEventMulticaster.getClass().getSimpleName() + "]");
        }
    }
}

九、onRefresh()

该方法在抽象类中也是空的,同样是留给子类进行扩展使用,此时一切的基本工作都已经准备好了:

web环境下在此阶段会创建一个服务器:

	private void createWebServer() {
		WebServer webServer = this.webServer;
		ServletContext servletContext = getServletContext();
		if (webServer == null && servletContext == null) {
			StartupStep createWebServer = getApplicationStartup().start("spring.boot.webserver.create");
			ServletWebServerFactory factory = getWebServerFactory();
			createWebServer.tag("factory", factory.getClass().toString());
			this.webServer = factory.getWebServer(getSelfInitializer());
			createWebServer.end();
			getBeanFactory().registerSingleton("webServerGracefulShutdown",
					new WebServerGracefulShutdownLifecycle(this.webServer));
			getBeanFactory().registerSingleton("webServerStartStop",
					new WebServerStartStopLifecycle(this, this.webServer));
		}
		else if (servletContext != null) {
			try {
				getSelfInitializer().onStartup(servletContext);
			}
			catch (ServletException ex) {
				throw new ApplicationContextException("Cannot initialize servlet context", ex);
			}
		}
		initPropertySources();
	}

十、注册监听器

registerListeners()阶段

protected void registerListeners() {
    // 首先注册静态指定的侦听器。比如用编程的方式加入:
    for (ApplicationListener<?> listener : getApplicationListeners()) {
        getApplicationEventMulticaster().addApplicationListener(listener);
    }

    // 获得bean的名字
    String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
    // 只需要加入名字即可,不要实例化,可以让容器去实例化,我们发布事件时会筛选和缓存
    for (String listenerBeanName : listenerBeanNames) {
        getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
    }

    // 发布早期应用程序事件,一般也没有,也是可以拓展的
    Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
    this.earlyApplicationEvents = null;
    if (!CollectionUtils.isEmpty(earlyEventsToProcess)) {
        for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
            getApplicationEventMulticaster().multicastEvent(earlyEvent);
        }
    }
}

#十一、完成bean工厂的初始化

finishBeanFactoryInitialization(beanFactory)阶段

此方法非常复杂,我们独立一个章节讲解,在这里会完成所有的单例bean的创建过程。

十二、完成刷新

protected void finishRefresh() {
    // 清除上下文级资源缓存(例如扫描ASM元数据)。
    clearResourceCaches();

    // 初始化一个生命周期处理器,并标志为running状态;
    initLifecycleProcessor();
    getLifecycleProcessor().onRefresh();

    // 发布最终事件。
    publishEvent(new ContextRefreshedEvent(this));
}

上边的内容告诉我们,我们可以订阅ContextRefreshedEvent事件,在容器启动后完成一些初始化操作。

十三、恢复现场

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

    // 销毁已经创建的单例以避免悬空资源。
    destroyBeans();

    // 重置'active'标志。
    cancelRefresh(ex);

    // 向调用者传播异常。
    throw ex;
}

finally {
    // 重置Spring核心中的公共内省缓存,因为我们可能再也不需要单例bean的元数据了……
    resetCommonCaches();
    contextRefresh.end();
}

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值