【spring源码深度解析—容器的功能扩展之initPropertySources】 ApplicationContext提供了更多的扩展功能。BeanFactory是容器的顶层接口类,ApplicationContext实现了BeanFactory所有功能同时增强了接口实现和功能扩展。大多数情况下优先使用ApplicationContext,
对 BeanFactory接口做了很多封装了功能实现。
initPropertySources扩展功能说明
refresh函数中是spring核心,包含大部分ApplicationContext中提供的功能,代码如下:
@Override public void refresh() throws BeansException, IllegalStateException { synchronized (this.startupShutdownMonitor) { /** * 1、设置容器启动时间 * 2、设置活跃状态为true * 3、设置关闭状态为false * 4、获取Environment对象,并加载当前系统的属性值到Environment对象中 * 5、准备监听器和时间的集合对象,默认为空的集合 */ prepareRefresh(); …… } } /** * prepareRefresh 方法 */ 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(); // 1、检查是否存在环境变量如果存在直接用,不存在重更新获取 // 2、创建并获取环境对象、验证需要的属性文件是否符合 getEnvironment().validateRequiredProperties(); // 判断刷新前的应用程序监听器集合是否为空,如果为空,则将监听器添加到此集合中 if (this.earlyApplicationListeners == null) { this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners); } else { // 如果不等于空,则清空集合元素对象 this.applicationListeners.clear(); this.applicationListeners.addAll(this.earlyApplicationListeners); } // 创建刷新前的监听事件集合 this.earlyApplicationEvents = new LinkedHashSet<>(); }
initPropertySources扩展功能说明
initPropertySources方法符合Spring的开放式结构设计,给用户增加扩展Spring的能力。用户可以根据自身的需要重写initPropertySourece方法,并在方法中进行个性化设计及其业务处理。getEnvironment().validateRequiredProperties()中,validateRequiredProperties则是对属性进行验证。下面对这个属性进行扩展举例说明:
例增加如下需求:在项目运行过程中想通过系统环境变量中取得定义的某个值或者系统中的值操作。此需求有很多解决办法,例如修改:spring原码,在Spring提供我们很好扩展性,例如可通过实现initPropertySources扩展接口实现。实例代码如下
/** * @author :java.zhao * @description:扩展initPropertySource,测试入口类 * @date :2018-10-08 15:23 */ public class testSuperInitPropertySources { /** * 演示:通过此例子可对系统的预留方法进行功能扩展,本次实现方法:【initPropertySources】 */ @Test public void test01() { MyClassPathXmlApplicatonContext ac1 = new MyClassPathXmlApplicatonContext("classpath:beanfactory.xml"); // ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring-${username}.xml"); System.out.println(ac1.getEnvironment().getSystemProperties().get("java.spring.teacher")); } }
/** * @author :java.zhao * @description:集成接口类,自定义类TycoonClassPathXmlApplicatonContext * @date :2018-10-08 15:19 */ public class TycoonClassPathXmlApplicatonContext extends ClassPathXmlApplicationContext { TycoonClassPathXmlApplicatonContext (String... configlocations){ super(configlocations); } // TODO 扩展 initPropertySources 方法,baidu实现 @Override protected void initPropertySources(){ // 还可以对系统属性值进行,修改(特别注意,如果不存在此属性程序会终止) //getEnvironment().setRequiredProperties("properties.error"); // 通过以上测试可得,可以对存在系统参数和内部环境变量等进行修改 System.out.println("扩展initPropertySource"); //这里添加了一个name属性到Environment里面,以方便我们在后面用到 getEnvironment().getSystemProperties().put("java.spring.teacher","java.zhao"); // 此处我们做了两个扩展: // 第一,向Environment中添加了一个属性值。 // 第二:设置了一个必要的系统属性properties.error,当Environment中不包含 // properties.error属性时系统会抛出异常,程序会终止。 } }
输出:
扩展initPropertySource
设置系统:java.spring.teacher 值为:java.zhao
Process finished with exit code 0