前言
上一章从源头上一步步的跟踪了bean的加载,bean加载需要解析配置文件,但是配置文件中也有不同的标签,spring会对不同的标签进行不同的解析逻辑,标签包括import,beans,bean,alias,下面就来分析不同的解析具体的逻辑
bean标签的解析
private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) {
// 对import标签的解析
if (delegate.nodeNameEquals(ele, "import")) {
this.importBeanDefinitionResource(ele);
} else if (delegate.nodeNameEquals(ele, "alias")) {
// 对alias标签的解析
this.processAliasRegistration(ele);
} else if (delegate.nodeNameEquals(ele, "bean")) {
// 对bean标签的解析
this.processBeanDefinition(ele, delegate);
} else if (delegate.nodeNameEquals(ele, "beans")) {
// 对beans标签的解析
this.doRegisterBeanDefinitions(ele);
}
}
bean标签的解析是最为复杂的,只要理解了bean标签的解析,其他标签的解析也就都迎刃而解
// 解析bean标签方法
protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
// 返回配置文件中的属性
BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
if (bdHolder != null) {
// 不为空时,如果默认标签的子节点存在自定义属性,需要对自定义标签进行解析
bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
try {
// 解析完成后 对bdHolder进行注册
BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, this.getReaderContext().getRegistry());
} catch (BeanDefinitionStoreException var5) {
this.getReaderContext().error("Failed to register bean definition with name '" + bdHolder.getBeanName() + "'", ele, var5);
}
// 最后发出相应事件,通知相关的监听器,注册完成
this.getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
}
}
delegate.parseBeanDefinitionElement(ele);在这个方法中进行解析
@Nullable
public BeanDefinitionHolder parseBeanDefinitionElement(Element ele, @Nullable BeanDefinition containingBean) {
// 解析id属性
String id = ele.getAttribute("id");
// 解析name属性
String nameAttr = ele.getAttribute("name");
List<String> aliases = new ArrayList();
if (StringUtils.hasLength(nameAttr)) {
String[] nameArr = StringUtils.tokenizeToStringArray(nameAttr, ",; ");
aliases.addAll(Arrays.asList(nameArr));
}
String beanName = id;
if (!StringUtils.hasText(id) && !aliases.isEmpty()) {
beanName = (String)aliases.remove(0);
if (this.logger.isTraceEnabled()) {
this.logger.trace("No XML 'id' specified - using '" + beanName + "' as bean name and " + aliases + " as aliases");
}
}
if (containingBean == null) {
this.checkNameUniqueness(beanName, aliases, ele);
}
// 创建用于承载属性的AbstractBeanDefinition类型的GenericBeanDefinition
AbstractBeanDefinition beanDefinition = this.parseBeanDefinitionElement(ele, beanName, containingBean);
if (beanDefinition != null) {
if (!StringUtils.hasText(beanName)) {
try {
if (containingBean != null) {
beanName = BeanDefinitionReaderUtils.generateBeanName(beanDefinition, this.readerContext.getRegistry(), true);
} else {
beanName = this.readerContext.generateBeanName(beanDefinition);
String beanClassName = beanDefinition.getBeanClassName();
if (beanClassName != null && beanName.startsWith(beanClassName) && beanName.length() > beanClassName.length() && !this.readerContext.getRegistry().isBeanNameInUse(beanClassName)) {
aliases.add(beanClassName);
}
}
if (this.logger.isTraceEnabled()) {
this.logger.trace("Neither XML 'id' nor 'name' specified - using generated bean name [" + beanName + "]");
}
} catch (Exception var9) {
this.error(var9.getMessage(), ele);
return null;
}
}
String[] aliasesArray = StringUtils.toStringArray(aliases);
return new BeanDefinitionHolder(beanDefinition, beanName, aliasesArray);
} else {
return null;
}
}
解析后,最终将信息封装到BeanDefinitionHolder中,而这其中也创建了BeanDefinition的实现GenericBeanDefinition
Spring通过BeanDefinition将配置文件中的bean配置信息转换为容器内部表示,并将这些BeanDefinition注册到BeanDefinitionRegisity
public abstract class BeanDefinitionReaderUtils {
public static final String GENERATED_BEAN_NAME_SEPARATOR = "#";
public BeanDefinitionReaderUtils() {
}
public static AbstractBeanDefinition createBeanDefinition(@Nullable String parentName, @Nullable String className, @Nullable ClassLoader classLoader) throws ClassNotFoundException {
GenericBeanDefinition bd = new GenericBeanDefinition();
bd.setParentName(parentName);
if (className != null) {
if (classLoader != null) {
//这里面挺重要 是通过jvm的加载器来记载bean配置文件中配置的对象,也就是说他的实例化是通过传入加载器和类名来进行的,不是简单的new 一个对象
bd.setBeanClass(ClassUtils.forName(className, classLoader));
} else {
bd.setBeanClassName(className);
}
}
return bd;
}
Xml中所有的配置都可以在GenericBeanDefinition实例类中找到对应的配置,但是GenericBeanDefinition只是子类实现,大部分的通用属性都保存在AbstractBeanDefinition
public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccessor implements BeanDefinition, Cloneable {
-------
// 作用范围
@Nullable
private String scope;
private boolean abstractFlag;
// 是否延迟加载
@Nullable
private Boolean lazyInit;
// 是否自动注入
private int autowireMode;
private int dependencyCheck;
@Nullable
private String[] dependsOn;
private boolean autowireCandidate;
private boolean primary;
-------
以上bean解析就结束了,解析的过程就是将xml配置封装到GenericBeanDefinition的过程,而GenericBeanDefinition实现了BeanDefinition,最终BeanDefinitionHolder又和BeanDefinition有依赖的关系,所以返回了BeanDefinitionHolder
public class BeanDefinitionHolder implements BeanMetadataElement {
private final BeanDefinition beanDefinition;
private final String beanName;
@Nullable
private final String[] aliases;
public BeanDefinitionHolder(BeanDefinition beanDefinition, String beanName) {
this(beanDefinition, beanName, (String[])null);
}
回到最开始的方法,这个方法里面包含两步骤,一步是bean的解析(将xml文件解析到GenericBeanDefinition,GenericBeanDefinition是BeanDefinition的实现,BeanDefinition是BeanDefinitionHolder中的一个属性),一步是bean的注册,下面我们就看看bean的注册
// 解析bean标签方法
protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
// 返回配置文件中的属性(BeanDefinitionHolder中包含BeanDefinition)
BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
if (bdHolder != null) {
// 不为空时,如果默认标签的子节点存在自定义属性,需要对自定义标签进行解析
bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
try {
// 解析完成后 对bdHolder进行注册
BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, this.getReaderContext().getRegistry());
} catch (BeanDefinitionStoreException var5) {
this.getReaderContext().error("Failed to register bean definition with name '" + bdHolder.getBeanName() + "'", ele, var5);
}
// 最后发出相应事件,通知相关的监听器,注册完成
this.getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
}
}
registerBeanDefinition方法
public static void registerBeanDefinition(BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry) throws BeanDefinitionStoreException {
String beanName = definitionHolder.getBeanName();
// 使用beanName作为唯一标识注册
registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());
String[] aliases = definitionHolder.getAliases();
if (aliases != null) {
String[] var4 = aliases;
int var5 = aliases.length;
for(int var6 = 0; var6 < var5; ++var6) {
String alias = var4[var6];
registry.registerAlias(beanName, alias);
}
}
}
在DefaultListableBeanFactory类中进行注册,注册的理解就是通过beanName形成一个map,beanName是key
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) throws BeanDefinitionStoreException {
Assert.hasText(beanName, "Bean name must not be empty");
Assert.notNull(beanDefinition, "BeanDefinition must not be null");
if (beanDefinition instanceof AbstractBeanDefinition) {
try {
((AbstractBeanDefinition)beanDefinition).validate();
} catch (BeanDefinitionValidationException var8) {
throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName, "Validation of bean definition failed", var8);
}
}
BeanDefinition existingDefinition = (BeanDefinition)this.beanDefinitionMap.get(beanName);
if (existingDefinition != null) {
if (!this.isAllowBeanDefinitionOverriding()) {
throw new BeanDefinitionOverrideException(beanName, beanDefinition, existingDefinition);
}
if (existingDefinition.getRole() < beanDefinition.getRole()) {
if (this.logger.isInfoEnabled()) {
this.logger.info("Overriding user-defined bean definition for bean '" + beanName + "' with a framework-generated bean definition: replacing [" + existingDefinition + "] with [" + beanDefinition + "]");
}
} else if (!beanDefinition.equals(existingDefinition)) {
if (this.logger.isDebugEnabled()) {
this.logger.debug("Overriding bean definition for bean '" + beanName + "' with a different definition: replacing [" + existingDefinition + "] with [" + beanDefinition + "]");
}
} else if (this.logger.isTraceEnabled()) {
this.logger.trace("Overriding bean definition for bean '" + beanName + "' with an equivalent definition: replacing [" + existingDefinition + "] with [" + beanDefinition + "]");
}
// beanDefinitionMap是全局变量会出现并发访问问题
// 在这一步注册bean
this.beanDefinitionMap.put(beanName, beanDefinition);
} else {
if (this.hasBeanCreationStarted()) {
Map var4 = this.beanDefinitionMap;
synchronized(this.beanDefinitionMap) {
this.beanDefinitionMap.put(beanName, beanDefinition);
List<String> updatedDefinitions = new ArrayList(this.beanDefinitionNames.size() + 1);
updatedDefinitions.addAll(this.beanDefinitionNames);
updatedDefinitions.add(beanName);
this.beanDefinitionNames = updatedDefinitions;
this.removeManualSingletonName(beanName);
}
} else {
this.beanDefinitionMap.put(beanName, beanDefinition);
this.beanDefinitionNames.add(beanName);
this.removeManualSingletonName(beanName);
}
this.frozenBeanDefinitionNames = null;
}
if (existingDefinition == null && !this.containsSingleton(beanName)) {
if (this.isConfigurationFrozen()) {
this.clearByTypeCache();
}
} else {
this.resetBeanDefinition(beanName);
}
}