上篇文章讲了setConfigLocations方法,本篇继续往下分析refresh方法。该方法实现在其父类AbstractApplicationContext中,我们进入该方法看下具体实现:
public void refresh() throws BeansException, IllegalStateException { synchronized (this.startupShutdownMonitor) { // Prepare this context for refreshing. prepareRefresh(); // Tell the subclass to refresh the internal bean factory. ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); // Prepare the bean factory for use in this context. prepareBeanFactory(beanFactory); try { // Allows post-processing of the bean factory in context subclasses. postProcessBeanFactory(beanFactory); // Invoke factory processors registered as beans in the context. 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. finishBeanFactoryInitialization(beanFactory); // Last step: publish corresponding event. finishRefresh(); } catch (BeansException ex) { 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(); } } } 复制代码
首先会执行prepareRefresh方法,该方法为刷新上下文做准备,进入该方法:
protected void prepareRefresh() { this.startupDate = System.currentTimeMillis(); this.active.set(true); if (logger.isInfoEnabled()) { logger.info("Refreshing " + this); } // Initialize any placeholder property sources in the context environment initPropertySources(); // Validate that all properties marked as required are resolvable // see ConfigurablePropertyResolver#setRequiredProperties getEnvironment().validateRequiredProperties(); // Allow for the collection of early ApplicationEvents, // to be published once the multicaster is available... this.earlyApplicationEvents = new LinkedHashSet<ApplicationEvent>(); } 复制代码
该方法首先会设置开始刷新时间startupDate、活动标志active,然后执行initPropertySources方法初始化属性源,进入initPropertySources方法看下:
protected void initPropertySources() { // For subclasses: do nothing by default. } 复制代码
该方法是个空方法,子类可以重写该方法,达到扩展目的。
然后,会执行validateRequiredProperties方法:
public void validateRequiredProperties() throws MissingRequiredPropertiesException { this.propertyResolver.validateRequiredProperties(); } 复制代码
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; } } 复制代码
该方法会校验系统环境中设置的RequiredProperties属性是否为空,如果为空则抛出异常。比如说我们设置了属性值aaa:getEnvironment().setRequiredProperties(“aaa”),但是在系统环境中没有该属性则会抛异常。例子:
public class MyApplicationContext extends AbstractXmlApplicationContext { public MyApplicationContext () { getEnvironment().setRequiredProperties("aaa"); refresh(); } } 复制代码
@Test public void testMyApplicationContext() { ApplicationContext applicationContext = new MyApplicationContext(); } 复制代码
此时,启动就会报错:
org.springframework.core.env.MissingRequiredPropertiesException: The following properties were declared as required but could not be resolved: [aaa] 复制代码
我们在系统环境中设置该属性,就不会抛出该异常:
@Test public void testMyApplicationContext() { Properties properties = System.getProperties(); properties.setProperty("aaa", "bbb"); ApplicationContext applicationContext = new MyApplicationContext(); } 复制代码
prepareRefresh方法最后创建一个 LinkedHashSet<ApplicationEvent>
,并赋值给earlyApplicationEvents,到此prepareRefresh方法就结束了。
如果读完觉得有收获的话,欢迎点赞、关注、加公众号【Java在线】,查阅更多精彩历史!!!