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

网友投稿 698 2022-11-18

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

目录SpringAop @Aspect织入不生效,不执行前置增强织入@Before想写一个AOP,主要有2个用意使用@Aspect,@Before不被调用

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

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

第一个用意是做后端的防表单重复提交的token验证。

第二个用意是对后台jsR303 Validator的校验结果做一个统一处理,不想把对校验结果的处理分散在每个controller方法中

@ResponseBody

@RequestMapping(value DLLVebO= "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动态代理设置。

如果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("参数校验切入方法被调DLLVebO用了.....");

//省略

}

}

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

这样就大功告成了。

使用@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.printhttp://ln("arount after");

}

@After("pointcut()")

public void after(){

System.out.println("after");

}

}

调用返回结果:

arount before

before

arount after

after

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:Docker学习笔记——制作容器与容器概念
下一篇:一文掌握Oracle、MySQL、DB2并发控制机制的异同
相关文章

 发表评论

暂时没有评论,来抢沙发吧~