简单的说一下AOP的实现,所谓AOP,即(Aspect Oriented Programming)的缩写,体现在程序中就是你可以通过配置在任意的代码块前后插入你想插入的执行代码。例如日志、事务、权限验证等。
首先看看Jfinal中基于@Before注解的拦截器如何用:
上面是一个简单的Controller。JFinal中Interceptor其实是由三种粒度,全局拦截器,Controller拦截器已经Method级别的拦截器,上面中体现了两点,这里我们仅对Method级别的拦截器进行剖析。
在JFinal中使用拦截器必须继承Interceptor接口:
这个接口很简单,只包含一个以ActionInvocaton为参数的方法,对于ActionInvocation顾名思义就是Action调度者,先来看看ActionInvocation的基本定义:
ActionInvocation会有一个invoke方法,调度Action的时候应该是new ActionInvocation().invoke()这个样子的形式。这个可以在
com.jfinal.core.ActionHandler中找到:
/**
-
handle
-
1: Action action = actionMapping.getAction(target)
-
2: new ActionInvocation(...).invoke()
-
3: render(...)
*/
上面可以看出,其实Action的调度者ActionInvocation实现了动态代理的功能,参考文章:JDK和CGLIB动态代理
拦截器实现类如下:
Before为用户自定义注解:
来看看框架是如何根据注解获取拦截器class的,这个要看JFinal的InterceptorBuilder类的实现:
注释可以看出这是一个方法级别的拦截器构造,Method讲师通过反射得到的index方法实例,而Method为我们提供了getAnnotation方法,这个方法可以获取Before.class的注解,接着看createInterceptor方法的实现:
createInterceptor将构造一个hashMap,保存对应拦截器的名称和实例。整个执行流程是这样的: 用户请求Action,ActionHandler处理用户的请求,内部获取对应的Action,其中Action中保存着已经构造好的拦截器信息,ActionHandler将用Action实例构造ActionInvocation实例,ActoinInvocation.invoke()将会实现切面代码和Action代码的执行。