1.1 空间架构 框架采取微内核全方位扩展架构,全方位是指其扩展办法在空间上的表现形式。
整 个空间架构由 Handler、Interceptor、Controller、Render、Plugin 五大部分组 成。
每个部分都是基于接口实现的,支持完全的自定义,利用灵巧,扩展性强。
空间架构图。
Handler Interceptor Controller Render Plugin

1.2 逻辑架构 框架的逻辑架构非常大略,便是一个经典的 MVC 模式蜕变、大致分成以下 6 个步骤: 1.2.1 Http

包括 HttpServletRequest、HttpServletResponse,即客户端要求与相应 1.2.2 Filter 所有要求的拦截器,相称于是一个闸口 1.2.3 Handler 要求处理器,是对所有要求的公共处理,在这里我们可以做权限掌握、安全验证等。
它是一个任务 链模式变种, 由初始配置的 Handler 以及框架默认的 ActionHandler 构成一个链条,依次实行。
1.2.4 Action 动作处理器,它是一个 AOP + Command 模式变种。
由 ActionInvocation 进行调度, 先实行拦截器,末了实行详细方法

jfinal中jsp遍历jsp谈谈JFinal技巧你可懂 React

1.2.5 Model 模型层。
在这个层面包括实体模型的定义、 DB+ActiveRecord 模式数据库操作的支持、从要求中解析出对应参数布局 Model 实例,可以把它算作是 DAO。
1.2.6 Render

渲染层。
卖力将

做事真个数据组装成客户端须要的数据格式,然后 response 到客户端。
支持多种视图的渲染:FreeMark、Jsp、VELOCITY 以及自定义。

HttpServletRequest

HttpServletResponse JFinalFilter(所有要求的拦截器

) Interceptorn(拦截器

) Method(详细的方法

) Action ActionInvocation(动作调度器

) ActionHandler(动作处理器

) Handler(处理器

) Handler ModelInjector (模型布局器

) Model(模型定义

)

DB(数据库操尴尬刁难象

) Render(渲染器

)

JSP FreeMark VeloCity 自定义

View 1.3 代码架构 1.3.1 包构造 1.3.2 包简介 Aop:拦截器 Config:通用配置 Core:核心处理,紧张是 Controller 的调度 Ext:扩展包 Handler:全局处理器 I18N:国际化 util:一些工具类 Log:日志类 Plugin:插件处理 Render:渲染处理,比如对付 FreeMark 的支持 Server:做事器 Token:令牌

Upload:文件上传处理 Validate:验证处理,紧张是数据持久化时的验证 1.4 运作事理

我们从一次新增页面的 add 操作要求来看: 1. 首先是客户端点击新增按钮,提交一个新增要求,要求中会带上做事端处理地址 url

2. 所有要求都会被 JFinalFilter 拦截,然后调用 Handler 进行详细处理 3. Handler 是 一 个 链 条 形 式 的 调 用 , 包 括 0-n 个 自 定 义 Handler , 以 及最 后 一 个ActionHandler,依次实行,当然可以自定义跳出。
4. 进入 ActionHandler 后,首先会根据要求的 target 从缓存的 ActionMapping 中映射获取 到详细操为难刁难应的 Action 工具,这个工具里面封装了方法名、方法 上面的拦截器,方法所在的 Controller, controller 上面的拦截器等。
然后根据 Action 以及 Controller 实例布局出 ActionInvocation。

5. 接下来通过 ActionInvocation 的 invoke 进行详细处理,这是一个明显的

Command模式的实现。
首先是拦截器的调用,拦截器调用中会重新回调

ActionInvocation 的 invoke, 当拦截器调用完毕后,会调用当前操的 method

6. 当进入具

体 controller 的新增方法时, 调用基类getModel(Systemparam.class);这个方法会从 request 中解析出所须要的数据,通过反射设置给详细的 Model 实体类,终极通过 ActiveRecord 来进行数据存储 .

7. 末了是页面渲染 render

核心代码简介

我们还是从一次新增要求的流程来看涉及到的核心类有哪些本身便是一个 Http 的过滤器,紧张有 3 个方法

2.1.1 init(初始化)

在做事器启动时实行一次,卖力初始化框架的全局配置

2.1.2 destory(销毁)

在做事器停滞时运行一次,卖力销毁框架的全局配置

2.1.3 doFilter(拦截)

拦截所有的客户端要求,处理详细逻辑

2.2 JFinalConfig

是一个 API 勾引式配置接口,供给用者自定义实现。
里面紧张配置常量、配置路由、配置处理器、配置插件、配置拦截器。

2.2.1 Config

自定义配置实行的调度器

2.3 JFinal

初始化框架全局配置的调度器, 由它来卖力调用各个组件的初始化接口。
包括 path、 Handler、 Action、Render、ActiveRecord、Const、i18n 等。
其余它 还供应了启动内置做事器 Jetty 的 api

2.4 Action

即一个详细的动作,比如新增、修正、删除等,你也可以称之为方法。
它包含以 下内容:controllerClass、controllerKey、actionKey、method、methodName、interceptors、 viewPath

2.4.1 ActionMapping

初始化要求 url 与 Action 的映射关系,是 Controller 的解析器,终极的产出物是天生一个个 actionKey 以及与之对应的 Action 工具。

2.4.2 ActionInvocation

动作调度器,卖力调用各个拦截器以及详细的方法

2.4.3 ActionKey

自定义的表明,用于自定义 action 的路由规则

2.5 Handler

通用的全局处理器

2.5.1 ActionHandler

动作处理器,卖力剖析要求,找到对应的 Action 并实行

2.5.2 HandlerFactory

全局 Handelr 的工厂,卖力天生一个 handler 链

2.6 Render

渲染器

2.6.1 RenderFactory

渲染器的工厂类,卖力布局出各种视图的渲染器

2.6.1.1 FreeMarkerRenderFactory

FreeMarkerRender

2.6.1.2

JspRenderFactory

JspRender

2.6.1.3

VelocityRenderFactory

VelocityRender

2.7 Iplugin 插件

2.7.1 C3p0Plugin、DruidPlugin

数据源插件

2.7.2 EhCachePlugin

缓存插件

2.7.3 ActiveRecordPlugin

model 初始化插件

2.7.3.1 AutoTableBindPlugin

自动绑定 model 与数据库表的插件

2.7.3.2 TableInfoBuilder

卖力初始化 model 与数据库表的映射关系

2.7.3.2.1 TableInfo

存储的即映射关系,包括 tableName、primaryKey、columnTypeMap

2.7.3.3 Model

所有 Model 的基类,封装了通用的数据库操作的方法

2.7.3.3.1 ModelInjector

从要求中布局出 model 实例的工具类

2.7.3.4 Db、DbKit 通用的数据库操尴尬刁难象类

2.7.4 SpringPlugin

卖力与 spring 框架进行集成

2.7.5 QuartzPlugin、Cron4jPlugin 任务调度插件

2.7.6 ConfigPlugin 配置文件插件

2.8 Routes 路由规则

2.8.1 MyRoutesUtil 自动绑定 Controller 的工具类

2.9 Controller

所有 Controller 的基类,封装了通用的方法

2.10拦截器

Interceptor

2.10.1 Before

自定义拦截器的表明,合营

拦截器实现类利用,实现热插拔拦截的功能

2.10.2 Tx

事务处理的拦截器

2.11Validator

做事真个校验器,供用户自定义实现

2.12做事器接口

IServer

2.12.1 JettyServer

内置的 jetty 做事器实现

2.13MultipartRequest 对付文件上传的处理

其余还有 1 个分布式缓存的实现,详细可以参照 MemcacheTool

3.详细先容

3.1初始化

初始化在做事器启动时进行,入口即在 JFinalFilter 中,下面讲最主要的

2 项初 始化过程

3.1.1 掌握器的初始化

掌握器的初始化包括 2 个方面,1 个是

路由,1 个是 action。

路由仅仅是初始化得到一个path—ControllerClass 的映

射。
Action 的初始化则是将 Controller 中每个方法进行封装。
Action 的初始化依

靠 ActionMapping 的 buildActionMapping 方法实现,

下面是实现过程, 当然我们首先

得明白 actioin 初始化目标是方法:

1. 获取不须要初始化的方法的名称,紧张是基类

Controller 里面封装的一些通用方法 2. 获取全局拦截器

3. 遍历前面初始化好的

路由,也便是每个自己写的业务 Controller

4. 解析每个 Controller 的拦截器

5. 反射获取到每个 Controller 里面的所有方法,进行遍历 6. 打消掉不须要的,剩下

的方法首先解析出方法上面的拦截器

7. 进行 Action 的布局 new Action

(controllerKey, actionKey, controllerClass, method, methodName, actionInter

s, routes.getViewPath(controllerKey));

8. 末了用一个 actionKey 与 Action 进

行映射,然后全局缓存住,这个 actionKey 即为客户 端调用这个方法的唯一钥匙

从上面

可以看出, jfinal 中实际上是不保留对付 Controller 的初始化信息的,它的单位只

有 1 个,便是 Action (动作 or 方法)。
在我看来,这样的组织有点不合理,个人以为

该当是 Controller 保留,Action 寄托在 Controller 中,这样才是最合理的,而且全局

的和类的成员 将不须要重复涌如今每个 Action 中。
客户端要求过来之后,该当首先实行

全局方法,再获取到 Controller,实行类方法,末了获取 对应 Action,实行详细动作。

3.1.2 Model 初始化

对付 model 的初始化,终极结果便是获取 TableInfo 工具 这个工具里面包含表名、主键名、实体名以及 1 个 columnTypeMap,这个 map 里面存放的是

数据库列名与该列数据类型 Class 的映射入口也是 JfinalFilter 的 init 方法

这里的 TableInfo 的 list 便是我们利用 Jfinal 的 config 须要初始配置的,

3.1.3 自动初始化实体的实现

编写了一个 AutoTableBindPlugin 插件类,通过查询出所有继续自 Model 的实体类,然后通过解析 TableBind 这个自定义表明,获取表名以及主键名

3.2 Jdbc 是如何与连接池插件集成的

比如我们原来利用的 proxool, hibernate 就支持与之整合。
亦或者 spring 中默认利用的 c3p0。
连接池, 说白了便是用来管理数据库连接的, 比如最大许可多少连接数, 最长连接韶光等等, 那么我们自己写的 jdbc, 怎么来整合它得到它所供应的功能呢?实在和大略, 我们只须要将 数据库连接交由连接池去托管即可:

1. 自定义一个类,比如叫 C3p0Plugin,它卖力与连接池的整合衔接,实在便是根据数据库 的配置,天生一个 javax.sql.DataSource即可,这个 DataSource 工具必须是连接池的, 比如要整合 C3p0,那么就必须

DataSource dataSource = new

ComboPooledDataSource(); dataSource.setJdbcUrl

(jdbcUrl); dataSource.setUser(user); dataSource.setPassword(password); 。




2. 所有须要利用到数据库 Connection 的地方,全部通过 C3p0Plugin 中

的 DataSource 获取,获取方法为 dataSource.getConnection()。
这样就完成了将数据库连接纳入连接池的事情

3.3 声明式事务是如何实现的

框架的事务是通过表明来支持的,spring 也是如此,即在须要事务的方法上面加上事务 特有的表明,比如 这便是所谓的声明式事务。
要讲它是如何实现的,那么就必须先明白表明是怎么起浸染 的。

1. 表明的意义 表明的出身便是为理解放 xml 的冗繁,从这一点可以看出,实在它最核心的功能就 是为了配置。
当然它还有其他一些浸染,比如功能聚簇。
实体的映射 xml 文件实在就该当 与实体在一起的。

2. 自定义表明 自己定义一些须要利用到

的表明,这个大略的运用还是比较大略的, 这里不多说 3. 表明解析

表明的核心浸染既然是配置,那么肯定是须要解析的,而且这种固定式的配置,显 然只须要解析一次即可。

Jfinal 中是在 Filter 的 init 方法中进行表明的解析事情的。
它会将方法以及方法上面的表明的映射关系都解析好缓存起来 4. 表明运用 当调用到详细该方法时,首先会从缓存中获取该方法上面的表明,然后根据详细的 表明内容进行干系的处理,比如这里的 Tx.class,便是一个事务处理的拦截器,那么 就会调用事务处理的操作。
这里是一个递归调用办法:

ActionInvocation 调用 invoke 方法 Invoke 方法中调用各个拦截器的拦截方法 intercept Intercept 方法中会通过传入的 ActionInvocation 工具回调 invoke 方法连续处理 这样如下的事务操作就可以席卷全体方法的实行了,这便是个命令模式。

3.4DB+ActiveRecord

DB 的话很大略明了,便是一个数据库操尴尬刁难象

类, ActiveRecord 说白了便是在我们 的 model 中加入了数据库操作的能力。
比如 add、 remove、 update。
这些通用的处理, JFinal 在 中统一交由最上层的基类 Model 进行,我们的实体类继续自 Model,就拥有了该能力。

3.5表单数据自动绑定是怎么实现的

Jfinal 中一个表单的新增,后台只须要写如下代码即可

完成,它是如何实现的 1. 表单页面

首先我们看下这个表单页面,把稳 3 个输入域的 name 属性,都是 blog.xxx,这里 实际上便是设置了值与实体属性之间的映射关系了

2. 做事端从 request 中获取到所有的值,过滤出个中 blog 属性,缓存到 Model基类 的 attrs 这个 map 中 3. 末了通过 Record 的 add 方法进行新增。

3.6关于路由

3.6.1 ioc

这里的路由就相称于我们原来 seam 框架的 ioc 了, 不过它功能更大略一些, 须要在初始 的时候进行配置,也便是页面与 Controller 之间的映射关系。

3.6.2 如何去除路由配置

很大略,利用我们原来的表明的办法即可。
自定义一个 Controller 的表明,比如 Name,然 后解析初始化到全局配置中即可。

3.6.3 自动绑定 controller 的实现 事理与我们原来猜想的一样

1. 自定义了一个 RouteBind 表明,然后每个 Controller 进行绑定

2. 编写了一个工具类 MyRoutesUtil

该工具类将 webinf/classes 目录下面所有的.class 二进制文件查找出来,然后通过反射 和解析表明天生 jfinal 的 Routes

3. 在做事器启动的时候进行初始化即可

3.7 拦截器

Jfinal 中所有的拦截都通过 Interceptor 实现,根据位置大致可以分成以下几种

3.7.1 全局拦截器

在 config 中进行注册

3.7.2 类拦截器

在类上面通过表明注册

3.7.3 方法拦截器

在方法上面通过表明注册

3.8 插件机制

插件的机制紧张便是一个基于接口动态扩展实现的架构,最顶层是一个 IPlugin。
实在说白 了,它便是一个全局性配置的扩展实现。

3.8.1 插件的注册

在自定义实现的 JfinalConfig 中进行配置

3.8.2 插件运行

所有插件的运行都是在做事器启动的时候进行一次,详细是在 Config 类中的如下方法:

3.8.3 插件停滞

停滞即在做事器关闭时 JfinalFiler 的 destroy 中进行

3.9 缓存

3.9.1 EcachePlugin

框架本身内置了 Ecache 这个插件,可以直策应用,只须要在 JfinalConfig 中进行注册即可

3.9.2 MemcachedClient

其余还有 1 个分布式缓存的实现,详细可以参照 MemcacheTool

4如何利用

4.1 拦截器

参照上面的 3.7

4.2 掌握器

编写一个普通 java 类,继续 Controller,类上面利用表明进行路由绑定

@RouteBind(path = \"大众/power\"大众) public class PowerContraller extends BaseController

4.2.1 调用 controller 的方法

1. 页面进来的时候默认会走 index 方法,这个实现在 ActionMapping

2. 调用指定方法 默认调用 controller 中方法的办法为/controllername/methodname <form action=\"大众${path}/power/list\"大众> 比如上面的路径,power 为 controller 的路由表明、list 即为方法名字。
但是也可以通过 ActionKey 这个表明来进行自定义,比如如下就将 list 方法名改成了 hello。
@ActionKey(value=\公众hello\公众) public void list() {}

4.3 数据库操作

Jfinal 中数据库的增编削查都可以通过 Db 这个工具类或者实体工具进行。
也便是所谓的 DB+ActiveRecord 办法。
里面的数据库方法基本涵盖了所有须要的,而且它支持 POJO 形式 的操作。

4.4

参数获取 后台获取要求中的参数,都是通过基类 Controller 中封装好的 getPara…方法进行。

4.5 如何实现事务

框架的事务是方法级别的,在须要实现事务的方法上面利用表明@Before{Tx.class},加上事 务 Tx 的拦截器即可。

4.6 如何实现文件上传

前端用一个 js 上传控件,后台有通用的 FileController 支持处理 比如前端用的 swf 的上传控件 后端:

5 后续扩展改进

5.1

紧张是针对 Model 以及 Controller 的初始化, 使其支持

5.2 带参数方法的支持

在前端须要能够调用做事端带参数的方法,参数能够直接绑定到方法上面

5.3 如何实现多数据源

多数据源的实现紧张在于事务的掌握上面,大家看下这个事务拦截器的实现:

这里 DbKit.getDataSource 获取到的是一个静态的全局框架性数据源的定义,显然是唯一的。
但是我们可以对其进行改造, 只须要这里事务可以从当前利用的数据源进行掌握即可达到目 的。

5.4 集群与负载均衡

Session 的信息可以采取分布式的 memcache 来支持共享。
而无状态的框架架构可以支持集 群与负载均衡的实现

5.5 前真个技能选型

目前 js 控件库准备采取 jQuery-eazyUI 与 dwz 中的一个,模板则利用 freeMark 或者 jsp 来进 行,详细情形需 要等到实际考试测验测试后确定

5.6 Webservice 支持

restful 办法,还是传统的 webservice。
这个个人以为可以

放到后面去考虑,实现肯定不是问 题的。