Controller层的方法访问标志与Spring装配与AspectJ切面处理
最近在做AspectJ实现的日志模块,在spring配置中加入了<aop:aspectj-autoproxy/>,之后发现,只要有用到自定义注解的类,某些方法经MVC请求时就报空指针错误。
【症状】同一个类,该类中某些方法使用了AspectJ处理的自定义注解,结果某些方法访问正常,另一些方法报空指针错误。进一步debug发现autowired的对象为空,即注入失败。去掉<aop:aspectj-autoproxy/>一切正常。
【排查】1、观察问题类中方法的差异,难道说代理类要严格区分某一个RequestMapping、GetMapping、PostMapping?@ResponseBody?经测试,这种理由不存在的。。
2、IDE内运行项目导致?个人用的Eclipse,Tomcat clean,Maven Update Project,问题依旧。
3、用到了多于一个切面处理方式,导致代理过一次的类无法再次代理?我找到了这两篇文章,https://blog.csdn.net/u013803303/article/details/53113102,https://blog.csdn.net/niemingming/article/details/9064487,但也多少受其误导,我们的问题不是一事。
首先,我想要使用的切面类都是AspectJ方式。何况,项目中spring已经达到4.x版本,不应出现spring装配和AspectJ代理二者兼容性的问题。
4、注册的切面类bean有问题?我找到了这篇文章,https://www.cnblogs.com/leiOOlei/p/3713989.html,得知,
--------------------------------------------------------------------------------------------------------------------------------------------------------------------
<context:annotation-config /> ,用于激活那些已经在spring容器里注册过的bean,而且仅能够在已经在已经注册过的bean上面起作用。对于没有在spring容器中注册的bean,它并不能执行任何操作。
<context:component-scan>除了具有
<context:annotation-config />的功能之外,还可以在指定的package下扫描以及注册javabean ,自动将带有@component,@service,@Repository等注解的对象注册到spring容器中。
<context:annotation-config />和 <context:component-scan>同时存在的时候,前者会被忽略。同时哪怕是手动的注册了多个处理器,Spring仍然会尽最大努力避免重复,也就是那些@autowire,@resource等注入注解只会被注入一次。
--------------------------------------------------------------------------------------------------------------------------------------------------------------------
的确,对于在配置中注册的切面类bean,其上的注解@Aspect,并不确定是否被激活了,于是我尝试在spring中加入<context:annotation-config />,问题依旧。
【原因】这是我观察到出现问题的方法,访问标志都是private。查阅资料得知,当Controller中方法为private修饰时,注入bean会失败。
但是,未引入<aop:aspectj-autoproxy/>元素时无此问题,想来这应该是spring 4.x版本装配bean时做的特殊处理。那么当aspectj再来代理时,估计其调用ASM解析时严格限制了访问标志,导致private方法的bean注入全部被忽略,同时public方法正常,也验证了代理是以方法为单位的(而不是类)。
【解决】如此,更改Controller层方法的访问标志为public即可。
【扩展】那么,如果存在多个切面类,如何确定它们执行的顺序呢?简单记忆切面类@order越小越先执行,最先执行的最后结束,详细参考这篇文章 https://blog.csdn.net/hxpjava1/article/details/55504513/,它验证了两个aop通知处理的顺序,其中before是否执行、before与around的先后、around与after的先后、after与afterReturning的先后,都很值得学习。
Controller层的方法访问标志与Spring装配与AspectJ切面处理的更多相关文章
- Spring实战(十二) Spring中注入AspectJ切面
1.Spring AOP与AspectJ Spring AOP与AspectJ相比,是一个功能比较弱的AOP解决方案. AspectJ提供了许多它不能支持的类型切点,如在创建对象时应用通知,构造器切点 ...
- SpringMVC的controller层的方法返回值
1.ModelAndView 既带着数据,又返回视图路劲 2.String 返回试图路径 model带数据 (官方或企业推荐使用此种方式 ,此方法符合解耦思想,即数据,视图,分离 MVC) 3. ...
- PowerMock+SpringMVC整合并测试Controller层方法
PowerMock扩展自Mockito,实现了Mockito不支持的模拟形式的单元测试.PowerMock实现了对静态方法.构造函数.私有方法以及final方法的模拟支持,对静态初始化过程的移除等强大 ...
- Spring AOP:面向切面编程,AspectJ,是基于注解的方法
面向切面编程的术语: 切面(Aspect): 横切关注点(跨越应用程序多个模块的功能)被模块化的特殊对象 通知(Advice): 切面必须要完成的工作 目标(Target): 被通知的对象 代理(Pr ...
- Spring AOP(面向切面示例)
什么是AOP?基本概念切面(aspect):横切关注点被模块化的特殊对象.通知(advice):切面必须要完成的工作.切面中的每个方向称之为通知.通知是在切面对象中的.目标(target):被通知的对 ...
- Spring学习--用 ASpectJ 注解实现 AOP
用 AspectJ 注解声明切面: 要在 Spring 中声明 AspectJ 切面 , 只需要在 IOC 容器中将切面声明为 bean 实例.当在 Spring IOC 容器中初始化 AsjectJ ...
- Spring中的面向切面编程(AOP)简介
一.什么是AOP AOP(Aspect-Oriented Programming, 面向切面编程): 是一种新的方法论, 是对传统 OOP(Object-Oriented Programming, 面 ...
- spring security 在controller层 方法级别使用注解 @PreAuthorize("hasRole('ROLE_xxx')")设置权限拦截 ,无权限则返回403
1.前言 以前学习的时候使用权限的拦截,一般都是对路径进行拦截 ,要么用拦截器设置拦截信息,要么是在配置文件内设置拦截信息, spring security 支持使用注解的形式 ,写在方法和接口上拦截 ...
- Spring框架Controller层(表现层)针对方法参数是Bean时HttpServletRequest绑定参数值问题解释
在做项目的时候,有一个需求是将数据库中的信息封装到实体类返回到jsp界面 传过来的参数只是实体类的id属性,然后根据id属性去查数据库,事情就是这样,然后 结果遇到很奇怪的事情,在jsp页面中使用EL ...
随机推荐
- apache ignite系列(九):ignite调优
1,配置文件调优 1.1 设置页面大小(pagesize) 先查看系统pagesiz,使用PAGE_SIZE或者PAGESIZE # getconf PAGE_SIZE 4096 # getconf ...
- IntelliJ IDEA远程连接tomcat,实现单步调试
web项目部署到tomcat上之后,有时需要打断点单步调试,如果用的是Intellij idea,可以通过如下方法实现: 开启debug端口,启动tomcat 以tomcat7.0.75为例,打开bi ...
- Java 教程(开发环境配置+基础语法)
Java 开发环境配置 在本章节中我们将为大家介绍如何搭建Java开发环境. window系统安装java 下载JDK 首先我们需要下载java开发工具包JDK,下载地址:http://www.ora ...
- [Linux] linux下vim对于意外退出的文档的再次开启
转载自博客:https://blog.csdn.net/ljp1919/article/details/48372615 1.对于同一个文件如果上次已经打开,而未关闭的情况下,又打开该文件进行编辑时, ...
- BASLER Pylon 抓取策略
BASLER Pylon 抓取策略 ( 涛哥工业技术 微信号 TaoRobotics) One by One Grab Strategy 逐个抓取策略 当使用 one by one 抓取模式时,图像按 ...
- 如何更规范化编写Java 代码
如何更规范化编写Java 代码 Many of the happiest people are those who own the least. But are we really so happy ...
- Centos安装PhantomJS
1.下载PhantomJS [root@liuge ~]# wget https://bitbucket.org/ariya/phantomjs/downloads/phantomjs-2.1.1-l ...
- 一个js破解教程
很好的一篇文章,先存着以后用到. 为了防止官网更新修复,存一下版本 https://pan.lanzou.com/b220073/ 密码:这是秘密 这篇文章以 JavaScript 为例讲解了破解的一 ...
- 看完您如果还不明白 Kerberos 原理,算我输!
系统环境 操作系统:CentOS 6 或 CentOS 7 JDK 版本:1.8.0_151 Ambari 版本:2.6.1 HDP 版本:2.6.4.0 扩展链接 Kerberos原理--经典对话 ...
- FILETIME类型到LARGE_INTEGER类型的转换
核心编程第5版 245页到247页的讲到SetWaitableTimer函数的使用 其中提到 FILETIME类型到LARGE_INTEGER类型的转换问题,如下代码 //我们声明的局部变量 HAND ...