往后我们进入到refresh方法内部进去处理
@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
//准备此上下文以进行刷新
prepareRefresh();
// Prepare the bean factory for use in this context.
prepareBeanFactory(beanFactory);
总结: 这个类的主要工作是前戏
1. 设置容器的启动时间
2. 设置关闭状态为false
3. 设置活跃状态为false
4.获取getEnvironment()对象,并加载系统的属性值到enviorment到对象中
5.准备监听器和事件的集合对象,默认为空的对象。
准备此上下文以进行刷新、设置其启动日期和活动标志以及执行属性源的任何初始化。
protected void prepareRefresh() {
// 启动时间
this.startupDate = System.currentTimeMillis();
this.closed.set(false);
this.active.set(true);
// 打印日志 没啥说的
if (logger.isDebugEnabled()) {
if (logger.isTraceEnabled()) {
logger.trace("Refreshing " + this);
}
else {
logger.debug("Refreshing " + getDisplayName());
}
}
//在上下文环境中初始化任何占位符属性源。注:这个是空的方法,其是由子类进行实现的。
initPropertySources();
// 验证所有标记为必需的属性都是可解析的
//参见 ConfigurablePropertyResolvetRequiredProperties
//注: 此时环境参数初始好了的, 在setConfigLocations 中进行了配置 详细见上一篇https://blog.csdn.net/u012249177/article/details/120006362
getEnvironment().validateRequiredProperties();
// 存储预刷新 ApplicationListener
if (this.earlyApplicationListeners == null) {
this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);
}
else {
// Reset local application listeners to pre-refresh state.
this.applicationListeners.clear();
this.applicationListeners.addAll(this.earlyApplicationListeners);
}
// Allow for the collection of early ApplicationEvents,
// to be published once the multicaster is available...
this.earlyApplicationEvents = new LinkedHashSet<>();
}
细节点一: initPropertySources 空方法由子类实现, 添加一个参数和一些校验等
如新建类MyClassPathXmlApplicationContext 继承了ClassPathXmlApplicationContext 重写了改方法:
getEnvironment().validateRequiredProperties(): 验证所有标记为必需的属性都是可解析的
如果initPropertySources 中 写上:
@Override
protected void initPropertySources() {
System.out.println("扩展initPropertySource");
getEnvironment().setRequiredProperties("abc"); //设置了需要的参数 username, 那么在后续就会校验这个参数舒存在
}
后面处理流程:
@Override
public void validateRequiredProperties() {
MissingRequiredPropertiesException ex = new MissingRequiredPropertiesException();
for (String key : this.requiredProperties) {
if (this.getProperty(key) == null) { // 从配置参数中获取value ,如果没有key则进行报错
ex.addMissingRequiredProperty(key);
}
}
if (!ex.getMissingRequiredProperties().isEmpty()) {
throw ex;
}
}
因为此时环境参数中并没有abc这个参数,然后就会报:
Exception in thread "main" org.springframework.core.env.MissingRequiredPropertiesException: The following properties were declared as required but could not be resolved: [abc]
at org.springframework.core.env.AbstractPropertyResolver.validateRequiredProperties(AbstractPropertyResolver.java:145)
附:代码:
package com.mashibing;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.config.DestructionAwareBeanPostProcessor;
import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.util.Assert;
public class MyClassPathXmlApplicationContext extends ClassPathXmlApplicationContext {
public MyClassPathXmlApplicationContext(String... configLocations){
super(configLocations);
}
@Override
protected void initPropertySources() {
System.out.println("扩展initPropertySource");
getEnvironment().setRequiredProperties("username"); //设置了需要的参数 username, 那么在后续就会校验这个参数舒存在
}
@Override
protected void customizeBeanFactory(DefaultListableBeanFactory beanFactory) {
// super.setAllowBeanDefinitionOverriding(false);
// super.setAllowCircularReferences(false);
super.addBeanFactoryPostProcessor(new MyBeanFactoryPostProcessor());
super.customizeBeanFactory(beanFactory);
}
@Override
protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
System.out.println("扩展实现postProcessBeanFactory方法");
}
}