spring AOP XML解析
<aop:config> 标签的解析:
<bean id="loggingAspect" class="com.zhuguang.jack.aop.aspect.AspectXml1"></bean>
<aop:config>
<aop:pointcut id="pointcut" expression="execution(* com.zhuguang.jack.aop.aspect.AspectXml1.*(..))" />
<aop:aspect ref="loggingAspect" order="1" >
<aop:before method="before" pointcut-ref="pointcut"/>
<aop:after method="after" pointcut-ref="pointcut"/>
<aop:after-returning method="afterReturning" pointcut-ref="pointcut" returning="result"/>
<aop:after-throwing method="afterThrowing" pointcut-ref="pointcut" throwing="exception"/>
</aop:aspect>
</aop:config>
aop:config对应的类是AspectJAwareAdvisorAutoProxyCreator。加到bean工厂。
aop:aspect 不用解析成类。
aop:before 对应的类是AspectJPointcutAdvisor,里面有AspectJMethodBeforeAdvice,里面有MethodLocatingFactoryBean和SimpleBeanFactoryAwareAspectInstanceFactory和pointcut。加到bean工厂。
aop:after ,aop:after-returning,aop:after-throwing与aop:before类似。 类的属性值就是根据标签上面写的解析出来的。
解析自定义标签就是创建bean的定义,<aop:before,<aop:after,<aop:after-returning,<aop:after-throwing。分别对应AspectJMethodBeforeAdvice.class;AspectJAfterAdvice.class;AspectJAfterReturningAdvice.class;AspectJAfterThrowingAdvice.class;AspectJAroundAdvice.class;
AspectJAwareAdvisorAutoProxyCreator是支持AOP功能的入口类,必定实现BeanPostProcessor接口,bean实例化的时候就回去调用这个类,就会找这个类有没有切面,有切面就生成代理,
首先找到AopNamespaceHandler,然后找到registerBeanDefinitionParser("config", new ConfigBeanDefinitionParser());
public class AopNamespaceHandler extends NamespaceHandlerSupport {
@Override
public void init() {
registerBeanDefinitionParser("config", new ConfigBeanDefinitionParser());
registerBeanDefinitionParser("aspectj-autoproxy", new AspectJAutoProxyBeanDefinitionParser());
registerBeanDefinitionDecorator("scoped-proxy", new ScopedProxyBeanDefinitionDecorator());
registerBeanDefinitionParser("spring-configured", new SpringConfiguredBeanDefinitionParser());
}
}
ConfigBeanDefinitionParser类里面有一个解析标签的方法parse(),
public BeanDefinition parse(Element element, ParserContext parserContext) { //element = [aop:config: null],parserContext = org.springframework.beans.factory.xml.ParserContext@2fd953a6,
CompositeComponentDefinition compositeDef = new CompositeComponentDefinition(element.getTagName(), parserContext.extractSource(element));
parserContext.pushContainingComponent(compositeDef);
configureAutoProxyCreator(parserContext, element); //ParserContext里面有一个属性XmlReaderContext readerContext,BeanDefinitionParserDelegate delegate,解析这个元素就是为了创建BeanDefinition对象,创建AspectJAwareAdvisorAutoProxyCreator的bean定义并且加载到bean工厂。这个类实现了BeanPostProcessor接口,实例化任何一个bean的时候,会调用spring容器中所有BeanPostProcessor接口的类的方法,AspectJAwareAdvisorAutoProxyCreator就会去检测要实例化的这个bean有没有切面,有切面,就帮这个bean生成代理,
List<Element> childElts = DomUtils.getChildElements(element); //[[aop:pointcut], [aop:advisor]]子标签,
for (Element elt: childElts) {
String localName = parserContext.getDelegate().getLocalName(elt); //aop下面就3个标签,
if (POINTCUT.equals(localName)) {
parsePointcut(elt, parserContext);
}
else if (ADVISOR.equals(localName)) {
parseAdvisor(elt, parserContext);
}
else if (ASPECT.equals(localName)) {
parseAspect(elt, parserContext);
}
}
parserContext.popAndRegisterContainingComponent();
return null;
}
private void configureAutoProxyCreator(ParserContext parserContext, Element element) {
AopNamespaceUtils.registerAspectJAutoProxyCreatorIfNecessary(parserContext, element);
}
public static void registerAspectJAutoProxyCreatorIfNecessary(ParserContext parserContext, Element sourceElement) {
BeanDefinition beanDefinition = AopConfigUtils.registerAspectJAutoProxyCreatorIfNecessary(
parserContext.getRegistry(), parserContext.extractSource(sourceElement)); //创建beanDefinition 对象,返回AspectJAwareAdvisorAutoProxyCreator的bean的定义,
useClassProxyingIfNecessary(parserContext.getRegistry(), sourceElement);
registerComponentIfNecessary(beanDefinition, parserContext);
}
public static BeanDefinition registerAspectJAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry, Object source) {
return registerOrEscalateApcAsRequired(AspectJAwareAdvisorAutoProxyCreator.class, registry, source); //注册器是DefaultListableBeanFactory,null,
}
private static BeanDefinition registerOrEscalateApcAsRequired(Class<?> cls, BeanDefinitionRegistry registry, Object source) { //AspectJAwareAdvisorAutoProxyCreator,bean工厂,null,
Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) { //看bean工厂中有没有AspectJAwareAdvisorAutoProxyCreator的实例,名字是internalAutoProxyCreator,有就直接返回,没有就在bean工厂创建AspectJAwareAdvisorAutoProxyCreator的实例,名字叫做internalAutoProxyCreator。
BeanDefinition apcDefinition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME);
if (!cls.getName().equals(apcDefinition.getBeanClassName())) {
int currentPriority = findPriorityForClass(apcDefinition.getBeanClassName());
int requiredPriority = findPriorityForClass(cls);
if (currentPriority < requiredPriority) {
apcDefinition.setBeanClassName(cls.getName());
}
}
return null;
}
RootBeanDefinition beanDefinition = new RootBeanDefinition(cls); //创建AspectJAwareAdvisorAutoProxyCreator的实例
beanDefinition.setSource(source);
beanDefinition.getPropertyValues().add("order", Ordered.HIGHEST_PRECEDENCE);
beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition); //加到bean工厂,名字叫做internalAutoProxyCreator,
return beanDefinition;
}
private static void useClassProxyingIfNecessary(BeanDefinitionRegistry registry, Element sourceElement) {
if (sourceElement != null) {
boolean proxyTargetClass = Boolean.valueOf(sourceElement.getAttribute(PROXY_TARGET_CLASS_ATTRIBUTE)); //获取[aop:config]标签的proxy-target-class="false"属性,true就是cglib的动态代理,faslse就是jdk的动态代理,没有写就是jdk的动态代理,
if (proxyTargetClass) {//true
AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
}
boolean exposeProxy = Boolean.valueOf(sourceElement.getAttribute(EXPOSE_PROXY_ATTRIBUTE)); //sourceElement = [aop:config]标签,
if (exposeProxy) {
AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
}
}
}
public static void forceAutoProxyCreatorToUseClassProxying(BeanDefinitionRegistry registry) {
if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) {
BeanDefinition definition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME);
definition.getPropertyValues().add("proxyTargetClass", Boolean.TRUE); //往internalAutoProxyCreator的bean定义里面加了一个属性,
}
}
private static void registerComponentIfNecessary(BeanDefinition beanDefinition, ParserContext parserContext) { //AspectJAwareAdvisorAutoProxyCreator的bean定义,org.springframework.beans.factory.xml.ParserContext@2fd953a6,
if (beanDefinition != null) {
BeanComponentDefinition componentDefinition = new BeanComponentDefinition(beanDefinition, AopConfigUtils.AUTO_PROXY_CREATOR_BEAN_NAME); //把AspectJAwareAdvisorAutoProxyCreator的bean定义包装成BeanComponentDefinition,包装的名称叫做internalAutoProxyCreator,
parserContext.registerComponent(componentDefinition);
}
}
BeanComponentDefinition extends BeanDefinitionHolder。
BeanDefinition最终会包装成BeanDefinitionHolder,BeanDefinitionHolder有BeanDefinition beanDefinition是bean的定义和String beanName 是bean的名称。
private void parseAspect(Element aspectElement, ParserContext parserContext) { //解析<aop:aspect标签,
String aspectId = aspectElement.getAttribute(ID); //id属性,
String aspectName = aspectElement.getAttribute(REF); //ref是对应的切面类,
try {
this.parseState.push(new AspectEntry(aspectId, aspectName));
List<BeanDefinition> beanDefinitions = new ArrayList<BeanDefinition>();
List<BeanReference> beanReferences = new ArrayList<BeanReference>();
List<Element> declareParents = DomUtils.getChildElementsByTagName(aspectElement, DECLARE_PARENTS);
for (int i = METHOD_INDEX; i < declareParents.size(); i++) {
Element declareParentsElement = declareParents.get(i);
beanDefinitions.add(parseDeclareParents(declareParentsElement, parserContext));
}
NodeList nodeList = aspectElement.getChildNodes();//aspect的子元素,<aop:before,<aop:after,<aop:after-returning,<aop:after-throwing。
boolean adviceFoundAlready = false;
for (int i = 0; i < nodeList.getLength(); i++) {
Node node = nodeList.item(i); //<aop:before,<aop:after,<aop:after-returning,<aop:after-throwing。
if (isAdviceNode(node, parserContext)) {
if (!adviceFoundAlready) {
adviceFoundAlready = true;
beanReferences.add(new RuntimeBeanReference(aspectName));
}
AbstractBeanDefinition advisorDefinition = parseAdvice(aspectName, i, aspectElement, (Element) node, parserContext, beanDefinitions, beanReferences); //解析通知节点<aop:before,<aop:after,<aop:after-returning,<aop:after-throwing标签。目的也是为了创建BeanDefinition。
//返回AspectJPointcutAdvisor的bean定义,constructorArgumentValues属性里面的gebericArgumentValues里面有AspectJMethodBeforeAdvice(现在解析的是aop:before标签)(还有after,around,throw,exception几种)的bean定义里面的constructorArgumentValues属性里面有MethodLocatingFactoryBean的bean定义和SimpleBeanFactoryAwareAspectInstanceFactory的bean定义和pointcut。
beanDefinitions.add(advisorDefinition);//4种前置后置环绕等通知加进去,一个是before标签的bean定义,一个是after的bean定义,一个是afterReturn的bean定义,一个是afterThrow的bean定义。
}
}
//解析aop:aspect标签,就是把里面的aop:before,aop:after,aop:afterthrow,aop:afterRuturnning,这几种标签解析成bean的定义,跟需要加入切面的类还没有建立直接的关系。
AspectComponentDefinition aspectComponentDefinition = createAspectComponentDefinition(
aspectElement, aspectId, beanDefinitions, beanReferences, parserContext);
parserContext.pushContainingComponent(aspectComponentDefinition);
List<Element> pointcuts = DomUtils.getChildElementsByTagName(aspectElement, POINTCUT); //这个<aop:aspect 标签里面的pointcut标签,
for (Element pointcutElement : pointcuts) {
parsePointcut(pointcutElement, parserContext);
}
parserContext.popAndRegisterContainingComponent();
}
finally {
this.parseState.pop();
}
}
private AbstractBeanDefinition parseAdvice(String aspectName, int order, Element aspectElement, Element adviceElement, ParserContext parserContext,List<BeanDefinition> beanDefinitions, List<BeanReference> beanReferences) {//aspectName = aop:aspect标签的ref属性的值,aspectElement = [aop:aspect: null]标签,adviceElement = <aop:before,<aop:after,<aop:after-returning,<aop:after-throwing。
try {
this.parseState.push(new AdviceEntry(parserContext.getDelegate().getLocalName(adviceElement)));
RootBeanDefinition methodDefinition = new RootBeanDefinition(MethodLocatingFactoryBean.class); //创建这个的bean定义,
methodDefinition.getPropertyValues().add("targetBeanName", aspectName);//loggingAspect,切面类名称。
methodDefinition.getPropertyValues().add("methodName", adviceElement.getAttribute("method")); //执行的方法,
methodDefinition.setSynthetic(true);
RootBeanDefinition aspectFactoryDef = new RootBeanDefinition(SimpleBeanFactoryAwareAspectInstanceFactory.class); //创建这个的bean定义,
aspectFactoryDef.getPropertyValues().add("aspectBeanName", aspectName);//loggingAspect,切面类名称。
aspectFactoryDef.setSynthetic(true);
AbstractBeanDefinition adviceDef = createAdviceDefinition(adviceElement, parserContext, aspectName, order, methodDefinition, aspectFactoryDef,beanDefinitions, beanReferences); //返回AspectJMethodBeforeAdvice的bean定义constructorArgumentValues属性里面有MethodLocatingFactoryBean的bean定义和SimpleBeanFactoryAwareAspectInstanceFactory的bean定义和pointcut,前置通知的beanDefinition(<aop:before>标签的beanDefinition)。
// configure the advisor
RootBeanDefinition advisorDefinition = new RootBeanDefinition(AspectJPointcutAdvisor.class); //切面内
advisorDefinition.setSource(parserContext.extractSource(adviceElement)); //[aop:before: null],
advisorDefinition.getConstructorArgumentValues().addGenericArgumentValue(adviceDef); //切面里面必须要有advice,通过构造函数设置值。
if (aspectElement.hasAttribute(ORDER_PROPERTY)) {
advisorDefinition.getPropertyValues().add(ORDER_PROPERTY, aspectElement.getAttribute(ORDER_PROPERTY));
}
// register the final advisor
parserContext.getReaderContext().registerWithGeneratedName(advisorDefinition);
return advisorDefinition;//返回这个切面。AspectJPointcutAdvisor的bean定义,constructorArgumentValues属性里面的gebericArgumentValues属性里面有AspectJMethodBeforeAdvice的bean定义里面的constructorArgumentValues属性里面有MethodLocatingFactoryBean的bean定义和SimpleBeanFactoryAwareAspectInstanceFactory的bean定义和pointcut。
}
finally {
this.parseState.pop();
}
}
private AbstractBeanDefinition createAdviceDefinition(
Element adviceElement, ParserContext parserContext, String aspectName, int order,
RootBeanDefinition methodDef, RootBeanDefinition aspectFactoryDef,
List<BeanDefinition> beanDefinitions, List<BeanReference> beanReferences) { RootBeanDefinition adviceDefinition = new RootBeanDefinition(getAdviceClass(adviceElement, parserContext)); //AspectJMethodBeforeAdvice的bean定义,before的类是AspectJMethodBeforeAdvice,after的类是AspectJAfterAdvice,return的类是AspectJAfterReturningAdvice,afterThrowing的类是AspectJAfterThrowingAdvice,around的类是AspectJAroundAdvice。
adviceDefinition.setSource(parserContext.extractSource(adviceElement)); adviceDefinition.getPropertyValues().add(ASPECT_NAME_PROPERTY, aspectName); //切面类名称
adviceDefinition.getPropertyValues().add(DECLARATION_ORDER_PROPERTY, order); if (adviceElement.hasAttribute(RETURNING)) {//添加属性
adviceDefinition.getPropertyValues().add(
RETURNING_PROPERTY, adviceElement.getAttribute(RETURNING));
}
if (adviceElement.hasAttribute(THROWING)) {//添加属性
adviceDefinition.getPropertyValues().add(
THROWING_PROPERTY, adviceElement.getAttribute(THROWING));
}
if (adviceElement.hasAttribute(ARG_NAMES)) {//添加属性
adviceDefinition.getPropertyValues().add(
ARG_NAMES_PROPERTY, adviceElement.getAttribute(ARG_NAMES));
} ConstructorArgumentValues cav = adviceDefinition.getConstructorArgumentValues(); //构造函数参数。
cav.addIndexedArgumentValue(METHOD_INDEX, methodDef); Object pointcut = parsePointcutProperty(adviceElement, parserContext); //解析pointcut,
if (pointcut instanceof BeanDefinition) {//有pointcut属性,返回bean定义,
cav.addIndexedArgumentValue(POINTCUT_INDEX, pointcut);
beanDefinitions.add((BeanDefinition) pointcut);
}
else if (pointcut instanceof String) {//有pointcut-ref属性,返回字符串,
RuntimeBeanReference pointcutRef = new RuntimeBeanReference((String) pointcut);
cav.addIndexedArgumentValue(POINTCUT_INDEX, pointcutRef);
beanReferences.add(pointcutRef);
} cav.addIndexedArgumentValue(ASPECT_INSTANCE_FACTORY_INDEX, aspectFactoryDef); return adviceDefinition; //返回AspectJMethodBeforeAdvice的bean定义里面有MethodLocatingFactoryBean的bean定义和SimpleBeanFactoryAwareAspectInstanceFactory的bean定义和pointcut。
}
private Class<?> getAdviceClass(Element adviceElement, ParserContext parserContext) {
String elementName = parserContext.getDelegate().getLocalName(adviceElement);
if (BEFORE.equals(elementName)) {//前置通知
return AspectJMethodBeforeAdvice.class;
}
else if (AFTER.equals(elementName)) {//后置通知
return AspectJAfterAdvice.class;
}
else if (AFTER_RETURNING_ELEMENT.equals(elementName)) {//返回通知
return AspectJAfterReturningAdvice.class;
}
else if (AFTER_THROWING_ELEMENT.equals(elementName)) {//异常通知
return AspectJAfterThrowingAdvice.class;
}
else if (AROUND.equals(elementName)) {//环绕通知
return AspectJAroundAdvice.class;
}
}
private Object parsePointcutProperty(Element element, ParserContext parserContext) { //element = aop:before标签,
if (element.hasAttribute(POINTCUT) && element.hasAttribute(POINTCUT_REF)) { //没有pointcut和pointcut-ref属性,直接报错。
parserContext.getReaderContext().error("Cannot define both 'pointcut' and );
return null;
}
else if (element.hasAttribute(POINTCUT)) {
String expression = element.getAttribute(POINTCUT);
AbstractBeanDefinition pointcutDefinition = createPointcutDefinition(expression); //创建AspectJExpressionPointcut的bean定义,
pointcutDefinition.setSource(parserContext.extractSource(element));
return pointcutDefinition;
}
else if (element.hasAttribute(POINTCUT_REF)) {
String pointcutRef = element.getAttribute(POINTCUT_REF);
return pointcutRef;//返回字符串,
}
}
private AspectComponentDefinition createAspectComponentDefinition(
Element aspectElement, String aspectId, List<BeanDefinition> beanDefs,
List<BeanReference> beanRefs, ParserContext parserContext) { BeanDefinition[] beanDefArray = beanDefs.toArray(new BeanDefinition[beanDefs.size()]); //4个前置后置环绕等通知的数组,
BeanReference[] beanRefArray = beanRefs.toArray(new BeanReference[beanRefs.size()]);
Object source = parserContext.extractSource(aspectElement);
return new AspectComponentDefinition(aspectId, beanDefArray, beanRefArray, source);
}
自定义标签都会有一个类与之对应,这个类是spring自己的类,然后加到spring的容器中,跟非自定义标签<bean>的解析类似。
<aop:config>
<aop:pointcut id="pointcut" expression="execution(* com.zhuguang.jack.aop.aspect.AspectXml1.*(..))" />
aop:pointcut 解析成AspectJExpressionPointcut类,aop:config不用解析。 类的属性值就是根据标签上面写的解析出来的。
parsePointcut(elt, parserContext); //[aop:pointcut: null],解析pointcut标签,
private AbstractBeanDefinition parsePointcut(Element pointcutElement, ParserContext parserContext) {
String id = pointcutElement.getAttribute(ID); //pointcut
String expression = pointcutElement.getAttribute(EXPRESSION); //execution(* com.zhuguang.jack.aop.aspect.AspectXml1.*(..)),
AbstractBeanDefinition pointcutDefinition = null;
try {
this.parseState.push(new PointcutEntry(id));
pointcutDefinition = createPointcutDefinition(expression); //AspectJExpressionPointcut的bean定义,里面有point的表达式,
pointcutDefinition.setSource(parserContext.extractSource(pointcutElement)); String pointcutBeanName = id; //pointcut
if (StringUtils.hasText(pointcutBeanName)) {
parserContext.getRegistry().registerBeanDefinition(pointcutBeanName, pointcutDefinition); //加到spring的容器,名字是pointcut,bean定义是AspectJExpressionPointcut的bean定义,
} parserContext.registerComponent(new PointcutComponentDefinition(pointcutBeanName, pointcutDefinition, expression)); //pointcut,AspectJExpressionPointcut的beanDefinition,execution(* com.zhuguang.jack.aop.aspect.AspectXml1.*(..)),加到栈中,
}
finally {
this.parseState.pop();
} return pointcutDefinition; //返回AspectJExpressionPointcut的bean定义,
}
protected AbstractBeanDefinition createPointcutDefinition(String expression) {
RootBeanDefinition beanDefinition = new RootBeanDefinition(AspectJExpressionPointcut.class);
beanDefinition.setScope(BeanDefinition.SCOPE_PROTOTYPE);
beanDefinition.setSynthetic(true);
beanDefinition.getPropertyValues().add(EXPRESSION, expression);
return beanDefinition;
}
<aop:config proxy-target-class="false">
<aop:advisor pointcut-ref="pc" advice-ref="userTxAdvice"/>
</aop:config>
aop:advisor 对应的类是DefaultBeanFactoryPointcutAdvisor,aop:config不用解析,然后解析pointcut-ref属性和 advice-ref属性。最后加到bean容器中去。 类的属性值就是根据标签上面写的解析出来的。
private void parseAdvisor(Element advisorElement, ParserContext parserContext) { //解析Advisor标签
AbstractBeanDefinition advisorDef = createAdvisorBeanDefinition(advisorElement, parserContext); //创建bean定义对象,返回DefaultBeanFactoryPointcutAdvisor的beanDefinition,他的PropertyValues属性 = new RuntimeBeanNameReference(userTxAdvice),userTxAdvice是需要IOC依赖注入的,
String id = advisorElement.getAttribute(ID);
try {
this.parseState.push(new AdvisorEntry(id));
String advisorBeanName = id;
if (StringUtils.hasText(advisorBeanName)) {
parserContext.getRegistry().registerBeanDefinition(advisorBeanName, advisorDef); //advisorDef 加到bean工厂中去,
}
else {
advisorBeanName = parserContext.getReaderContext().registerWithGeneratedName(advisorDef); //自动生成的名字org.springframework.aop.support.DefaultBeanFactoryPointcutAdvisor#0,advisorDef 加到bean工厂中去,
}
Object pointcut = parsePointcutProperty(advisorElement, parserContext); //解析pointcut-ref属性,
if (pointcut instanceof BeanDefinition) {//根据pointcut返回beanDefinition,根据pointcut-ref返回String,
advisorDef.getPropertyValues().add(POINTCUT, pointcut); // 添加pointcut属性,
parserContext.registerComponent(new AdvisorComponentDefinition(advisorBeanName, advisorDef, (BeanDefinition) pointcut));//注册到栈中,
}
else if (pointcut instanceof String) {
advisorDef.getPropertyValues().add(POINTCUT, new RuntimeBeanReference((String) pointcut));//将pointcut-ref转换成RuntimeBeanReference,然后添加pointcut属性,
parserContext.registerComponent(new AdvisorComponentDefinition(advisorBeanName, advisorDef));//注册到栈中,
}
}
}
private AbstractBeanDefinition createAdvisorBeanDefinition(Element advisorElement, ParserContext parserContext) { //[aop:advisor: null]标签,
RootBeanDefinition advisorDefinition = new RootBeanDefinition(DefaultBeanFactoryPointcutAdvisor.class);
advisorDefinition.setSource(parserContext.extractSource(advisorElement));
String adviceRef = advisorElement.getAttribute(ADVICE_REF); //advice-ref属性 = userTxAdvice(ref就是引用,就需要依赖注入)
if (!StringUtils.hasText(adviceRef)) {
parserContext.getReaderContext().error(pshot());
}
else {
advisorDefinition.getPropertyValues().add(ADVICE_BEAN_NAME, new RuntimeBeanNameReference(adviceRef)); //userTxAdvice封装成RuntimeBeanNameReference,ref是引用要依赖注入,当发现依赖注入的类型是RuntimeBeanNameReference的时候,那么就会去通过bean工厂去拿这个对象。
}
if (advisorElement.hasAttribute(ORDER_PROPERTY)) { //排序属性
advisorDefinition.getPropertyValues().add(
ORDER_PROPERTY, advisorElement.getAttribute(ORDER_PROPERTY));
}
return advisorDefinition;//返回DefaultBeanFactoryPointcutAdvisor的beanDefinition,他的PropertyValues属性 = new RuntimeBeanNameReference(userTxAdvice),userTxAdvice是需要IOC依赖注入的,
}
private Object parsePointcutProperty(Element element, ParserContext parserContext) { //element = [aop:advisor: null]标签,
if (element.hasAttribute(POINTCUT) && element.hasAttribute(POINTCUT_REF)) { //是否有pointcut属性
parserContext.getReaderContext().error(ot());
return null;
}
else if (element.hasAttribute(POINTCUT)) { //pointcut属性
// Create a pointcut for the anonymous pc and register it.
String expression = element.getAttribute(POINTCUT);
AbstractBeanDefinition pointcutDefinition = createPointcutDefinition(expression); //AspectJExpressionPointcut的bean定义,
pointcutDefinition.setSource(parserContext.extractSource(element));
return pointcutDefinition;
}
else if (element.hasAttribute(POINTCUT_REF)) { //pointcut-ref属性
String pointcutRef = element.getAttribute(POINTCUT_REF); //string:引用的名字,
if (!StringUtils.hasText(pointcutRef)) {
parserContext.getReaderContext().error(ement, this.parseState.snapshot());
return null;
}
return pointcutRef; //string:引用的名字,
}
}
spring AOP XML解析的更多相关文章
- 这一次搞懂Spring的XML解析原理
前言 Spring已经是我们Java Web开发必不可少的一个框架,其大大简化了我们的开发,提高了开发者的效率.同时,其源码对于开发者来说也是宝藏,从中我们可以学习到非常优秀的设计思想以及优雅的命名规 ...
- Spring的xml解析原理分析【转载】
一:前言 二:spring的配置文件 三:依赖的第三方库.使用技术.代码布局 四:Document实现 五:获取Element的实现 六:解析Element元素 七:Bean创造器 八:Ioc容器的创 ...
- Spring之XML解析
XML解析,我们可以通过我们常用的以下代码作为入口 也许,我们习惯使用第一种加载方式,但是以前也存在 第二种加载,并且这两种加载也有差别,下面再来分析. 先分析 第二种 使用 BeanFactory ...
- spring 5.x 系列第3篇 —— spring AOP (xml配置方式)
文章目录 一.说明 1.1 项目结构说明 1.2 依赖说明 二.spring aop 2.1 创建待切入接口及其实现类 2.2 创建自定义切面类 2.3 配置切面 2.4 测试切面 附: 关于切面表达 ...
- Spring AOP Xml配置过程及解释
目录 Spring AOP(基于xml) 专业术语: 基于xml的声明式AspectJ 具体实践 Spring AOP(基于xml) 目前主流的AOP框架有两个,分别是Spring AOP和Aspec ...
- eclipse导入spring aop xml约束
步骤: 1. 2. 3. 4.取 Location:中最后一个命名:spring-aop-4.2.xsd,放到Key的最后面,Key type:选择 Schema location.点击OK 5.编 ...
- Spring AOP原理解析
原文链接请参见:http://blog.csdn.net/u010723709/article/details/47839307
- spring aop xml中配置实例
http://blog.csdn.net/wangpeng047/article/details/8560694
- 死磕Spring之AOP篇 - Spring AOP注解驱动与XML配置
该系列文章是本人在学习 Spring 的过程中总结下来的,里面涉及到相关源码,可能对读者不太友好,请结合我的源码注释 Spring 源码分析 GitHub 地址 进行阅读. Spring 版本:5.1 ...
随机推荐
- Unity BehaviorDesigner行为树基础总结
BehaviorDesigner——行为树,用于控制和实现AI逻辑,类似于这样: 上面这个行为树实现了这样的逻辑: 当Player有Input时按照Input值来移动,无Input时查找最近的可攻击目 ...
- Python的互斥锁与信号量
并发与锁 a. 多个线程共享数据的时候,如果数据不进行保护,那么可能出现数据不一致现象,使用锁,信号量.条件锁 b. c.互斥锁1. 互斥锁,是使用一把锁把代码保护起来,以牺牲性能换取代码的安全性,那 ...
- Java设计模式:Flyweight(享元)模式
概念定义 享元(Flyweight)模式运用共享技术高效地支持大量细粒度对象的复用. 当系统中存在大量相似或相同的对象时,有可能会造成内存溢出等问题.享元模式尝试重用现有的同类对象,如果未找到匹配的对 ...
- Laravel配置全局公共函数
在Laravel项目中我们常常需要定义一些全局的公共函数,通常我们会将这些公共函数定义在一个单独的文件里,如helpers.php中.我们在app目录下创建一个名为helpers.php的文件(app ...
- \" 转义字符, \a系统警报,逐字字符串(verbatim string)
string str="The key factors are \"focus\" and \"perseverance\""; strin ...
- 接口的 COM 组件调用 QueryInterface 因以下错误而失败: 库没有注册。
这个问题原因是因为安装了高版本的office然后卸载掉,又安装了低版本的office导致的. 博主是 office2016卸载后,安装了office2013. EXCEL报错信息为: 无法将类型为“M ...
- linux下 sort | uniq | wc | less 几个命令的基本用法
sort -f :忽略大小写的差异,例如 A 与 a 视为编码相同: -b :忽略最前面的空格符部分: -M :以月份的名字来排序,例如 JAN, DEC 等等的排序方法: -n :使用『纯数字』进行 ...
- Redis Python(一)
Infi-chu: http://www.cnblogs.com/Infi-chu/ NoSQL(NoSQL=Not Only SQL),中文意思是非关系型数据库. 随着互联网Web2.0网站的兴起, ...
- [20190515]热备份模式与rman冲突.txt
[20190515]热备份模式与rman冲突.txt --//别人的系统做dg时打开热备份模式,忘记关闭,做rman备份时报错.做一个记录.--//实际上也怪自己,实施时没有讲清楚.通过例子说明: 1 ...
- Oracle第二话之调优工具
Oracle第二话之调优工具 原创if 0 = -I can 发布于2019-04-09 19:53:12 阅读数 172 收藏 展开 目录 1.告警日志 2.用户进程trace文件 3.动态性能视 ...