前言:
一年前就接觸了AOP的概念,並且對AOP的三種模式進行了系統的學習,至今還是不能熟練地掌握和運用。今天針對jfinal框架的AOP,重點理解AOP的思想及實現。
這里有篇Thoughtworks大牛之作,他所描述的AOP讓我有種新的認知輕松理解AOP思想(面向切面編程)
Jfinal中的AOP

AOP概述
傳統AOP實現需要引入大量繁雜而多余的概念,例如:**Aspect、Advice、Joinpoint、Poincut、Introduction、Weaving、Around**等等,並且需要引入IOC容器並配合大量的XML或者annotation來進行組件裝配。之前雖然系統學過,但了解地並不深入。如果您也想從傳統的方法過渡到現在的jfinal AOP這種切面編程思想,可以了解一下我們框架中[AOP+IOC的方式](http://www.sec119.com/)
傳統AOP不但學習成本極高,開發效率極低,開發體驗極差,而且還影響系統性能,尤其是在開發階段造成項目啟動緩慢,極大影響開發效率。
JFinal采用極速化的AOP設計,專注AOP最核心的目標,將概念減少到極致,僅有三個概念:Interceptor、Before、Clear,並且無需引入IOC也無需使用啰嗦的XML。
Interceptor
Interceptor可以對方法進行攔截,並提供就會在方法的前后添加切面代碼,實現AOP的核心目標。Interceptor接口僅僅定義了一個方法public void interceptor(Invocation inv),以下是簡單示例:
public class DemoInterceptor implements Interceptor{
public void intecept(Invocation inv){
System.out.println(“Before method invoking”);
Inv.invoke();
System.out.println(“After method invoking”);
}
}
以上代碼中的DemoInterceptor 將攔截目標方法,並且在目標方法調用前后向控制台輸出文本inv.invoke() 這一行代碼是對目標方法的調用,在這一行代碼的前后插入切面可以很方便地實現AOP.
Before
Before 注解用來對攔截器進行配置,該注解可配置class、method級別的攔截器,一下是代碼示例:
1.// 配置一個Class級別的攔截器,她將攔截本類中的所有方法
2.@Before(AaaInter.class)
3.public class BlogController extends Controller {
4.
5. // 配置多個Method級別的攔截器,僅攔截本方法
6. @Before({BbbInter.class, CccInter.class})
7. public void index() {
8. }
9.
10. // 未配置Method級別攔截器,但會被Class級別攔截器AaaInter所攔截
11. public void show() {
12. }
13.}
如上代碼所示,Before可以將攔截器配置為Class級別與method級別,class級別的攔截器將攔截本類中所有的方法,method方法進攔截本方法。此外Before可以同時配置多個攔截器,只需要在大括號內用逗號將多個攔截器進行分隔即可。
除了class和method級別的攔截器意外,Jfinal還支持全局攔截器以及Inject攔截器(Inject攔截將在后面介紹),全局攔截器分為控制器層全局攔截器與業務層全局攔截器,前者攔截控制層所有Action方法,后者攔截業務層所有方法。
全局攔截器需要在YourJFinalconfig 進行配置,一下是配置示例:
1.public class AppConfig extends JFinalConfig {
2. public void configInterceptor(Interceptors me) {
3. // 添加控制層全局攔截器
4. me.addGlobalActionInterceptor(new GlobalActionInterceptor());
5.
6. // 添加業務層全局攔截器
7. me.addGlobalServiceInterceptor(new GlobalServiceInterceptor());
8.
9. // 為兼容老版本保留的方法,功能與addGlobalActionInterceptor完全一樣
10. me.add(new GlobalActionInterceptor());
11. }
12.}
當某個Method被多個級別的攔截器所攔截,攔截器各級別執行的次序依次為:Global、Routes、Class、Method,如果同級中有多個攔截器,那么同級中的執行次序是:配置在前面的先執行。
攔截器從上到下依次分為Global、Routes、Class、Method四個層次,Clear用於清除自身所處層次以上層的攔截器。
Clear聲明在Method層時將針對Global、Routes、Class進行清除。Clear聲明在Class層時將針對Global、Routes 進行清除。Clear注解攜帶參數時清除目標層中指定的攔截器。
在某些應用場景之下,需要移除Global或Class攔截器。例如某個后台管理系統,配置了一個全局的權限攔截器,但是其登錄action就必須清除掉她,否則無法完成登錄操作,以下是代碼示例:
1.// login方法需要移除該權限攔截器才能正常登錄
2.@Before(AuthInterceptor.class)
3.public class UserController extends Controller {
4. // AuthInterceptor 已被Clear清除掉,不會被其攔截
5. @Clear
6. public void login() {
7. }
8.
9. // 此方法將被AuthInterceptor攔截
10. public void show() {
11. }
12.}
Clear注解帶有參數時,能清除指定的攔截器,以下是一個更加全面的示例:
1.@Before(AAA.class)
2.public class UserController extends Controller {
3. @Clear
4. @Before(BBB.class)
5. public void login() {
6. // Global、Class級別的攔截器將被清除,但本方法上聲明的BBB不受影響
7. }
8.
9. @Clear({AAA.class, CCC.class})// 清除指定的攔截器AAA與CCC
10. @Before(CCC.class)
11. public void show() {
12. // 雖然Clear注解中指定清除CCC,但她無法被清除,因為清除操作只針對於本層以上的各層
13. }
14.}
參考資料
【1】輕松理解AOP思想(面向切面編程).https://www.cnblogs.com/Wolfmanlq/p/6036019.html#undefined
【2】jifnal官方文檔.https://www.jfinal.com/doc/4-3
