Spring source extension point 2: customizeBeanFactory 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 customizeBeanFactory(DefaultListableBeanFactory beanFactory) {
    
    
		// 如果属性allowBeanDefinitionOverriding不为空,设置给beanFactory对象相应属性,是否允许覆盖同名称的不同定义的对象
		if (this.allowBeanDefinitionOverriding != null) {
    
    
			beanFactory.setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);
		}
		// 如果属性allowCircularReferences不为空,设置给beanFactory对象相应属性,是否允许bean之间存在循环依赖
		if (this.allowCircularReferences != null) {
    
    
			beanFactory.setAllowCircularReferences(this.allowCircularReferences);
		}
	}

In the AbstractRefreshableApplicationContext class, there is a customizeBeanFactory method that is reserved for subclasses to extend. It is called in the second method of refresh(), obtainFreshBeanFactory() -> refreshBeanFactory().

protected final void refreshBeanFactory() throws BeansException {
    
    
		// 如果存在beanFactory,则销毁beanFactory
		if (hasBeanFactory()) {
    
    
			destroyBeans();
			closeBeanFactory();
		}
		try {
    
    
			// 创建DefaultListableBeanFactory对象
			DefaultListableBeanFactory beanFactory = createBeanFactory();
			// 为了序列化指定id,可以从id反序列化到beanFactory对象
			beanFactory.setSerializationId(getId());
			// 定制beanFactory,设置相关属性,包括是否允许覆盖同名称的不同定义的对象以及循环依赖
			customizeBeanFactory(beanFactory);
			// 初始化documentReader,并进行XML文件读取及解析,默认命名空间的解析,自定义标签的解析
			loadBeanDefinitions(beanFactory);
			this.beanFactory = beanFactory;
		}
		catch (IOException ex) {
    
    
			throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
		}
	}

This method is used to implement the property setting of BeanFactory, mainly to set two properties:

  • allowBeanDefinitionOverriding: Whether to allow overriding objects of different definitions with the same name.
  • allowCircularReferences: Whether to allow circular dependencies between beans.

The following example:

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");
    }

    @Override
    protected void customizeBeanFactory(DefaultListableBeanFactory beanFactory) {
    
    
        super.setAllowBeanDefinitionOverriding(false);
        super.setAllowCircularReferences(false);
        super.customizeBeanFactory(beanFactory);
    }
}
public class Test {
    
    

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

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

Guess you like

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