Spring AOP @Aspect織入不生效,不執行前置增強織入@Before
阿新 • • 發佈:2018-12-31
想寫一個AOP,主要有2個用意,,
第一個用意是做後端的防表單重複提交的token驗證。
第二個用意是對後臺JSR303 Validator的校驗結果做一個統一處理,不想把對校驗結果的處理分散在每個controller方法中
第一個用意是做後端的防表單重複提交的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"/>
這樣就大功告成了。