您好,登錄后才能下訂單哦!
這篇文章給大家分享的是有關SpringAop中如何實現@Aspect織入不生效、不執行前置增強織入@Before的內容。小編覺得挺實用的,因此分享給大家做個參考,一起跟隨小編過來看看吧。
第一個用意是做后端的防表單重復提交的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 @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
感謝各位的閱讀!關于“SpringAop中如何實現@Aspect織入不生效、不執行前置增強織入@Before”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,讓大家可以學到更多知識,如果覺得文章不錯,可以把它分享出去讓更多的人看到吧!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。