AnnotationConfigApplicationContext-prepareRefresh

prepareRefresh

刷新前的预处理

protected void prepareRefresh() {
		this.startupDate = System.currentTimeMillis();
		this.closed.set(false);
		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>();
	}

initPropertySources

发现这个方法为空方法,是用来留给子类进行属性值处理的

protected void initPropertySources() {
		// For subclasses: do nothing by default.
	}

getEnvironment()

@Override
	public ConfigurableEnvironment getEnvironment() {
		if (this.environment == null) {
			this.environment = createEnvironment();
		}
		return this.environment;
	}

createEnvironment

protected ConfigurableEnvironment createEnvironment() {
		return new StandardEnvironment();
	}

StandardEnvironment继承了AbstractEnvironment,重写了customizePropertySources

public class StandardEnvironment extends AbstractEnvironment {
    public static final String SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME = "systemEnvironment";
    public static final String SYSTEM_PROPERTIES_PROPERTY_SOURCE_NAME = "systemProperties";

    public StandardEnvironment() {
    }

    protected void customizePropertySources(MutablePropertySources propertySources) {
        propertySources.addLast(new MapPropertySource("systemProperties", this.getSystemProperties()));
        propertySources.addLast(new SystemEnvironmentPropertySource("systemEnvironment", this.getSystemEnvironment()));
    }
}

getEnvironment().validateRequiredProperties()

来看看getEnvironment().validateRequiredProperties()的源码,对应的是AbstractPropertyResolver类的validateRequiredProperties方法:

public void validateRequiredProperties() {
        MissingRequiredPropertiesException ex = new MissingRequiredPropertiesException();
        Iterator var2 = this.requiredProperties.iterator();

        while(var2.hasNext()) {
            String key = (String)var2.next();
            if (this.getProperty(key) == null) {
                ex.addMissingRequiredProperty(key);
            }
        }

        if (!ex.getMissingRequiredProperties().isEmpty()) {
            throw ex;
        }
    }

可见spring容器初始化的时候,会从集合requiredProperties中取出所有key,然后获取这些key的环境变量(包括系统环境变量和进程环境变量),如果有一个key对应的环境变量为空,就会抛出异常,导致spring容器初始化失败;

实现自定义环境变量验证

发现在多种ApplicationContext中只有WebApplicationContext相关的,才可以重写initPropertySources
在这里插入图片描述

自定义ApplicationContext
/**
 * @Description : AnnotationConfigServletWebServerApplicationContext,重写了initPropertySources方法,
 * 要求spring启动的时候环境变量MYSQL_HOST必须存在
 * @Author : zq2599@gmail.com
 * @Date : 2018-08-10 21:40
 */
public class CustomApplicationContext extends AnnotationConfigServletWebServerApplicationContext {

    @Override
    protected void initPropertySources() {
        super.initPropertySources();
        //把"MYSQL_HOST"作为启动的时候必须验证的环境变量
        getEnvironment().setRequiredProperties("MYSQL_HOST");
    }
}
创建应用启动类

创建应用启动类CustomizepropertyverifyApplication,指定ApplicationContext的class为CustomApplicationContext:

@SpringBootApplication
public class CustomizepropertyverifyApplication {

    public static void main(String[] args) {
        SpringApplication springApplication = new SpringApplication(CustomizepropertyverifyApplication.class);
        springApplication.setApplicationContextClass(CustomApplicationContext.class);
        springApplication.run(args);
    }
}
运行结果
org.springframework.core.env.MissingRequiredPropertiesException: The following properties were declared as required but could not be resolved: [MYSQL_HOST]
	at org.springframework.core.env.AbstractPropertyResolver.validateRequiredProperties(AbstractPropertyResolver.java:146) ~[spring-core-5.0.8.RELEASE.jar:5.0.8.RELEASE]
	at org.springframework.core.env.AbstractEnvironment.validateRequiredProperties(AbstractEnvironment.java:519) ~[spring-core-5.0.8.RELEASE.jar:5.0.8.RELEASE]
	at org.springframework.context.support.AbstractApplicationContext.prepareRefresh(AbstractApplicationContext.java:591) ~[spring-context-4.3.12.RELEASE.jar:4.3.12.RELEASE]
	at org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext.prepareRefresh(AnnotationConfigServletWebServerApplicationContext.java:200) ~[spring-boot-2.0.4.RELEASE.jar:2.0.4.RELEASE]
	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:512) ~[spring-context-4.3.12.RELEASE.jar:4.3.12.RELEASE]
	at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:140) ~[spring-boot-2.0.4.RELEASE.jar:2.0.4.RELEASE]
	at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:762) ~[spring-boot-2.0.4.RELEASE.jar:2.0.4.RELEASE]
	at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:398) ~[spring-boot-2.0.4.RELEASE.jar:2.0.4.RELEASE]
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:330) ~[spring-boot-2.0.4.RELEASE.jar:2.0.4.RELEASE]
	at com.atguigu.CustomizepropertyverifyApplication.main(CustomizepropertyverifyApplication.java:18) [classes/:na]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值