本文主要是介绍IOC 之解析 bean 标签:BeanDefinition,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
BeanDefinition 是一个接口,它描述了一个 Bean 实例,包括属性值、构造方法值和继承自它的类的更多信息。它继承 AttributeAccessor 和 BeanMetadataElement 接口。两个接口定义如下:
- AttributeAccessor :定义了与其它对象的(元数据)进行连接和访问的约定,即对属性的修改,包括获取、设置、删除。
- BeanMetadataElement:Bean 元对象持有的配置元素可以通过getSource() 方法来获取。
我们常用的三个实现类有:ChildBeanDefinition、GenericBeanDefinition、RootBeanDefinition,三者都继承 AbstractBeanDefinition。如果配置文件中定义了父 <bean> 和 子 <bean> ,则父 <bean> 用 RootBeanDefinition表示,子 <bean> 用 ChildBeanDefinition 表示,而没有父 <bean> 的就使用RootBeanDefinition 表示。GenericBeanDefinition 为一站式服务类。AbstractBeanDefinition对三个子类共同的类信息进行抽象。
解析 Bean 标签
在 BeanDefinitionParserDelegate.parseBeanDefinitionElement() 中完成 Bean 的解析,返回的是一个已经完成对 <bean> 标签解析的 BeanDefinition 实例。在该方法内部,首先调用 createBeanDefinition() 方法创建一个用于承载属性的 GenericBeanDefinition 实例,如下:
1 2 3 4 5 | protected AbstractBeanDefinition createBeanDefinition( @Nullable String className, @Nullable String parentName) throws ClassNotFoundException { return BeanDefinitionReaderUtils.createBeanDefinition( parentName, className, this .readerContext.getBeanClassLoader()); } |
委托 BeanDefinitionReaderUtils 创建,如下:
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 | 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 ) { bd.setBeanClass(ClassUtils.forName(className, classLoader)); } else { bd.setBeanClassName(className); } } return bd; } |
该方法主要是设置 parentName 、className、classLoader。 创建完 GenericBeanDefinition 实例后,再调用 parseBeanDefinitionAttributes() ,该方法将创建好的 GenericBeanDefinition 实例当做参数,对 Bean 标签的所有属性进行解析,如下:
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 | public AbstractBeanDefinition parseBeanDefinitionAttributes(Element ele, String beanName, @Nullable BeanDefinition containingBean, AbstractBeanDefinition bd) { // 解析 scope 标签 if (ele.hasAttribute(SINGLETON_ATTRIBUTE)) { error( "Old 1.x 'singleton' attribute in use - upgrade to 'scope' declaration" , ele); } 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. 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 (DEFAULT_VALUE.equals(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 ( "" .equals(autowireCandidate) || DEFAULT_VALUE.equals(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)); } // 解析 primay 标签 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-mothod 标签 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)); } if (ele.hasAttribute(FACTORY_BEAN_ATTRIBUTE)) { bd.setFactoryBeanName(ele.getAttribute(FACTORY_BEAN_ATTRIBUTE)); } return bd; } |
从上面代码我们可以清晰地看到对 Bean 标签属性的解析,这些属性我们在工作中都或多或少用到过。 完成 Bean 标签基本属性解析后,会依次调用 parseMetaElements()、parseLookupOverrideSubElements()、parseReplacedMethodSubElements() 对子元素 meta、lookup-method、replace-method 完成解析。
更多Java学习资料可关注:gzitcast获取
这篇关于IOC 之解析 bean 标签:BeanDefinition的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!