在开始之前,我才发现忘记说明了一些东西,这个系列完全是自己参看《spring源码深度解析》一书结合源码,总结而来,spring主要是3.0.5,如果这过程中有不正之处欢迎大家指正,在这过程中我也发现自己写的文章清晰度不高,这里会逐步提高,这里mark一些自己看到的好的学习spring的链接。
继续上一篇的读取内容查看源码
protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) {
if (delegate.isDefaultNamespace(root)) {
NodeList nl = root.getChildNodes();
for(int i = 0; i < nl.getLength(); ++i) {
Node node = nl.item(i);
if (node instanceof Element) {
Element ele = (Element)node;
if (delegate.isDefaultNamespace(ele)) {
this.parseDefaultElement(ele, delegate);
} else {
delegate.parseCustomElement(ele);
}
}
}
} else {
delegate.parseCustomElement(root);
}
}
进入parseDefaultElement方法,由方法名可知这里是解析默认的element,下面调用的和上一篇分析的方法一样
private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) {
if (delegate.nodeNameEquals(ele, "import")) {
this.importBeanDefinitionResource(ele);
} else if (delegate.nodeNameEquals(ele, "alias")) {
this.processAliasRegistration(ele);
} else if (delegate.nodeNameEquals(ele, "bean")) {
this.processBeanDefinition(ele, delegate);
}
}
可以看出是对三种标签解析,我们先看Bean标签的解析
protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
if (bdHolder != null) {
bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
try {
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));
}
}
现在是2018年一月22日晚上九点半,一天上班又要干这,改那说实话我对程序员不免心生倦怠,不知道能坚持多久。
在进入parseBeanDefinitonElemet
public BeanDefinitionHolder parseBeanDefinitionElement(Element ele, BeanDefinition containingBean) {
String id = ele.getAttribute("id");
String nameAttr = ele.getAttribute("name");
List<String> aliases = new ArrayList();
if (StringUtils.hasLength(nameAttr)) {
String[] nameArr = StringUtils.tokenizeToStringArray(nameAttr, ",; ");
aliases.addAll((Collection)Arrays.asList(nameArr));
}
String beanName = id;
if (!StringUtils.hasText(id) && !aliases.isEmpty()) {
beanName = (String)aliases.remove(0);
if (this.logger.isDebugEnabled()) {
this.logger.debug("No XML 'id' specified - using '" + beanName + "' as bean name and " + aliases + " as aliases");
}
}
if (containingBean == null) {
//保证beanNam的唯一性,id存在时为id,不然为name中的第一个
this.checkNameUniqueness(beanName, aliases, ele);
}
/解析xml文件中的bean标签,并利用AbstractBeanDefinition用来保存其中的各个属性
一、bean标签的属性
scope:用来配置spring bean的作用域
singleton:表示bean为单例的
abstract:设置为true,将该bean仅仅作为模板使用,应用程序上下文不会试图预先初始化它
lazy-init:设为true,延迟加载,该bean不会在ApplicationContext启动时提前被实例化,而是第一次向容器通过getBean索取bean时实例化。注:只对singleton的bean起作用
autowire:自动装配
dependency-check:依赖检查
depends-on:表示一个bean的实例化依靠另一个bean先实例化
autowire-candidate:设为false,容器在查找自动装配对象时,将不考虑该bean,即它不会被考虑作为其他bean自动装配的候选者,但是该bean本身可以使用自动装配来注入其他bean
primary:该bean优先被注入
init-method:初始化bean时调用的方法
destory-method:容器销毁之前所调用的方法
factory-method:当调用factory-method所指向的方法时,才开始实例化bean
factory-bean:调用静态工厂方法的方式创建bean
二、bean的子元素
meta:元数据,当需要使用里面的信息时可以通过key获取
lookup-method:获取器注入,是把一个方法声明为返回某种类型的bean但实际要返回的bean是在配置文件里面配置的
replaced-method:可以在运行时调用新的方法替换现有的方法,还能动态的更新原有方法的逻辑
constructor-arg:对bean自动寻找对应的构造函数,并在初始化的时候将设置的参数传入进去
property:基本数据类型赋值
qualifier:通过Qualifier指定注入bean的名称
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.isDebugEnabled()) {
this.logger.debug("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;
}
}
再解析bean标签之后,进入decorateBeanDefinitionIfRequired方法,此方法为bean标签下的元素进行解析,如果是自定义标签则调用其namespace否则不解析,原书对此方法的描述为装饰模式的调用?之后再进入BeanDefinitionReaderutils.registerBeanDefiniton方法,其中传入了bdholder,这之中具有bean的AbstaractBeanDefinition,其中获取的register为xmlBeanFactory
public BeanDefinitionHolder parseBeanDefinitionElement(Element ele, BeanDefinition containingBean) {
String id = ele.getAttribute("id");
String nameAttr = ele.getAttribute("name");
List<String> aliases = new ArrayList();
if (StringUtils.hasLength(nameAttr)) {
String[] nameArr = StringUtils.tokenizeToStringArray(nameAttr, ",; ");
aliases.addAll((Collection)Arrays.asList(nameArr));
}
String beanName = id;
if (!StringUtils.hasText(id) && !aliases.isEmpty()) {
beanName = (String)aliases.remove(0);
if (this.logger.isDebugEnabled()) {
this.logger.debug("No XML 'id' specified - using '" + beanName + "' as bean name and " + aliases + " as aliases");
}
}
if (containingBean == null) {
//保证beanNam的唯一性,id存在时为id,不然为name中的第一个
this.checkNameUniqueness(beanName, aliases, ele);
}
/解析xml文件中的bean标签,并利用AbstractBeanDefinition用来保存其中的各个属性
一、bean标签的属性
scope:用来配置spring bean的作用域
singleton:表示bean为单例的
abstract:设置为true,将该bean仅仅作为模板使用,应用程序上下文不会试图预先初始化它
lazy-init:设为true,延迟加载,该bean不会在ApplicationContext启动时提前被实例化,而是第一次向容器通过getBean索取bean时实例化。注:只对singleton的bean起作用
autowire:自动装配
dependency-check:依赖检查
depends-on:表示一个bean的实例化依靠另一个bean先实例化
autowire-candidate:设为false,容器在查找自动装配对象时,将不考虑该bean,即它不会被考虑作为其他bean自动装配的候选者,但是该bean本身可以使用自动装配来注入其他bean
primary:该bean优先被注入
init-method:初始化bean时调用的方法
destory-method:容器销毁之前所调用的方法
factory-method:当调用factory-method所指向的方法时,才开始实例化bean
factory-bean:调用静态工厂方法的方式创建bean
二、bean的子元素
meta:元数据,当需要使用里面的信息时可以通过key获取
lookup-method:获取器注入,是把一个方法声明为返回某种类型的bean但实际要返回的bean是在配置文件里面配置的
replaced-method:可以在运行时调用新的方法替换现有的方法,还能动态的更新原有方法的逻辑
constructor-arg:对bean自动寻找对应的构造函数,并在初始化的时候将设置的参数传入进去
property:基本数据类型赋值
qualifier:通过Qualifier指定注入bean的名称
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.isDebugEnabled()) {
this.logger.debug("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;
}
}
public static void registerBeanDefinition(BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry) throws BeanDefinitionStoreException {
String beanName = definitionHolder.getBeanName();
registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());
String[] aliases = definitionHolder.getAliases();
if (aliases != null) {
String[] var7 = aliases;
int var6 = aliases.length;
for(int var5 = 0; var5 < var6; ++var5) {
String aliase = var7[var5];
registry.registerAlias(beanName, aliase);
}
}
}
//注册beanDefinition
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 {
//校验beanDefinition中的methodOverrides中匹配的方法是否在beanDefinition中有方法
((AbstractBeanDefinition)beanDefinition).validate();
} catch (BeanDefinitionValidationException var6) {
throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName, "Validation of bean definition failed", var6);
}
}
//全局变量,存有所有的beanDefinition
Map var3 = this.beanDefinitionMap;
synchronized(this.beanDefinitionMap) {
Object oldBeanDefinition = this.beanDefinitionMap.get(beanName);
if (oldBeanDefinition != null) {
if (!this.allowBeanDefinitionOverriding) {
throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName, "Cannot register bean definition [" + beanDefinition + "] for bean '" + beanName + "': There is already [" + oldBeanDefinition + "] bound.");
}
if (this.logger.isInfoEnabled()) {
this.logger.info("Overriding bean definition for bean '" + beanName + "': replacing [" + oldBeanDefinition + "] with [" + beanDefinition + "]");
}
} else {
this.beanDefinitionNames.add(beanName);
this.frozenBeanDefinitionNames = null;
}
this.beanDefinitionMap.put(beanName, beanDefinition);
//
this.resetBeanDefinition(beanName);
}
}