Spring5源码分析(014)——IoC篇之解析bean标签:解析各种属性
注:《Spring5源码分析》汇总可参考:Spring5源码分析(002)——博客汇总
前面的篇章提到, parseBeanDefinitionElement( Element ele, String beanName, @Nullable BeanDefinition containingBean) 方法内部就是对 bean 标签的各种属性和子元素的解析,然后封装到 AbstractBeanDefinition 中。本文将对解析 bean 标签的各种属性这一步进行分析,这里调用的是 BeanDefinitionParserDelegate.parseBeanDefinitionAttributes(Element ele, String beanName,@Nullable BeanDefinition containingBean, AbstractBeanDefinition bd) 方法进行属性的解析,没有什么特殊处理处理,基本上就是去读给定 bean 标签的各种指定的属性,然后设置到 AbstractBeanDefinition 实例中。
/** * Apply the attributes of the given bean element to the given bean * definition. * <p>解析给定 bean 元素的属性然后设置到 bean 定义中 * @param ele bean declaration element * @param beanName bean name * @param containingBean containing bean definition * @return a bean definition initialized according to the bean element attributes */ public AbstractBeanDefinition parseBeanDefinitionAttributes(Element ele, String beanName, @Nullable BeanDefinition containingBean, AbstractBeanDefinition bd) { // 解析 singleton 属性 if (ele.hasAttribute(SINGLETON_ATTRIBUTE)) { error("Old 1.x 'singleton' attribute in use - upgrade to 'scope' declaration", ele); } // 解析 scope 属性 else if (ele.hasAttribute(SCOPE_ATTRIBUTE)) { bd.setScope(ele.getAttribute(SCOPE_ATTRIBUTE)); } else if (containingBean != null) { // Take default from containing bean in case of an inner bean definition. // 如果都没有设置,则使用嵌入 beanDefinition 的 scope 属性 bd.setScope(containingBean.getScope()); } // 解析 abstract 属性 if (ele.hasAttribute(ABSTRACT_ATTRIBUTE)) { bd.setAbstract(TRUE_VALUE.equals(ele.getAttribute(ABSTRACT_ATTRIBUTE))); } // 解析 lazy-init 属性 String lazyInit = ele.getAttribute(LAZY_INIT_ATTRIBUTE); if (isDefaultValue(lazyInit)) { lazyInit = this.defaults.getLazyInit(); } bd.setLazyInit(TRUE_VALUE.equals(lazyInit)); // 解析 autowire 属性 String autowire = ele.getAttribute(AUTOWIRE_ATTRIBUTE); bd.setAutowireMode(getAutowireMode(autowire)); // 解析 depends-on 属性 if (ele.hasAttribute(DEPENDS_ON_ATTRIBUTE)) { String dependsOn = ele.getAttribute(DEPENDS_ON_ATTRIBUTE); bd.setDependsOn(StringUtils.tokenizeToStringArray(dependsOn, MULTI_VALUE_ATTRIBUTE_DELIMITERS)); } // 解析 autowire-candidate 属性 String autowireCandidate = ele.getAttribute(AUTOWIRE_CANDIDATE_ATTRIBUTE); if (isDefaultValue(autowireCandidate)) { String candidatePattern = this.defaults.getAutowireCandidates(); if (candidatePattern != null) { String[] patterns = StringUtils.commaDelimitedListToStringArray(candidatePattern); bd.setAutowireCandidate(PatternMatchUtils.simpleMatch(patterns, beanName)); } } else { bd.setAutowireCandidate(TRUE_VALUE.equals(autowireCandidate)); } // 解析 primary 属性 if (ele.hasAttribute(PRIMARY_ATTRIBUTE)) { bd.setPrimary(TRUE_VALUE.equals(ele.getAttribute(PRIMARY_ATTRIBUTE))); } // 解析 init-method 属性 if (ele.hasAttribute(INIT_METHOD_ATTRIBUTE)) { String initMethodName = ele.getAttribute(INIT_METHOD_ATTRIBUTE); bd.setInitMethodName(initMethodName); } else if (this.defaults.getInitMethod() != null) { bd.setInitMethodName(this.defaults.getInitMethod()); bd.setEnforceInitMethod(false); } // 解析 destroy-method 属性 if (ele.hasAttribute(DESTROY_METHOD_ATTRIBUTE)) { String destroyMethodName = ele.getAttribute(DESTROY_METHOD_ATTRIBUTE); bd.setDestroyMethodName(destroyMethodName); } else if (this.defaults.getDestroyMethod() != null) { bd.setDestroyMethodName(this.defaults.getDestroyMethod()); bd.setEnforceDestroyMethod(false); } // 解析 factory-method 属性 if (ele.hasAttribute(FACTORY_METHOD_ATTRIBUTE)) { bd.setFactoryMethodName(ele.getAttribute(FACTORY_METHOD_ATTRIBUTE)); } // 解析 factory-bean 属性 if (ele.hasAttribute(FACTORY_BEAN_ATTRIBUTE)) { bd.setFactoryBeanName(ele.getAttribute(FACTORY_BEAN_ATTRIBUTE)); } return bd; }
这里,我们可以清楚地看到 Spring 完成了对 bean 标签所有属性的解析,这些属性中有很多事是我们经常使用到或者见过的,例如 lazy-init 、 autowire 、 depends-on 、 init-method 、 destroy-method 、 factory-method 等,还有一些不太熟悉或者没有使用过的,如有兴趣可查阅相关资料进行进一步的了解,此不赘述。接下来的文章将对 bean 标签的子元素解析进行分析。
参考
- spring 官方文档 5.2.3.RELEASE:https://docs.spring.io/spring-framework/docs/5.2.3.RELEASE/spring-framework-reference/core.html
- Spring源码深度解析(第2版),郝佳,P44-P72
- 相关注释可参考笔者 github 链接:https://github.com/wpbxin/spring-framework