千家信息网

SpringAop中如何实现@Aspect织入不生效、不执行前置增强织入@Before

发表于:2025-01-21 作者:千家信息网编辑
千家信息网最后更新 2025年01月21日,这篇文章给大家分享的是有关SpringAop中如何实现@Aspect织入不生效、不执行前置增强织入@Before的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。SpringA
千家信息网最后更新 2025年01月21日SpringAop中如何实现@Aspect织入不生效、不执行前置增强织入@Before

这篇文章给大家分享的是有关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@Componentpublic 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类还未初始化,所以无法正常织入。。

    所以调整如下:

    @Aspectpublic 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,如下:

    这样就大功告成了。

    使用@Aspect,@Before不被调用

    @Aspect@Componentpublic 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@Componentpublic 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

    感谢各位的阅读!关于"SpringAop中如何实现@Aspect织入不生效、不执行前置增强织入@Before"这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,让大家可以学到更多知识,如果觉得文章不错,可以把它分享出去让更多的人看到吧!

    0