Spring source extension point 1: initPropertySources method

The power of Spring is not only that it provides great convenience for Java developers, but also that its open architecture allows users to have the greatest ability to extend Spring.

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

There is an initPropertySources method in the AbstractApplicationContext class that is reserved for subclasses to extend. It is called in the first method prepareRefresh(); of 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());
			}
		}

		// Initialize any placeholder property sources in the context environment.
		// 留给子类覆盖,初始化属性资源
		initPropertySources();

		// Validate that all properties marked as required are resolvable:
		// see ConfigurablePropertyResolver#setRequiredProperties
		// 创建并获取环境对象,验证需要的属性文件是否都已经放入环境中
		getEnvironment().validateRequiredProperties();

		// Store pre-refresh ApplicationListeners...
		// 判断刷新前的应用程序监听器集合是否为空,如果为空,则将监听器添加到此集合中
		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<>();
	}

So we can inherit this class or its subclasses to override the initPropertySources method and implement some extensions.

public class MyClassPathXmlApplicationContext extends ClassPathXmlApplicationContext {


    public MyClassPathXmlApplicationContext(String... configLocations){
        super(configLocations);
    }

    @Override
    protected void initPropertySources() {
        System.out.println("扩展initPropertySource");
        //这里添加了一个name属性到Environment里面,以方便我们在后面用到
        getEnvironment().getSystemProperties().put("name","bobo");
        //这里要求Environment中必须包含username属性,如果不包含,则抛出异常
        getEnvironment().setRequiredProperties("username");
    }
}

Here we have made two extensions:
First, an attribute value is added to the Environment.
Second: We set a necessary system attribute username, and the system will throw an exception when the username attribute is not included in the Environment.

Test category:

public class Test {

    public static void main(String[] args) {
        MyClassPathXmlApplicationContext ac = new MyClassPathXmlApplicationContext("applicationContext.xml");

//        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring-${username}.xml");
    }
}

Of course you can also do other extensions, here is just an example.

Guess you like

Origin blog.csdn.net/u013277209/article/details/109177452