-
2019-03-29 14:12:02更多相关内容
-
aop:aspectj-autoproxy作用
2018-07-08 21:52:48通过配置织入@Aspectj切面虽然可以通过编程的...aop:aspectj-autoproxy />声明自动为spring容器中那些配置@aspectJ切面的bean创建代理,织入切面。当然,spring在内部依旧采用AnnotationAwareAspectJAutoP...通过配置织入@Aspectj切面
虽然可以通过编程的方式织入切面,但是一般情况下,我们还是使用spring的配置自动完成创建代理织入切面的工作。
通过aop命名空间的<aop:aspectj-autoproxy />声明自动为spring容器中那些配置@aspectJ切面的bean创建代理,织入切面。当然,spring
在内部依旧采用AnnotationAwareAspectJAutoProxyCreator进行自动代理的创建工作,但具体实现的细节已经被<aop:aspectj-autoproxy />隐藏起来了
<aop:aspectj-autoproxy />有一个proxy-target-class属性,默认为false,表示使用jdk动态代理织入增强,当配为<aop:aspectj-autoproxy poxy-target-class="true"/>时,表示使用CGLib动态代理技术织入增强。不过即使proxy-target-class设置为false,如果目标类没有声明接口,则spring将自动使用CGLib动态代理。
@AspectJ语法基础
@AspectJ使用jdk5.0注解和正规则的AspectJ 5的切面表达式语言描述切面,由于spring只支持方法的连接点,所以spring仅支持部分aspectJ的切面语言,在这节时,我们将对AspectJ切点表达式语言进行必要的学习。
切点表达式函数
AspectJ 5的切点表达式由关键字和操作参数组成。如execution(*greeTo(..))的切点表达式,"execute"为关键字,而"*greeTo(..)"为操作参数。在这里,execution代表目标类执行某一方法,而"*greeTo(..)"是描述目标方法的匹配模式串,两者联合起来所表示的切点匹配目标类greeTo(..)方法的连接点。为了描述方便,我们将execution()称作函数,而将匹配串"*greeTo(..)"称作函数的入参。
-
aop:aspectj-autoproxy
2021-09-29 17:06:18aop:aspectj-autoproxy 此标签用以开启对于@AspectJ注解风格AOP的支持。 属性 proxy-target-class 你懂的。 expose-proxy 是否应该把代理对象暴露给AopContext,默认false。 栗子 切面 @Aspect public class Aspect...aop:aspectj-autoproxy
此标签用以开启对于@AspectJ注解风格AOP的支持。
属性
proxy-target-class
你懂的。
expose-proxy
是否应该把代理对象暴露给AopContext,默认false。
栗子
切面
@Aspect public class AspectDemo { @Pointcut("execution(void base.aop.AopDemo.send(..))") public void beforeSend() {} @Before("beforeSend()") public void before() { System.out.println("send之前"); } }
被代理类
public class AopDemo implements AopDemoInter { public void send() { System.out.println("send from aopdemo"); } public void receive() { System.out.println("receive from aopdemo"); } @Override public void inter() { System.out.println("inter"); } }
配置
<aop:aspectj-autoproxy proxy-target-class="true" /> <bean class="base.aop.AopDemo" /> <bean class="base.aop.annotation.AspectDemo" />
因为AopDemo实现了AopDemoInter接口,但做实验的send方法又不在此接口里定义,所以只能用cglib的方式代理。
可以看出,即使标注了@Aspect注解,仍然需要将切面自己配置到Spring容器中。
解析
AspectJAutoProxyBeanDefinitionParser.parse:
@Override public BeanDefinition parse(Element element, ParserContext parserContext) { AopNamespaceUtils. registerAspectJAnnotationAutoProxyCreatorIfNecessary(parserContext, element); extendBeanDefinition(element, parserContext); return null; }
注册最终在AopConfigUtils.registerOrEscalateApcAsRequired方法中完成,创建器实际上是一个AnnotationAwareAspectJAutoProxyCreator类的对象,此类是前面AspectJAwareAdvisorAutoProxyCreator的子类。
原理
既然是AspectJAwareAdvisorAutoProxyCreator的子类,那么其代理子类的创建等核心逻辑自然是一样的。这里所需要关注的地方自然是所不一样的地方: 即是如何体现其注解的特性的。
前面说过,AspectJAwareAdvisorAutoProxyCreator通过findCandidateAdvisors方法来找到适用于bean的Advisor,所以注解的特性也是通过重写此方法来体现。
AnnotationAwareAspectJAutoProxyCreator.findCandidateAdvisors:
@Override protected List<Advisor> findCandidateAdvisors() { List<Advisor> advisors = super.findCandidateAdvisors(); //这里 advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors()); return advisors; }
buildAspectJAdvisors方法所做的便是从容器中得到所有的bean,逐一判断是不是一个Aspect。那么判断Aspect的依据是什么?
AbstractAspectJAdvisorFactory.isAspect:
@Override public boolean isAspect(Class<?> clazz) { return (hasAspectAnnotation(clazz) && !compiledByAjc(clazz)); }
至于其它的实现细节不再探究。
总结
Spring对于AspectJ风格AOP的支持停留在外表(注解)上面,内部的实现仍然是自己的东西。
拾遗
AOP切面的坑
- 定义在private方法上的切面不会被执行,这个很容易理解,毕竟子类不能覆盖父类的私有方法。
- 同一个代理子类内部的方法相互调用不会再次执行切面。
这里以Cglib为例对第二点进行说明,cglib的相关核心组件可以参考前面CallbackFilter & Callback部分。对于配置了一个切面的典型场景,Spring内部的执行流程可总结如下图:
核心便是对目标方法的调用上,这里由CglibMethodInvocation的invokeJoinpoint实现:
@Override protected Object invokeJoinpoint() throws Throwable { if (this.publicMethod) { return this.methodProxy.invoke(this.target, this.arguments); } else { return super.invokeJoinpoint(); } }
如果是非public方法,那么Spring将使用反射的方法对其进行调用,因为反射将其可访问性设为true。MethodProxy是Cglib对方法代理的抽象,这里的关键是方法调用的对象(目标)是我们的原生类对象,而不是Cglib代理子类的对象,这就从根本上决定了对同类方法的调用不会再次经过切面。
总结
前面aop:aspectj-autoproxy-属性-expose-proxy一节提到了,Spring允许我们将代理子类暴露出来,可以进行如下配置:
<aop:config expose-proxy="true"> <aop:advisor advice-ref="simpleMethodInterceptor" pointcut="execution(* aop.SimpleAopBean.*(..))" /> </aop:config>
当我们需要在一个被代理方法中调用同类的方法时(此方法也需要经过切面),可以这样调用:
public void testB() { System.out.println("testB执行"); ((SimpleAopBean) AopContext.currentProxy()).testC(); }
这里其实是一个ThreadLocal,当Cglib代理子类创建调用链之间便会将代理类设置到其中,DynamicAdvisedInterceptor.intercept相关源码:
if (this.advised.exposeProxy) { // Make invocation available if necessary. oldProxy = AopContext.setCurrentProxy(proxy); setProxyContext = true; }
-
<aop:aspectj-autoproxy />作用
2020-11-06 17:27:34aop:aspectj-autoproxy />声明自动为spring容器中那些配置@aspectJ切面的bean创建代理,织入切面。当然,spring 在内部依旧采用AnnotationAwareAspectJAutoProxyCreator进行自动代理的创建工作,但具体实现的...通过配置织入@Aspectj切面
虽然可以通过编程的方式织入切面,但是一般情况下,我们还是使用spring的配置自动完成创建代理织入切面的工作。
通过aop命名空间的<aop:aspectj-autoproxy />声明自动为spring容器中那些配置@aspectJ切面的bean创建代理,织入切面。当然,spring
在内部依旧采用AnnotationAwareAspectJAutoProxyCreator进行自动代理的创建工作,但具体实现的细节已经被<aop:aspectj-autoproxy />隐藏起来了
<aop:aspectj-autoproxy />有一个proxy-target-class属性,默认为false,表示使用jdk动态代理织入增强,当配为<aop:aspectj-autoproxy poxy-target-class="true"/>时,表示使用CGLib动态代理技术织入增强。不过即使proxy-target-class设置为false,如果目标类没有声明接口,则spring将自动使用CGLib动态代理。
@AspectJ语法基础
@AspectJ使用jdk5.0注解和正规则的AspectJ 5的切面表达式语言描述切面,由于spring只支持方法的连接点,所以spring仅支持部分aspectJ的切面语言,在这节时,我们将对AspectJ切点表达式语言进行必要的学习。
切点表达式函数
AspectJ 5的切点表达式由关键字和操作参数组成。如execution(*greeTo(..))的切点表达式,"execute"为关键字,而"*greeTo(..)"为操作参数。在这里,execution代表目标类执行某一方法,而"*greeTo(..)"是描述目标方法的匹配模式串,两者联合起来所表示的切点匹配目标类greeTo(..)方法的连接点。为了描述方便,我们将execution()称作函数,而将匹配串"*greeTo(..)"称作函数的入参。
-
<aop:aspectj-autoproxy />的作用
2018-02-11 15:18:23作用:启用注节方式,创建AOP切面。 通过配置织入@Aspectj切面 ...aop:aspectj-autoproxy />声明自动为spring容器中那些配置@aspectJ切面的bean创建代理,织入切面。当然,spr... -
Sping AOP 源码解析(一、动态 AOP 自定义标签 aop:aspectj-autoproxy)
2020-12-29 22:05:29XML 中 AOP 标签的使用 <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop=... -
<aop:aspectj-autoproxy />AOP自动代理
2021-03-21 18:59:27aop:aspectj-autoproxy />作用 通过配置织入@Aspectj切面 虽然可以通过编程的方式织入切面,但是一般情况下,我们还是使用spring的配置自动完成创建代理织入切面的工作。 通过aop命名空间的<aop:aspectj-... -
cvc-complex-type.2.4.c: 通配符的匹配很全面, 但无法找到元素 ‘aop:aspectj-autoproxy‘ 的声明。
2021-11-06 10:02:36cvc-complex-type.2.4.c: 通配符的匹配很全面, 但无法找到元素 ‘aop:aspectj-autoproxy’ 的声明。 at com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper.createSAXParseException... -
Spring:aspectj-autoproxy 简介
2020-01-15 15:02:021.美图 2.概述 Spring:aspectj-autoproxy 简介 未完待续 -
通配符的匹配很全面, 但无法找到元素 ‘aop:aspectj-autoproxy‘ 的声明
2021-08-04 11:32:39aop:aspectj-autoproxy proxy-target-class="true"/> 之后,项目启动报文章标题的错误。 检查原因是忘记引用AOP的文件。 xml文件的 头文件中 <?xml version="1.0" encoding="UTF-8"?> <beans xmlns=... -
元素 “aop:aspectj-autoproxy” 的前缀 “aop” 未绑定
2020-12-31 10:06:27配置spring-mvc.xml,如图 -
无法找到元素 ‘aop:aspectj-autoproxy‘ 的声明
2020-10-10 15:48:38后来通过查询文档发现,我们不仅仅要引入Aop的名称空间,还要在xsi:schemaLocation中加入aop的xsd文件 http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd 这两... -
SpringAop_2通知(新手)和无法找到元素 'aop:aspectj-autoproxy' 的声明
2020-03-05 22:25:13AspectJ:java社区里最完善最流行的AOP框架 在spring2.0以上的版本中,可以使用基于AspectJ注解或基于XML配置的AOP,其实Spring本身提供了aop框架,但是AspectJ更方便. ... -
<aop:aspectj-autoproxy/> 的作用
2017-06-03 08:48:08通过配置织入@Aspectj切面 ...通过aop命名空间的 />声明自动为spring容器中那些配置@aspectJ切面的bean创建代理,织入切面。当然,spring 在内部依旧采用AnnotationAwareAspectJAutoProxyCreator进行自 -
spring基于aspectj的AOP配置 aop:aspectj-autoproxy proxy-target-class="true
2018-09-21 18:15:53<aop:aspectj-autoproxy/> 其中<aop:aspectj-autoproxy/>有一个 proxy-target-class属性,默认为false,表示使用JDK动态代理技术织入增强;当配置为<aop:aspectj-autoproxy proxy-target-class="true"/>时,表示使用... -
无法找到元素 'aop:aspectj-autoproxy' 的声明
2019-11-01 10:14:23通配符的匹配很全面, 但无法找到元素 ‘aop:aspectj-autoproxy’ 的声明。(已解决) 今天博主我在测试Spring Aop时遇到了一个在网上都很少见到的问题,是这样子的,当我执行Spring Aop测试代码时,它抛出了以下异常... -
Spring使用标签aop:aspectj-autoproxy 出的一些错
2019-12-05 23:29:42Spring使用标签aop:aspectj-autoproxy 出的一些错 配置时出现了红色提示 检查后发现是 上图的是已经改好了的,之前因为没有配对好位置,aop没跟aop放一起。导致没加载成功。 改成上图那样后就没有出现红色提示了。... -
Spring源码分析总结(二)-Spring AOP 解析aop:aspectj-autoproxy
2018-04-27 18:53:40Spring AOP当前分析的Spring 版本 5.0 Spring 2.0开始采用@AspectJ注解...aop:aspectj-autoproxy /> 在Spring中自定义的注解和自定义的标签都会在Spring中找到 注册该注解或者标签的对应解析器。一、注册解... -
| org.xml.sax.SAXParseException: 通配符的匹配很全面, 但无法找到元素 ‘aop:aspectj-autoproxy‘ ...
2019-06-06 19:05:08cvc-complex-type.2.4.c: 通配符的匹配很全面, 但无法找到元素 'aop:aspectj-autoproxy' 的声明。 java.lang.IllegalStateException: Failed to load ApplicationContext at org.springframework.test.c -
SpringAOP源码解析之aop:aspectj-autoproxy标签解析
2018-01-11 19:33:04阅读须知文章中使用//单行注释做代码的简单...本文的主要内容是分析Spring AOP配置解析的源码。正文Spring AOP是我们日常开发中经常使用的工具,常被用来做统一的日志、异常处理、监控等功能,使用方法在此不多赘述,有 -
配置Spring AOP aspectj-autoproxy标签源码解析
2018-03-10 19:35:08aop:aspectj-autoproxy /> 此标签有以下两个属性: <aop:aspectj-autoproxy proxy-target-class="false" expose-proxy="false"/> 开启AOP之后:会使用... -
SpringAop源码(六)- 标签aspectj-autoproxy实现分析
2019-11-24 11:03:28目录 1、自定义标签、解析器的加载和调用时机 2、AspectJAutoProxyBeanDefinitionParser 3、总结 1、自定义标签、解析器的加载和调用时机 之前分析过EnableAspectJAutoProxy方式...aop:aspectj-autoproxy p... -
Spring 报错—“通配符的匹配很全面, 但无法找到元素 'aop:aspectj-autoproxy' 的声明”
2019-06-10 20:56:33cvc-complex-type.2.4.c: 通配符的匹配很全面, 但无法找到元素 'aop:aspectj-autoproxy' 的声明。 at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.doLoadBeanDefinitions... -
org.xml.sax.SAXParseException: 通配符的匹配很全面, 但无法找到元素 ‘aop:aspectj-autoproxy‘ 的声明
2020-07-26 18:06:08spring在启动时获取不到引入的外部资源文件获取不到,出现这种情况的原因是在spring.xml配置的头部beans中存在问题,首先需要添加xmlns:aop的命名空间,然后需要在schemaLocation中添加aop的xsd。 xmlns:aop=... -
Spring3 context:component-scan和aop:aspectj-autoproxy联合使用时,无法检测到bean
2019-05-06 09:51:031.项目 package com.cl.aop; import org.aspectj.lang.ProceedingJoinPoint;...import org.aspectj.lang.annotation.After;...import org.aspectj.lang.annotation.After...import org.aspectj.lang.annota... -
[已解决] 通配符的匹配很全面,但无法找到元素 'aop:aspectj-autoproxy' 的声明。
2019-05-17 11:21:32问题背景: 今天在基于注解配置AOP的时候,出现了以下错误: Caused by: org.xml.sax.... cvc-complex-type.2.4.c: 通配符的匹配很全面, 但无法找到元素 'aop:aspectj-autoproxy' 的声明。 就是说applicationContex... -
spring aop:aspectj-autoproxy 配置
2017-03-05 09:50:00经常遇到aop-aspectJ的通知不被执行的问题 解决方法:http://blog.csdn.net/qwdafedv/article/details/53005210 首先,确保配置文件都已经是正确的。 1、首先,把所写的通知所在的类交于spring来管理 <... -
通配符的匹配很全面, 但无法找到元素 'aop:aspectj-autoproxy' 的声明
2019-03-31 22:24:21aop:aspectj-autoproxy proxy-target-class="true"/> 于spring-service.xml中 还是没有拦截到特定类的方法,想了一下,拦截的目标是controller的方法, 所以把<aop:aspectj-autoproxy proxy-target-class=...