前言:
一年前就接触了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级别的拦截器,她将拦截本类中的所有方法
[email protected](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方法需要移除该权限拦截器才能正常登录
[email protected](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注解带有参数时,能清除指定的拦截器,以下是一个更加全面的示例:
[email protected](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
原文地址:https://www.cnblogs.com/Erma/p/10348081.html