知道了IOC启动的需要多个阶段,接下来学习下第一个阶段 AbstractApplicationContext # prepareRefresh() 都干了啥!
工作内容
这个阶段主要是准备工作:
- 设置启动日期,启动标志;
- 给子类扩展点,自定义处理环境变量;
- 验证环境变量是否都已经准备好了;
- 处理事件监听器们;
spring-web | org.springframework.context.support.AbstractApplicationContext#refresh
protected void prepareRefresh() {// 记录启动时间,设置状态表示开始启动// Switch to active.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();// 检测下需要验证的属性是否都已经正确的放入当前环境中getEnvironment().validateRequiredProperties();// 准备相关监听器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);}this.earlyApplicationEvents = new LinkedHashSet<>();}
代码验证环境变量
可以重写这个 initPropertySources() 来测试下工作。
准备个 bean.xml 及对应的实体
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN""https://www.springframework.org/dtd/spring-beans-2.0.dtd"><beans><bean id="user" class="cn.lichenghao.entity.User"><property name="name"><value>Rod</value></property><property name="age"><value>31</value></property></bean></beans>
测试用对象。
package cn.lichenghao.entity;public class User {private String name;private String age;public User() {System.out.println("User construct run~~~");}public User(String name, String age) {this.name = name;this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getAge() {return age;}public void setAge(String age) {this.age = age;}@Overridepublic String toString() {return "User{" +"name='" + name + '\'' +", age='" + age + '\'' +'}';}public void sayHello() {System.out.println("hello world!");}}
然后先加载测试。
/*** 编译后的第一个Hello World** @author chenghao.li*/public class App {public static void main(String[] args) {// 根据配置文件加载beanClassPathXmlApplicationContext classPathXmlApplicationContext= new ClassPathXmlApplicationContext("bean.xml");User bean = classPathXmlApplicationContext.getBean(User.class);bean.sayHello();}}
自定义个context。
/*** 自定义** @author chenghao.li*/public class MyApplicationContext extends ClassPathXmlApplicationContext {public MyApplicationContext(String configLocation) throws BeansException {super(configLocation);}@Overrideprotected void initPropertySources() {getEnvironment().setRequiredProperties("ABC");super.initPropertySources();}}
再测试下。
/*** 编译后的第一个Hello World** @author chenghao.li*/public class App {public static void main(String[] args) {// 自定义加载MyApplicationContext myApplicationContext = new MyApplicationContext("bean.xml");User mybean = myApplicationContext.getBean(User.class);mybean.sayHello();}}
这个时候就会报错,因为我们的系统环境变量中并没有 ABC。
Exception in thread "main" org.springframework.core.env.MissingRequiredPropertiesException:The following properties were declared as required but could not be resolved: [ABC]
添加个环境变量 ABC,再进行测试。
/*** 编译后的第一个Hello World** @author chenghao.li*/public class App {public static void main(String[] args) {System.setProperty("ABC", "1234");// 自定义加载MyApplicationContext myApplicationContext = new MyApplicationContext("bean.xml");User mybean = myApplicationContext.getBean(User.class);mybean.sayHello();}}
