SpringAOP的運用方式——註解方式和XML配置方式java
AOP(Aspect Oriented Programming):面向切面編程,經過預編譯方式和運行期動態代理實現程序功能的統一維護的一種技術。web
package controller; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; @Controller @RequestMapping public class ProjectController { @RequestMapping("/success/{param}") public String goContent(@PathVariable String param, Model model){ System.out.println(param + "調用了 Controller"); model.addAttribute("userName",param); return "/success"; } }
package north; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.*; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.EnableAspectJAutoProxy; import java.io.IOException; @Configuration @EnableAspectJAutoProxy @ComponentScan(basePackages = "controller") @Aspect public class AspectStyleNorth { @Pointcut("execution(* controller.*.*(..))") public void pointcut() { System.out.println("定義切點....."); } @Before(value="pointcut()") public void before() { System.out.println("AspectStyleNorth.before()方法執行前執行....."); } @After("pointcut()") public void after(JoinPoint joinPoint) throws IOException { System.out.println("AspectStyleNorth.after()方法執行後執行....."); } @Around(value="pointcut()") public Object around(ProceedingJoinPoint pjp){ System.out.println("AspectStyleNorth.around()方法環繞start....."); Object rs = new Object(); try { rs = pjp.proceed(); } catch (Throwable e) { e.printStackTrace(); } System.out.println("AspectStyleNorth.around()方法環繞end....."); return rs; } @AfterThrowing(value="pointcut()", throwing="e") public void exception(Exception e) { //記錄異常 System.out.println("exception ["+e+"]"); } }
c.springmvc.xml中須要配置對 註解類的掃描spring
<context:component-scan base-package="north"></context:component-scan>
d.效果express
【說明】:around()與before() 開始執行的前後不肯定,但before() 一定在around()中 proceedingJoinPoint.proceed()以前執行。編程
package controller; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; @Controller @RequestMapping public class ProjectController { @RequestMapping("/success/{param}") public String goContent(@PathVariable String param, Model model){ System.out.println(param + "調用了 Controller"); model.addAttribute("userName",param); return "/success"; } }
<!-- 掃描下方切面配置的各個切點所在的包 --> <context:component-scan base-package="controller"></context:component-scan> <!-- 切面配置 --> <aop:config> <aop:pointcut id="pointcut" expression="execution(* controller.*.*(..))"/> <aop:aspect ref="aspectStyleSouth"> <aop:before pointcut-ref="pointcut" method="before"/> <aop:after pointcut-ref="pointcut" method="after"/> <aop:around pointcut-ref="pointcut" method="around"/> <aop:after-throwing pointcut-ref="pointcut" method="exception" throwing="e"/> </aop:aspect> </aop:config> <bean id="aspectStyleSouth" class="south.AspectStyleSouth"/>
【注】:須要同時掃描兩個地方的包:①AOP附加處理邏輯所在的包;②運用到 AOP 的業務邏輯所在的包。安全
package south; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.*; import java.io.IOException; @Aspect public class AspectStyleSouth { public void before() { System.out.println("before方法執行前執行....."); } @Pointcut("execution(* server.*.*(..))") public void pointcutA() { System.out.println("定義切點....."); } @Before(value="pointcutA()") public void beforeA() { System.out.println("AspectStyleNorth.before()方法執行前執行....."); } /** * * @Title:doAfterInServiceLayer * @Description: 方法調用後觸發 * 記錄結束時間 * @author shaojian.yu * @date 2014年11月2日 下午4:46:21 * @param joinPoint */ public void after(JoinPoint joinPoint) throws IOException { Object[] args = joinPoint.getArgs() == null ? new String[]{""} : joinPoint.getArgs(); System.out.println("after方法執行後執行....."+args[0]); } public Object around(ProceedingJoinPoint pjp){ System.out.println("around方法環繞start....."); Object rs = new Object(); try { rs = pjp.proceed(); } catch (Throwable e) { e.printStackTrace(); } System.out.println("around方法環繞end....."); return rs; } public void exception(Exception e) { //記錄異常 System.out.println("exception ["+e+"]"); } }
d.效果mvc
項目的目錄:app
延伸:ide
1.在AOP中,須要用到傳參的時,可參考:【第六章】 AOP 之 6.3 基於Schema的AOP ——跟我學spring3性能
2.AOP中,方法、路徑、參數等匹配的表達式,可參考:Aspectj execution表達式