El poder de Spring no es solo que proporciona una gran comodidad para los desarrolladores de Java, sino también que su arquitectura abierta permite a los usuarios tener la mayor capacidad para extender 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);
}
}
Hay un métodoustomBeanFactory en la clase AbstractRefreshableApplicationContext que está reservado para que las subclases se extiendan. Se llama en el segundo método de refresh (), getFreshBeanFactory () -> 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);
}
}
Este método se utiliza para implementar la configuración de propiedades de BeanFactory, principalmente para establecer dos propiedades:
- allowBeanDefinitionOverriding: si se permite la sustitución de objetos de diferentes definiciones con el mismo nombre.
- allowCircularReferences: si se permiten dependencias circulares entre beans.
El siguiente ejemplo:
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");
}
}