复制代码
protected void doRegisterBeanDefinitions(Element root) {
// Any nested <beans> elements will cause recursion in this method. In
// order to propagate and preserve <beans> default-* attributes correctly,
// keep track of the current (parent) delegate, which may be null. Create
// the new (child) delegate with a reference to the parent for fallback purposes,
// then ultimately reset this.delegate back to its original (parent) reference.
// this behavior emulates a stack of delegates without actually necessitating one.
BeanDefinitionParserDelegate parent = this.delegate;
//委托给delegate解析
this.delegate = createDelegate(getReaderContext(), root, parent);
//判断当前Beans节点是否是默认命名空间
if (this.delegate.isDefaultNamespace(root)) {
//获取beans节点的profile属性
String profileSpec = root.getAttribute(PROFILE_ATTRIBUTE);
if (StringUtils.hasText(profileSpec)) {
//可以使用逗号或分号将当前beans标签指定为多个profile类型
String[] specifiedProfiles = StringUtils.tokenizeToStringArray(
profileSpec, BeanDefinitionParserDelegate.MULTI_VALUE_ATTRIBUTE_DELIMITERS);
// We cannot use Profiles.of(...) since profile expressions are not supported
// in XML config. See SPR-12458 for details.
//判断当前beans标签的profile是否被激活
if (!getReaderContext().getEnvironment().acceptsProfiles(specifiedProfiles)) {
if (logger.isDebugEnabled()) {
logger.debug("Skipped XML bean definition file due to specified profiles [" + profileSpec +
"] not matching: " + getReaderContext().getResource());
}
return;
}
}
}
//解析前处理,留给子类实现
preProcessXml(root);
//真正的解析过程
parseBeanDefinitions(root, this.delegate);
//解析后处理,留给子类实现
postProcessXml(root);
private final DocumentDefaultsDefinition defaults = new DocumentDefaultsDefinition();
public BeanDefinitionParserDelegate(XmlReaderContext readerContext) {
Assert.notNull(readerContext, "XmlReaderContext must not be null");
this.readerContext = readerContext;
}
DocumentDefaultsDefinition保存了根节点的默认配置属性值,比如说default-lazyInit,default-autowire,default-initMethod,default-destroyMethod等,这几种属性应该都用过吧,如果该beans标签下的bean没有配置这些属性,就会使用beans标签的默认配置。
复制代码
//判断当前Beans节点是否是默认命名空间
if (this.delegate.isDefaultNamespace(root)) {
//获取beans节点的profile属性
String profileSpec = root.getAttribute(PROFILE_ATTRIBUTE);
if (StringUtils.hasText(profileSpec)) {
//可以使用逗号或分号将当前beans标签指定为多个profile类型
String[] specifiedProfiles = StringUtils.tokenizeToStringArray(
profileSpec, BeanDefinitionParserDelegate.MULTI_VALUE_ATTRIBUTE_DELIMITERS);
// We cannot use Profiles.of(...) since profile expressions are not supported
// in XML config. See SPR-12458 for details.
//判断当前beans标签的profile是否被激活
if (!getReaderContext().getEnvironment().acceptsProfiles(specifiedProfiles)) {
if (logger.isDebugEnabled()) {
logger.debug("Skipped XML bean definition file due to specified profiles [" + profileSpec +
"] not matching: " + getReaderContext().getResource());
}
return;
}
}
}
复制代码
知道了怎么用,就容易多了,首先得到beans标签的指定的profile数组,与指定的spring.active.profile对比,符合条件的话改beans才会被加载。
复制代码
protected AbstractBeanDefinitionReader(BeanDefinitionRegistry registry) {
Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
this.registry = registry;
// Determine ResourceLoader to use.
if (this.registry instanceof ResourceLoader) {
this.resourceLoader = (ResourceLoader) this.registry;
}
else {
this.resourceLoader = new PathMatchingResourcePatternResolver();
}
// Inherit Environment if possible
if (this.registry instanceof EnvironmentCapable) {
this.environment = ((EnvironmentCapable) this.registry).getEnvironment();
}
else {
this.environment = new StandardEnvironment();
}
}
复制代码
这里的StandardEnvironment初始化会加载当前的系统变量和环境变量,是对系统变量和环境变量的封装。在StandardEnvironmen继承自父类的构造方法中,会调用customizePropertySources方法
复制代码
private final MutablePropertySources propertySources = new MutablePropertySources()
protected void customizePropertySources(MutablePropertySources propertySources) {
propertySources.addLast(
new PropertiesPropertySource(SYSTEM_PROPERTIES_PROPERTY_SOURCE_NAME, getSystemProperties()));
propertySources.addLast(
new SystemEnvironmentPropertySource(SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME, getSystemEnvironment()));
}
复制代码
该方法将当前系统变量和环境变量保存在其propertySources属性中。
复制代码
public class MutablePropertySources implements PropertySources {
private final List<PropertySource<?>> propertySourceList = new CopyOnWriteArrayList<>();
/**
* Create a new {@link MutablePropertySources} object.
*/
public MutablePropertySources() {
}
}
复制代码
而MutablePropertySources 有一个List属性,保存多个属性来源。
复制代码
protected void doRegisterBeanDefinitions(Element root) {
// Any nested <beans> elements will cause recursion in this method. In
// order to propagate and preserve <beans> default-* attributes correctly,
// keep track of the current (parent) delegate, which may be null. Create
// the new (child) delegate with a reference to the parent for fallback purposes,
// then ultimately reset this.delegate back to its original (parent) reference.
// this behavior emulates a stack of delegates without actually necessitating one.
BeanDefinitionParserDelegate parent = this.delegate;
//委托给delegate解析
this.delegate = createDelegate(getReaderContext(), root, parent);
//判断当前Beans节点是否是默认命名空间
if (this.delegate.isDefaultNamespace(root)) {
//获取beans节点的profile属性
String profileSpec = root.getAttribute(PROFILE_ATTRIBUTE);
if (StringUtils.hasText(profileSpec)) {
//可以使用逗号或分号将当前beans标签指定为多个profile类型
String[] specifiedProfiles = StringUtils.tokenizeToStringArray(
profileSpec, BeanDefinitionParserDelegate.MULTI_VALUE_ATTRIBUTE_DELIMITERS);
// We cannot use Profiles.of(...) since profile expressions are not supported
// in XML config. See SPR-12458 for details.
//判断当前beans标签的profile是否被激活
if (!getReaderContext().getEnvironment().acceptsProfiles(specifiedProfiles)) {
if (logger.isDebugEnabled()) {
logger.debug("Skipped XML bean definition file due to specified profiles [" + profileSpec +
"] not matching: " + getReaderContext().getResource());
}
return;
}
}
}
//解析前处理,留给子类实现
preProcessXml(root);
//真正的解析过程
parseBeanDefinitions(root, this.delegate);
//解析后处理,留给子类实现
postProcessXml(root);