SpringAop @Aspect织入不生效,不执行前置增强织入@Before方式

 更新时间:2021年12月02日 10:09:05   作者:苦作舟  
这篇文章主要介绍了SpringAop @Aspect织入不生效,不执行前置增强织入@Before方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

SpringAop @Aspect织入不生效,不执行前置增强织入@Before

想写一个AOP,主要有2个用意

  • 第一个用意是做后端的防表单重复提交的token验证。
  • 第二个用意是对后台JSR303 Validator的校验结果做一个统一处理,不想把对校验结果的处理分散在每个controller方法中
@ResponseBody
	@RequestMapping(value = "add", method = RequestMethod.POST)
	public ResponseModel add(@Valid User user, BindingResult br, HttpServletResponse response) {
		
		if(br.hasErrors()) {
			return ResponseModel.validFail(getErrorsSplitNewLine(br));
		}
		accountService.addUser(user);
		return ResponseModel.success("保存用户成功");
	}

如上面方法中, br.hasErrors() 在每个表单提交方法中都存在,想单独抽出来使用AOP统一处理。

所以写一个AOP,如下:

@Aspect
@Component
public class ParamValidAspect {
    @Before("@annotation(com.hebao.tech.adm.framework.annotation.ParamValid)")
    public void paramValid(JoinPoint point) {
	System.out.println("参数校验切入方法被调用了.....");
        //省略
    } 
}

由于这篇文章主要是记录AOP不生效的原因,所以,这里不写具体实现了。

上面的内容定义一个Aop织入,在有注解@ParamValid的注释Controller方法上织入。

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
 
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface ParamValid {
 
}

这个ParamValid的内容,仅仅是一个标志性的注解,声明为方法层的注解,并且是运行时注解。

最后在application.xml中加入AOP动态代理设置。

<!-- 这个配置要配置在component-scan以后 -->
<aop:aspectj-autoproxy proxy-target-class="true" />

如果spring配置文件没引入过aop的配置,还需要在加入xml声明

大功告成,测试了一下,发现有点悲剧,根本织入不生效,也不报错,,楞是不执行相关的织入代码。

最后在网上搜了一下,发现Spring与SpringMVC是2个不同的父子容器, @Aspect如果被spring容器加载的话,而@Controller注解的这些类的实例化以及注入却是由SpringMVC来完成。 @Aspect如果被spring容器加载的时候,可能Spring MVC容器还未初始化, Controller类还未初始化,所以无法正常织入。。

所以调整如下:

@Aspect
public class ParamValidAspect {
    @Before("@annotation(com.hebao.tech.adm.framework.annotation.ParamValid)")
    public void paramValid(JoinPoint point) {
 System.out.println("参数校验切入方法被调用了.....");
        //省略
    } 
}

去掉@Component注解,然后把 aop:aspectj-autoproxy 移入springmvc配置文件中,并定义bean,如下:

<!-- 这个配置一定要配置在component-scan以后 -->
<aop:aspectj-autoproxy proxy-target-class="true" />
<bean id="paramValidAspect" class="com.hebao.tech.adm.framework.spring.aop.ParamValidAspect"/>

这样就大功告成了。

使用@Aspect,@Before不被调用

@Aspect
@Component
public class LogAspect {
    @Before("pointcut()")
    public void before(){
        System.out.println("before");
    }
 
    @Pointcut("@annotation(com.demo.annotation.Log)")
    public void pointcut(){     
    } 
 
    @Around("pointcut()")
    public void around(){
        System.out.println("arount");
    }
 
    @After("pointcut()")
    public void after(){
        System.out.println("after"); 
    }
}

调用方法返回结果:

arount

after

@Aspect
@Component
public class LogAspect {
    @Before("pointcut()")
    public void before(){
        System.out.println("before");
    }
 
    @Pointcut("@annotation(com.mxy.annotation.Log)")
    public void pointcut(){
        
    } 
 
    @Around("pointcut()")
    public void around(ProceedingJoinPoint point){
        System.out.println("arount before");
 
        try {
            point.proceed();
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }
        System.out.println("arount after");
    } 
 
    @After("pointcut()")
    public void after(){
        System.out.println("after"); 
    }
}

调用返回结果:

arount before

before

arount after

after

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • Java分布式session存储解决方案图解

    Java分布式session存储解决方案图解

    这篇文章主要介绍了Java分布式session存储解决方案图解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-07-07
  • 深入理解Java中线程间的通信

    深入理解Java中线程间的通信

    一般来讲,线程内部有自己私有的线程上下文,互不干扰。但是当我们需要多个线程之间相互协作的时候,就需要我们掌握Java线程的通信方式。本文将介绍Java线程之间的几种通信原理,需要的可以参考一下
    2022-11-11
  • CommonMark 使用教程:将 Markdown 语法转成 Html

    CommonMark 使用教程:将 Markdown 语法转成 Html

    这篇文章主要介绍了CommonMark 使用教程:将 Markdown 语法转成 Html,这个技巧我们做任何网站都可以用到,而且非常好用。,需要的朋友可以参考下
    2019-06-06
  • Java monitor机制使用方法解析

    Java monitor机制使用方法解析

    这篇文章主要介绍了Java monitor机制使用方法解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-09-09
  • Java class文件格式之属性_动力节点Java学院整理

    Java class文件格式之属性_动力节点Java学院整理

    在本文中, 主要讲解了class文件中的一些属性。 这些属性可以出现在class文件中的对个地方, 用来描述一些其他信息
    2017-06-06
  • java开放地址法和链地址法解决hash冲突的方法示例

    java开放地址法和链地址法解决hash冲突的方法示例

    这篇文章主要介绍了java开放地址法和链地址法解决hash冲突的方法示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-12-12
  • 微信支付java版本之查询订单

    微信支付java版本之查询订单

    这篇文章主要为大家详细介绍了微信支付java版本之查询订单,为大家分享了微信支付订单的查询接口,感兴趣的小伙伴们可以参考一下
    2016-08-08
  • Spring中实例化bean的四种方式详解

    Spring中实例化bean的四种方式详解

    这篇文章主要给大家介绍了关于Spring中实例化bean的四种方式,分别是setter 方法、构造函数、静态工厂以及实例工厂等四种方法,分别给出了示例代码供大家参考学习,需要的朋友们下面随着小编来一起学习学习吧。
    2017-12-12
  • Spring Boot如何获取maven打包时间

    Spring Boot如何获取maven打包时间

    这篇文章主要介绍了Spring Boot如何获取maven打包时间,首先引入maven打包插件,本文分步骤给大家介绍的非常详细,需要的朋友参考下吧
    2024-03-03
  • MyBatis实现自定义MyBatis插件的流程详解

    MyBatis实现自定义MyBatis插件的流程详解

    MyBatis的一个重要的特点就是插件机制,使得MyBatis的具备较强的扩展性,我们可以根据MyBatis的插件机制实现自己的个性化业务需求,本文给大家介绍了MyBatis实现自定义MyBatis插件的流程,需要的朋友可以参考下
    2024-12-12

最新评论