Spring Bean加载流程分析(通过 XML 方式加载)( 十 )
@Nullablepublic AbstractBeanDefinition parseBeanDefinitionElement(Element ele, String beanName, @Nullable BeanDefinition containingBean) {//是否有 class 属性String className = null;if (ele.hasAttribute(CLASS_ATTRIBUTE)) {className = ele.getAttribute(CLASS_ATTRIBUTE).trim();}// 是否有 parent 属性String parent = null;if (ele.hasAttribute(PARENT_ATTRIBUTE)) {parent = ele.getAttribute(PARENT_ATTRIBUTE);}try {// 创建一个 bean 的定义AbstractBeanDefinition bd = createBeanDefinition(className, parent);// 解析 beanDefinitionAttributes 属性 , 包括 init-method, destroy-method 属性等等parseBeanDefinitionAttributes(ele, beanName, containingBean, bd);bd.setDescription(DomUtils.getChildElementValueByTagName(ele, DESCRIPTION_ELEMENT));parseMetaElements(ele, bd);parseLookupOverrideSubElements(ele, bd.getMethodOverrides());parseReplacedMethodSubElements(ele, bd.getMethodOverrides());//解析构造参数parseConstructorArgElements(ele, bd);// 解析属性参数parsePropertyElements(ele, bd);parseQualifierElements(ele, bd);bd.setResource(this.readerContext.getResource());bd.setSource(extractSource(ele));return bd;}//省略部分代码...return null;}复制代码
看看如何创建一个 BeanDefinitionpublic 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) {bd.setBeanClass(ClassUtils.forName(className, classLoader));}else {bd.setBeanClassName(className);}}return bd;}复制代码
首先通过 new 出来了一个 GenericBeanDefinition 对象 , 然后根据是否存在 classLoader 对象来判断是否应该给该对象设置 class 对象或者 className 名称 , 最后将 GenericBeanDefinition 返回 。parseBeanDefinitionAttributes 方法源码如下:
public AbstractBeanDefinition parseBeanDefinitionAttributes(Element ele, String beanName,@Nullable BeanDefinition containingBean, AbstractBeanDefinition bd) {if (ele.hasAttribute(SINGLETON_ATTRIBUTE)) { //是否有 singleton 属性 , 在早前的版本存在 , 2.x 以后就不存在了 , 如果你设置了该属性 , spring 会提示升级成 scope 属性error("Old 1.x 'singleton' attribute in use - upgrade to 'scope' declaration", ele);}else if (ele.hasAttribute(SCOPE_ATTRIBUTE)) { //是否有 scope 属性bd.setScope(ele.getAttribute(SCOPE_ATTRIBUTE));}else if (containingBean != null) {// Take default from containing bean in case of an inner bean definition.bd.setScope(containingBean.getScope());}if (ele.hasAttribute(ABSTRACT_ATTRIBUTE)) {//是否有 abstract 属性bd.setAbstract(TRUE_VALUE.equals(ele.getAttribute(ABSTRACT_ATTRIBUTE)));}String lazyInit = ele.getAttribute(LAZY_INIT_ATTRIBUTE); //是否有 lazy-init 属性if (isDefaultValue(lazyInit)) {lazyInit = this.defaults.getLazyInit();}bd.setLazyInit(TRUE_VALUE.equals(lazyInit));String autowire = ele.getAttribute(AUTOWIRE_ATTRIBUTE); //是否有自动装配属性bd.setAutowireMode(getAutowireMode(autowire));if (ele.hasAttribute(DEPENDS_ON_ATTRIBUTE)) { //是否有 depends-on 属性String dependsOn = ele.getAttribute(DEPENDS_ON_ATTRIBUTE);bd.setDependsOn(StringUtils.tokenizeToStringArray(dependsOn, MULTI_VALUE_ATTRIBUTE_DELIMITERS));}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));}if (ele.hasAttribute(PRIMARY_ATTRIBUTE)) {bd.setPrimary(TRUE_VALUE.equals(ele.getAttribute(PRIMARY_ATTRIBUTE)));}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);}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);}if (ele.hasAttribute(FACTORY_METHOD_ATTRIBUTE)) {bd.setFactoryMethodName(ele.getAttribute(FACTORY_METHOD_ATTRIBUTE));}if (ele.hasAttribute(FACTORY_BEAN_ATTRIBUTE)) {bd.setFactoryBeanName(ele.getAttribute(FACTORY_BEAN_ATTRIBUTE));}return bd;}复制代码
推荐阅读
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- FlinkSQL 动态加载 UDF 实现思路
- 基于Spring+Angular9+MySQL开发平台
- 网络比15年前更慢错误更多?开发者加载了100万个网站实测
- 别不拿GateWay当回事,SpringCloud告诉你错了
- web 安全之 Spring Security 入门教程
- Spring Application实例化流程和构造方法参数
- SpringBoot常用注解
- 阿里爆款SpringBoot项目实战PDF+源码+视频分享
- Firefox 83将默认启用Warp更新:大幅提升响应时间和加载速度
- SpringCloud下skywalking的快速入门