示例程序:
public class BeanFactoryTest {
@SuppressWarnings(value={"deprecation"})
public static void main(String[] args) {
BeanFactory beanFactory = new XmlBeanFactory(new ClassPathResource("spring-bf.xml"));
Object a = beanFactory.getBean("componentA");
Object b = beanFactory.getBean("componentB");
System.out.println(a);
System.out.println(b);
}
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="componentA" class="com.wz.spring.xml.ComponentA"/>
<bean id="componentB" class="com.wz.spring.xml.ComponentB"/>
</beans>
1.核心流程
public XmlBeanFactory(Resource resource, BeanFactory parentBeanFactory) throws BeansException {
super(parentBeanFactory);
this.reader.loadBeanDefinitions(resource);
}
这里reader是:
private final XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(this);
实际加载BeanDefinition是在:
doLoadBeanDefinitions(inputSource, encodedResource.getResource());
这里核心流程就两步:
- step1.将xml解析成Document
- step2.解析并注册BeanDefinition
protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource)
throws BeanDefinitionStoreException {
try {
Document doc = doLoadDocument(inputSource, resource);
int count = registerBeanDefinitions(doc, resource);
if (logger.isDebugEnabled()) {
logger.debug("Loaded " + count + " bean definitions from " + resource);
}
return count;
}
2.BeanDefinitionDocumentReader解析并注册BeanDefinition
核心是BeanDefinitionDocumentReader,会在DefaultBeanDefinitionDocumentReader#doRegisterBeanDefinitions进行解析处理。
protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) {
// 条件成立:说明root是spring命名空间
if (delegate.isDefaultNamespace(root)) {
// <beans>
// <bean> ... </bean>
// <bean> ... </bean>
// </beans>
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;
// 子标签也是spring默认标签
if (delegate.isDefaultNamespace(ele)) {
parseDefaultElement(ele, delegate);
}
else {
delegate.parseCustomElement(ele);
}
}
}
}
else {
// 解析自定义标签
delegate.parseCustomElement(root);
}
}
private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) {
// import标签
if (delegate.nodeNameEquals(ele, IMPORT_ELEMENT)) {
importBeanDefinitionResource(ele);
}
// alias标签
else if (delegate.nodeNameEquals(ele, ALIAS_ELEMENT)) {
processAliasRegistration(ele);
}
// bean标签
else if (delegate.nodeNameEquals(ele, BEAN_ELEMENT)) {
processBeanDefinition(ele, delegate);
}
// 嵌套beans标签
else if (delegate.nodeNameEquals(ele, NESTED_BEANS_ELEMENT)) {
// recurse
doRegisterBeanDefinitions(ele);
}
}
import标签示例:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.Springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<import resource="application-business1.xml"/>
<import resource="application-business2.xml"/>
<import resource="application-business3.xml"/>
...
</beans>
alias标签示例:
<bean id="testBean" class="xx.xx.xx.xxBean"/>
1.要给这个JavaBean增加别名,以方便使用时,我们可以直接使用bean标签中的name属性:
<bean id="testBean" name="testBean,testBean2" class="xx.xx.xx.xxBean"/>
2.Spring还提供了 另外一种声明别名的方式:
<bean id="testBean" class="xx.xx.xx.xxBean"/>
<alias name="testBean" alias="testBean,testBean2"/>
处理bean标签:
protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
// 这里处理了bean名字以及解析AbstractBeanDefinition
BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
if (bdHolder != null) {
// 这里进行装饰,主要处理自定义属性
bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
try {
// Register the final decorated instance.
// 将bd注册到容器里面
BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());
}
catch (BeanDefinitionStoreException ex) {
getReaderContext().error("Failed to register bean definition with name '" +
bdHolder.getBeanName() + "'", ele, ex);
}
// Send registration event.
// 发布注册完成事件
getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
}
}
BeanDefinitionParserDelegate#parseBeanDefinitionElement的方法:
- 1)将name拆分成数组,作为别名
- 2)id没有值且别名不为空,则将别名第一个名字作为beanName
- 3)解析AbstractBeanDefinition
- 4)如果beanName为空,会生成一个beanName:className#序列号
- 5)如果className没有使用,则加一个别名为className别名
注意别名的注册,是放在aliasMap中ConcurrentHashMap,key - alias,value - beanName。
核心在重载方法BeanDefinitionParserDelegate#parseBeanDefinitionElement()处理BeanDefinition:
public AbstractBeanDefinition parseBeanDefinitionElement(
Element ele, String beanName, @Nullable BeanDefinition containingBean) {
this.parseState.push(new BeanEntry(beanName));
String className = null;
// 读取bean标签的className,除非从parent标签继承
if (ele.hasAttribute(CLASS_ATTRIBUTE)) {
className = ele.getAttribute(CLASS_ATTRIBUTE).trim();
}
String parent = null;
// parent标签
if (ele.hasAttribute(PARENT_ATTRIBUTE)) {
parent = ele.getAttribute(PARENT_ATTRIBUTE);
}
try {
// 创建bd对象,设置beanClass或者beanClassName
AbstractBeanDefinition bd = createBeanDefinition(className, parent);
// 解析attribute信息:scope、lazy-init、init-method、depends-on等
parseBeanDefinitionAttributes(ele, beanName, containingBean, bd);
// description
bd.setDescription(DomUtils.getChildElementValueByTagName(ele, DESCRIPTION_ELEMENT));
// meta
parseMetaElements(ele, bd);
// lookup-method
parseLookupOverrideSubElements(ele, bd.getMethodOverrides());
// replaced-method
parseReplacedMethodSubElements(ele, bd.getMethodOverrides());
// 解析constructor-arg子元素
parseConstructorArgElements(ele, bd);
// 解析property子元素
parsePropertyElements(ele, bd);
// 解析qualifier子元素
parseQualifierElements(ele, bd);
bd.setResource(this.readerContext.getResource());
bd.setSource(extractSource(ele));
return bd;
}
注意property或者constructor-arg解析时:
- 1)ref和value不能同时存在
- 2)ref或value有一个存在时,就不能有子元素subElement
正好对应Bean的xml配置:
<bean id="xxxComponent" name="xxxComponent" class="xx.xx.xx.xxxComponent">
<meta key="meta_1" value="meta_val_1"/>
<meta key="meta_2" value="meta_val_2"/>
...
<property name="key1" value="value1"/>
<property name="key2" value="value2"/>
...
<constructor-arg index="0">
<value>aaa</value>
</constructor-arg>
<constructor-arg index="1">
<value>bbb</value>
</constructor-arg>
<constructor-arg index="2">
<map>
<entry key="key" value="value">
...
</map>
</constructor-arg>
</bean>
重点来看看BeanDefinitionParserDelegate#parseBeanDefinitionAttributes
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为true,表示是一个抽象bean,只能让子bean去继承
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设置为false后,当前bean不能参与其余bean的自动依赖注入。默认是true。
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,依赖注入有多个候选对象,选择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;
}
网友评论