SpringAop @Aspect織入不生效,不執(zhí)行前置增強織入@Before方式
SpringAop @Aspect織入不生效,不執(zhí)行前置增強織入@Before
想寫一個AOP,主要有2個用意
- 第一個用意是做后端的防表單重復提交的token驗證。
- 第二個用意是對后臺JSR303 Validator的校驗結(jié)果做一個統(tǒng)一處理,不想把對校驗結(jié)果的處理分散在每個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統(tǒng)一處理。
所以寫一個AOP,如下:
@Aspect
@Component
public class ParamValidAspect {
@Before("@annotation(com.hebao.tech.adm.framework.annotation.ParamValid)")
public void paramValid(JoinPoint point) {
System.out.println("參數(shù)校驗切入方法被調(diào)用了.....");
//省略
}
}
由于這篇文章主要是記錄AOP不生效的原因,所以,這里不寫具體實現(xiàn)了。
上面的內(nèi)容定義一個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的內(nèi)容,僅僅是一個標志性的注解,聲明為方法層的注解,并且是運行時注解。
最后在application.xml中加入AOP動態(tài)代理設置。
<!-- 這個配置要配置在component-scan以后 --> <aop:aspectj-autoproxy proxy-target-class="true" />
如果spring配置文件沒引入過aop的配置,還需要在加入xml聲明

大功告成,測試了一下,發(fā)現(xiàn)有點悲劇,根本織入不生效,也不報錯,,楞是不執(zhí)行相關(guān)的織入代碼。
最后在網(wǎng)上搜了一下,發(fā)現(xiàn)Spring與SpringMVC是2個不同的父子容器, @Aspect如果被spring容器加載的話,而@Controller注解的這些類的實例化以及注入?yún)s是由SpringMVC來完成。 @Aspect如果被spring容器加載的時候,可能Spring MVC容器還未初始化, Controller類還未初始化,所以無法正??椚搿?。
所以調(diào)整如下:
@Aspect
public class ParamValidAspect {
@Before("@annotation(com.hebao.tech.adm.framework.annotation.ParamValid)")
public void paramValid(JoinPoint point) {
System.out.println("參數(shù)校驗切入方法被調(diào)用了.....");
//省略
}
}
去掉@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不被調(diào)用
@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");
}
}
調(diào)用方法返回結(jié)果:
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");
}
}
調(diào)用返回結(jié)果:
arount before
before
arount after
after
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
CommonMark 使用教程:將 Markdown 語法轉(zhuǎn)成 Html
這篇文章主要介紹了CommonMark 使用教程:將 Markdown 語法轉(zhuǎn)成 Html,這個技巧我們做任何網(wǎng)站都可以用到,而且非常好用。,需要的朋友可以參考下2019-06-06
Java class文件格式之屬性_動力節(jié)點Java學院整理
在本文中, 主要講解了class文件中的一些屬性。 這些屬性可以出現(xiàn)在class文件中的對個地方, 用來描述一些其他信息2017-06-06
MyBatis實現(xiàn)自定義MyBatis插件的流程詳解
MyBatis的一個重要的特點就是插件機制,使得MyBatis的具備較強的擴展性,我們可以根據(jù)MyBatis的插件機制實現(xiàn)自己的個性化業(yè)務需求,本文給大家介紹了MyBatis實現(xiàn)自定義MyBatis插件的流程,需要的朋友可以參考下2024-12-12

