您的位置:首页 > 编程语言 > Java开发

spring-aop源码解析:declare-parent

2015-09-13 14:05 736 查看
spring-aop源码解析:declare-parent

借助Aop的引入,我们可以不侵入性的改变现有的实现,对现有实现类无侵入性的增加方法。

1、举个例子:Einstein从小爱发明,是个发明家,我们创建一个Einstein类,实现发明家(Inventor)接口。随着知识的积累,Einstein也成为了数学家,我们可以在不改变Eistein类的前提下使用declare-parent为Eistein添加数学家的特性。
package com.zhc.aop.declareparent;

public interface Inventor {
public void invent();
}


package com.zhc.aop.declareparent;

public class Einstein implements Inventor {

@Override
public void invent() {
// TODO Auto-generated method stub
System.out.println("create new thing");
}

}


package com.zhc.aop.declareparent;

public interface Mathematician {
public void calculate();
}


package com.zhc.aop.declareparent;

public class MathematicianImpl implements Mathematician {

@Override
public void calculate() {
System.out.println("calculate the result of the formulae");
}

}


spring-aop.xml配置declare-parent,为Einstein添加特性
<bean id="Einstein" class="com.zhc.aop.declareparent.Einstein"></bean>
<aop:config>
<aop:aspect>
<aop:declare-parents types-matching="com.zhc.aop.declareparent.Einstein"
implement-interface="com.zhc.aop.declareparent.Mathematician"
default-impl="com.zhc.aop.declareparent.MathematicianImpl"/>
</aop:aspect>
</aop:config>


测试类:
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class DeclareParentTest {
@Test
public void testEinstein(){
String xml = "classpath:spring-aop.xml";
ApplicationContext context = new ClassPathXmlApplicationContext(new String[] { xml });
Inventor inventor = (Inventor) context.getBean("Einstein");
inventor.invent();
Mathematician mathematician = (Mathematician) context.getBean("Einstein");
mathematician.calculate();
}
}


2、源码分析

ConfigBeanDefinitionParser同过parseDeclareParents方法来解析declare-parents 标签
/**
* Parse a '<code>declare-parents</code>' element and register the appropriate
* DeclareParentsAdvisor with the BeanDefinitionRegistry encapsulated in the
* supplied ParserContext.
* 解析一个declare-parents标签,并且使用BeanDefinitionRegistry注册一个合适的DeclareParentsAdvisor
* BeanDefinitionRegistry封装在了parserContext中
*/
private AbstractBeanDefinition parseDeclareParents(Element declareParentsElement, ParserContext parserContext) {
//BeanDefinition是由BeanDefinitionBuilder创建的,在builder创建BeanDefinition之前,
//要设置根bean定义(rootBeanDefinition),它指定了bean的Class
//declare-parents标签内部实现方式是创建了一个切面
BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(DeclareParentsAdvisor.class);
//添加构造函数的参数
//这里的构造函数是指DeclareParentsAdvisor的构造函数
builder.addConstructorArgValue(declareParentsElement.getAttribute(IMPLEMENT_INTERFACE));//新加的接口
builder.addConstructorArgValue(declareParentsElement.getAttribute(TYPE_PATTERN));//类型匹配表达式

String defaultImpl = declareParentsElement.getAttribute(DEFAULT_IMPL);//新加接口的默认实现
String delegateRef = declareParentsElement.getAttribute(DELEGATE_REF);//新加接口的实现引用

//新接口实现类和实现引用指定一个即可,且只能指定一个
if (StringUtils.hasText(defaultImpl) && !StringUtils.hasText(delegateRef)) {
builder.addConstructorArgValue(defaultImpl);
}
else if (StringUtils.hasText(delegateRef) && !StringUtils.hasText(defaultImpl)) {
builder.addConstructorArgReference(delegateRef);
}
else {
parserContext.getReaderContext().error(
"Exactly one of the " + DEFAULT_IMPL + " or " + DELEGATE_REF + " attributes must be specified",
declareParentsElement, this.parseState.snapshot());
}

//获取bean定义
AbstractBeanDefinition definition = builder.getBeanDefinition();
definition.setSource(parserContext.extractSource(declareParentsElement));
//注册bean定义
parserContext.getReaderContext().registerWithGeneratedName(definition);
return definition;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: