最近在做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. 从零开始入门 K8s| 阿里技术专家详解 K8s 核心概念

    作者| 阿里巴巴资深技术专家.CNCF 9个 TCO 之一 李响 一.什么是 Kubernetes Kubernetes,从官方网站上可以看到,它是一个工业级的容器编排平台.Kubernetes 这个 ...

  2. Linux下Eclipse以及Java环境安装教程[小白化](2019-9)

    Linux下安装Eclipse以及Java 一.前言 许久未用Eclipse, Ubuntu上也没装Eclipse, 今天安装发现, 好多东西都忘了. 不过经过一番查找(百度, csdn) 终于还是安 ...

  3. NPOI导出数值格式设置(我是保留四位小数,不足补0)

    看了网上好多帖子,都是保留两位小数的,写法是: HSSFDataFormat.GetBuiltinFormat("0.00"); 于是想四位小数,就是多加两个00,变成: HSSF ...

  4. [Scikit-learn] 4.3 Preprocessing data

    数据分析的重难点,就这么来了,欢迎欢迎,热烈欢迎. 4. Dataset transformations 4.3. Preprocessing data 4.3.1. Standardization, ...

  5. seo搜索引擎的优化方法

    现在互联网的入口,一般都是被搜索引擎霸占.所以我们要想让别人搜索时,优先看到我们的网站.有两种方法: 1.竞价排名.这是需要钱的,给的钱越多,排名越靠前.参考某度.. 2.不想花钱,就使用seo搜索引 ...

  6. 使用express框架创建服务器

    上一篇写创建第一个node服务器是基于原始方法写的,express框架的作用就是省掉那些原始代码,直接调用相关的方法就可以了,开发起来简单方便. 一.package.json的配置 首先要进行pack ...

  7. python2.x和python3.x版本共存时选择启动的版本

    在windows环境下装好python2.7和python3.6之后,我之前一直是用了很笨的办法去区分版本 那就是把各个版本python安装目录下的python.exe分别改为python2.exe和 ...

  8. Jetpack系列:LiveData入门级使用方法

    Android APP开发中,开发者们都想有一个公共的组件,可以实现后台数据的监听,同时实时更新到UI进行显示,从而大大简化开发过程.Google针对这一开发需求,提供了Jetpack LiveDat ...

  9. Spring 梳理 - View - JSON and XML View

    实际案例json <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www. ...

  10. (三)分布式数据库tidb-隔离级别详解

    tidb隔离级别详解: 1.TiDB 支持的隔离级别是 Snapshot Isolation(SI),它和 Repeatable Read(RR) 隔离级别基本等价,详细情况如下: ● TiDB 的 ...