最近在做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切面处理的更多相关文章

  1. Spring实战(十二) Spring中注入AspectJ切面

    1.Spring AOP与AspectJ Spring AOP与AspectJ相比,是一个功能比较弱的AOP解决方案. AspectJ提供了许多它不能支持的类型切点,如在创建对象时应用通知,构造器切点 ...

  2. SpringMVC的controller层的方法返回值

    1.ModelAndView  既带着数据,又返回视图路劲 2.String 返回试图路径  model带数据  (官方或企业推荐使用此种方式 ,此方法符合解耦思想,即数据,视图,分离 MVC) 3. ...

  3. PowerMock+SpringMVC整合并测试Controller层方法

    PowerMock扩展自Mockito,实现了Mockito不支持的模拟形式的单元测试.PowerMock实现了对静态方法.构造函数.私有方法以及final方法的模拟支持,对静态初始化过程的移除等强大 ...

  4. Spring AOP:面向切面编程,AspectJ,是基于注解的方法

    面向切面编程的术语: 切面(Aspect): 横切关注点(跨越应用程序多个模块的功能)被模块化的特殊对象 通知(Advice): 切面必须要完成的工作 目标(Target): 被通知的对象 代理(Pr ...

  5. Spring AOP(面向切面示例)

    什么是AOP?基本概念切面(aspect):横切关注点被模块化的特殊对象.通知(advice):切面必须要完成的工作.切面中的每个方向称之为通知.通知是在切面对象中的.目标(target):被通知的对 ...

  6. Spring学习--用 ASpectJ 注解实现 AOP

    用 AspectJ 注解声明切面: 要在 Spring 中声明 AspectJ 切面 , 只需要在 IOC 容器中将切面声明为 bean 实例.当在 Spring IOC 容器中初始化 AsjectJ ...

  7. Spring中的面向切面编程(AOP)简介

    一.什么是AOP AOP(Aspect-Oriented Programming, 面向切面编程): 是一种新的方法论, 是对传统 OOP(Object-Oriented Programming, 面 ...

  8. spring security 在controller层 方法级别使用注解 @PreAuthorize("hasRole('ROLE_xxx')")设置权限拦截 ,无权限则返回403

    1.前言 以前学习的时候使用权限的拦截,一般都是对路径进行拦截 ,要么用拦截器设置拦截信息,要么是在配置文件内设置拦截信息, spring security 支持使用注解的形式 ,写在方法和接口上拦截 ...

  9. Spring框架Controller层(表现层)针对方法参数是Bean时HttpServletRequest绑定参数值问题解释

    在做项目的时候,有一个需求是将数据库中的信息封装到实体类返回到jsp界面 传过来的参数只是实体类的id属性,然后根据id属性去查数据库,事情就是这样,然后 结果遇到很奇怪的事情,在jsp页面中使用EL ...

随机推荐

  1. apache ignite系列(九):ignite调优

    1,配置文件调优 1.1 设置页面大小(pagesize) 先查看系统pagesiz,使用PAGE_SIZE或者PAGESIZE # getconf PAGE_SIZE 4096 # getconf ...

  2. IntelliJ IDEA远程连接tomcat,实现单步调试

    web项目部署到tomcat上之后,有时需要打断点单步调试,如果用的是Intellij idea,可以通过如下方法实现: 开启debug端口,启动tomcat 以tomcat7.0.75为例,打开bi ...

  3. Java 教程(开发环境配置+基础语法)

    Java 开发环境配置 在本章节中我们将为大家介绍如何搭建Java开发环境. window系统安装java 下载JDK 首先我们需要下载java开发工具包JDK,下载地址:http://www.ora ...

  4. [Linux] linux下vim对于意外退出的文档的再次开启

    转载自博客:https://blog.csdn.net/ljp1919/article/details/48372615 1.对于同一个文件如果上次已经打开,而未关闭的情况下,又打开该文件进行编辑时, ...

  5. BASLER Pylon 抓取策略

    BASLER Pylon 抓取策略 ( 涛哥工业技术 微信号 TaoRobotics) One by One Grab Strategy 逐个抓取策略 当使用 one by one 抓取模式时,图像按 ...

  6. 如何更规范化编写Java 代码

    如何更规范化编写Java 代码 Many of the happiest people are those who own the least. But are we really so happy ...

  7. Centos安装PhantomJS

    1.下载PhantomJS [root@liuge ~]# wget https://bitbucket.org/ariya/phantomjs/downloads/phantomjs-2.1.1-l ...

  8. 一个js破解教程

    很好的一篇文章,先存着以后用到. 为了防止官网更新修复,存一下版本 https://pan.lanzou.com/b220073/ 密码:这是秘密 这篇文章以 JavaScript 为例讲解了破解的一 ...

  9. 看完您如果还不明白 Kerberos 原理,算我输!

    系统环境 操作系统:CentOS 6 或 CentOS 7 JDK 版本:1.8.0_151 Ambari 版本:2.6.1 HDP 版本:2.6.4.0 扩展链接 Kerberos原理--经典对话 ...

  10. FILETIME类型到LARGE_INTEGER类型的转换

    核心编程第5版 245页到247页的讲到SetWaitableTimer函数的使用 其中提到 FILETIME类型到LARGE_INTEGER类型的转换问题,如下代码 //我们声明的局部变量 HAND ...