AOP(Aspect Orient Programming),其實也就是面向切面編程。面向對象編程(OOP)是從靜態角度考慮程序結構。面向切面編程(AOP)是從動態角度考慮程序運行過程。java
根據我的的理解,AOP執行圖大體以下:spring
1. 切面(Aspect):業務流程運行的某個特定步驟,也就是應用運行過程當中的關注點,關注點能夠橫切多個對象,也稱爲橫切關注點。如示例中的AspectService。apache
2. 鏈接點(Joinpoint):是切面類和業務類的鏈接點。編程
3. 通知(Advice):在切面類中,聲明對業務方法執行額外加強處理。框架
3.1 前置通知(Before Advice):切入前執行測試
3.2 後置通知(After Advice):切入後執行【無論程序在運行過程當中是否發生異常】spa
3.3 返回後通知(AfterReturning Advice):切入後執行【程序成功運行後】代理
3.4 環繞通知(Around Advice):近似等於Before Advice與AfterReturning Advice總和,Around Advice 既可在執行目標方法以前,也可在執行目標方法後,既然如此的不肯定爲何不用Before Advice + After Advice代替呢?我的以爲仍是省着點用吧日誌
3.5 異常通知(AfterThrowing Advice):在切入點發生異常時執行 code
4. 切入點(Pointcut):能夠插入加強處理的鏈接點,說白了就是當基本個鏈接點符合要求時,這個鏈接點就會添加額外加強處理,這個點也就成了切入點了。
5. 目標(Target):被代理的對象。
1. 切面定義
package com.swyma.spring.service; import java.util.Date; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.annotation.After; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Pointcut; import org.springframework.stereotype.Service; import com.swyma.spring.core.DateUtils; /** * AOP切面 * @author yemaoan * */ @Aspect @Service public class AspectService { Log log = LogFactory.getLog(AspectService.class); @Pointcut("execution(* *.create(..))") public void createPointCut() { } @Around(value = "createPointCut()") public void weaveCreatePointCut(JoinPoint join) { Object obj = join.getTarget().getClass().getSimpleName(); log.info("用戶 " + " " +" 在 " + DateUtils.getDate2String(new Date(),"yyyy-MM-dd HH:mm:ss") + " 調用了 " + obj + " 並執行了 create 操做"); } @Pointcut("execution(* *.modify(..))") public void modifyPointCut() { } @After(value = "modifyPointCut()") public void weaveModifyPointCut(JoinPoint join) { log.info("用戶 " + " " +" 在 " + DateUtils.getDate2String(new Date(),"yyyy-MM-dd HH:mm:ss") + " 執行了 modify 操做"); } @Pointcut("execution(* *.delete(..))") public void deletePointCut() { } @After(value = "deletePointCut()") public void weaveDeletePointCut(JoinPoint join) { log.info("用戶 " + " " +" 在 " + DateUtils.getDate2String(new Date(),"yyyy-MM-dd HH:mm:ss") + " 執行了 delete 操做"); } }
2. 目標【target】
2.1 UserService【用戶服務】
package com.swyma.spring.service; import org.springframework.stereotype.Service; import com.swyma.spring.entity.User; @Service public class UserService extends BasicService { public void create(User user) { } public void modify(User user) { } public void delete(User user) { } }
2.2 RegisteService【註冊服務】
package com.swyma.spring.service; import org.springframework.stereotype.Service; @Service public class RegisterService extends BasicService { public void create() { } }
3. 測試類
package com.swyma.spring.test; import org.junit.Test; import com.swyma.spring.core.ISpringContext; import com.swyma.spring.entity.User; import com.swyma.spring.service.BasicSpringContext; import com.swyma.spring.service.LoginService; import com.swyma.spring.service.RegisterService; import com.swyma.spring.service.UserService; /** * JUintTest * @author yemaoan * */ public class TestSpringEnv { @Test public void testLookup() { ISpringContext context = new BasicSpringContext(); LoginService loginService = context.lookup(LoginService.class); loginService.handle(); } @Test public void testAspect() { ISpringContext context = new BasicSpringContext(); UserService userService = context.lookup(UserService.class); RegisterService registerService = context.lookup(RegisterService.class); userService.create(new User()); registerService.create(); } }
4. 運行結果【cosole】
21:26:30,741 INFO com.swyma.spring.service.AspectService:35 - 用戶 在 2013-10-03 21:26:30 調用了 UserService 並執行了 create 操做
21:26:30,742 INFO com.swyma.spring.service.AspectService:35 - 用戶 在 2013-10-03 21:26:30 調用了 RegisterService 並執行了 create 操做
4、總結
1. 以上均是我的的對Spring AOP的理解,若有錯誤之處,望各位網友批評批評,共同探討,在些先謝過!
2. Spring AOP核心思想實際上是個動態代理的機制,動態代理【DynamicProxy】尋找【JointPoint】鏈接點,當找到符合要求時就會執行通知【Advice】。