新書推薦:
《
天下的当代性:世界秩序的实践与想象(新版)
》
售價:HK$
79.4
《
德国天才4:断裂与承续
》
售價:HK$
112.7
《
妈妈的情绪,决定孩子的未来
》
售價:HK$
43.7
《
推拿纲目
》
售價:HK$
414.0
《
精致考古--山东大学实验室考古项目论文集(一)
》
售價:HK$
250.7
《
从天下到世界——国际法与晚清中国的主权意识
》
售價:HK$
78.2
《
血色帝国:近代英国社会与美洲移民
》
售價:HK$
59.8
《
海外中国研究·王羲之:六朝贵族的世界(艺术系列)
》
售價:HK$
182.9
|
內容簡介: |
本书全面、深入介绍了企业级Java EE设计的相关内容,内容涵盖了Java EE架构设计的常见问题。本书每一章讲解一个Java EE领域的具体问题,采用问题背景、需求分析、解决思路、架构设计、实践示例和章节总结的顺序组织内容,旨在通过分析相关领域中的常用框架及存在问题,给出相应的解决方案,提高读者分析和解决问题的能力,并增强其架构设计的能力。
本书共13章。内容主要包括虚拟文件系统实践、缓存实践、文件处理框架实践、模板语言实践、数据库访问层实践、数据库扩展实践、服务层实践、流程引擎实践、元数据实践、展现层开发实践、Web扩展实践、Tiny统一界面框架实践和RESTful实践。附录中给出了相关学习资源和配置运行指南。
本书语言简洁,思路清晰,示例丰富、完整,适合具有一定Java基础的读者阅读,尤其适合从事企业级Java EE软件架构和设计的人员阅读。
|
關於作者: |
罗果专注于企业级Java EE开发平台领域。涉猎广泛,在模块化、元数据、模板引擎、数据库分区分表、SOA等领域都有深入实践。吃过很多亏,上过很多当,但坚信实践出真知。业余时间热心于开源技术,热衷于技术分享,撰写了大量的技术博客,从问题、原理和实践几个方面深入浅出地讲述知识。在开源中国社区开博两年,其博客浏览量已近百万次。所开发的Java EE开源框架Tiny,入驻开源中国社区两年以来,获得的Star和Fork数都已双双近千,是开源中国极具活力的开源项目之一。
|
目錄:
|
第1章 虚拟文件系统实践
1.1 背景介绍
1.2 什么是VFS
1.3 VFS对比
1.3.1 Apache VFS
1.3.2 Tiny VFS
1.4 VFS框架设计思想
1.5 VFS实现讲解
1.5.1 VFS管理器
1.5.2 SchemaProvider模式提供者
1.5.3 FileObject虚拟文件
1.5.4 FileObjectFilter过滤接口
1.6 VFS应用示例
1.6.1 本地文件
1.6.2 Jar文件
1.6.3 FTP文件
1.6.4 ZIP文件
1.7 本章总结
第2章 缓存实践
2.1 缓存简介
2.1.1 问题的提出及其解决方案分析
2.1.2 用户需求
2.1.3 Tiny缓存解决思路
2.2 字节码缓存设计
2.2.1 字节码操作工程
2.2.2 预编译工程
2.2.3 缓存实现工程
2.2.4 技术特点
2.3 动态代理缓存设计
2.3.1 缓存接口定义
2.3.2 切面缓存工程
2.3.3 技术特点
2.4 缓存方案实践
2.4.1 字节码方案配置
2.4.2 字节码方案示例
2.4.3 动态代理方案配置
2.4.4 动态代理方案示例
2.5 本章总结
2.5.1 关键点:缓存实现方案的可替换性
2.5.2 关键点:缓存代码与业务代码的解耦
2.5.3 关键点:模板语言的应用
第3章 文件处理框架实践
3.1 概述
3.1.1 FileProcessor接口
3.1.2 FileResolver接口
3.1.3 FileMonitorProcessor类
3.2 基础文件扫描器
3.2.1 XStreamFileProcessor类
3.2.2 I18nFileProcessor类
3.2.3 Annotation扫描器
3.2.4 SpringBeansFileProcessor类
3.3 完整示例
3.3.1 单独使用
3.3.2 通过配置文件配置
3.4 本章总结
第4章 模板语言实践
4.1 模板语言简介
4.1.1 模板语言构成
4.1.2 模板语言应用场景
4.2 常见的模板语言
4.2.1 Velocity模板语言
4.2.2 FreeMarker模板语言
4.2.3 Tiny模板语言
4.3 Tiny模板语言设计
4.3.1 Tiny模板语言的构建原因
4.3.2 模板语言执行方式
4.3.3 模板语言架构
4.3.4 Tiny模板语言实现与扩展
4.3.5 模板语言语法解析
4.3.6 模板语言渲染机制
4.4 模板语言的使用
4.4.1 依赖配置
4.4.2 模板语言的配置
4.4.3 模板语言的Eclipse插件
4.4.4 Hello,TinyTemplate
4.5 模板语言语法介绍
4.5.1 变量
4.5.2 取值表达式
4.5.3 Map常量
4.5.4 数组常量
4.5.5 其他表达式
4.5.6 索引表达式
4.5.7 #set指令
4.5.8 条件判断
4.5.9 ==相等运算
4.5.10 AND运算
4.5.11 OR运算
4.5.12 NOT运算
4.5.13 循环语句
4.5.14 循环状态变量
4.5.15 循环中断:#break
4.5.16 循环继续:# continue
4.5.17 while循环
4.5.18 模板嵌套语句#include
4.5.19 宏定义语句#macro
4.5.20 宏引入语句#import
4.5.21 布局重写语句#layout #@layout
4.5.22 停止执行#stop
4.5.23 返回指令#return
4.5.24 行结束指令
4.5.25 读取文本资源函数read和readContent
4.5.26 解析模板parser
4.5.27 格式化函数fmt、format和formatter
4.5.28 宏调用方法call和callMacro
4.5.29 实例判断函数is、instanceOf和instance
4.5.30 求值函数eval和evaluate
4.5.31 随机数函数rand和random
4.5.32 类型转换函数
4.5.33 日期格式转换formatDate
4.6 模板语言扩展
4.6.1 资源加载器的使用
4.6.2 宏的使用
4.6.3 函数的使用
4.6.4 国际化的使用
4.6.5 静态类和静态方法的使用
4.6.6 Servlet集成
4.6.7 SpringMVC集成
4.7 本章总结
第5章 数据库访问层实践
5.1 数据访问层简介
5.2 常见数据库访问层介绍
5.2.1 Hibernate简介
5.2.2 Ibatis简介
5.2.3 JPA简介
5.2.4 DSL数据库访问层简介
5.3 TinyDsl设计方案
5.3.1 SQL抽象化设计
5.3.2 DSL风格SQL设计
5.3.3 SQL执行接口设计
5.3.4 执行接口实现介绍
5.4 数据库访问层示例
5.4.1 工程创建
5.4.2 准备工作
5.4.3 Hibernate示例
5.4.4 Ibatis示例
5.4.5 JPA示例
5.4.6 TinyDsl示例
5.5 本章总结
第6章 数据库扩展实践
6.1 数据库扩展简介
6.2 常见数据库扩展方案
6.2.1 DAO层
6.2.2 DataSource层
6.2.3 JDBC层
6.2.4 Proxy层
6.3 读写分离
6.3.1 读写分离
6.3.2 负载均衡
6.3.3 数据同步
6.4 分库分表
6.4.1 同库分表
6.4.2 不同库分表
6.5 开源方案介绍
6.5.1 TDDL
6.5.2 Routing4DB
6.5.3 TinyDbRouter
6.5.4 开源方案的对比
6.6 TinyDbRouter的设计和实现
6.6.1 设计目标
6.6.2 设计原理之接入层设计
6.6.3 设计原理之SQL解析层设计
6.6.4 设计原理之路由决策层设计
6.6.5 设计原理之执行层设计
6.6.6 实现
6.7 应用实践
6.7.1 读写分离示例
6.7.2 分库分表示例
6.7.3 集群事务示例
6.7.4 元数据示例
6.7.5 自定义扩展
6.7.6 常见FAQ
6.8 本章总结
第7章 服务层实践
7.1 服务层简介
7.1.1 传统服务层
7.1.2 Tiny服务层
7.2 Tiny服务层介绍
7.2.1 服务声明
7.2.2 服务注册
7.2.3 小结
7.3 本地服务层实践
7.3.1 服务描述
7.3.2 服务定义
7.3.3 服务收集与注册
7.3.4 服务执行
7.3.5 小结
7.4 远程服务实践
7.4.1 传统的远程服务
7.4.2 新的远程服务模式
7.4.3 多服务中心支持
7.4.4 新的远程服务实现
7.4.5 小结
7.5 本地服务调用示例
7.5.1 非Tiny框架调用示例
7.5.2 Tiny框架应用调用
7.6 远程服务配置示例
7.6.1 非Tiny框架配置示例
7.6.2 Tiny框架应用配置
7.7 本章总结
第8章 流程引擎实践
8.1 流程引擎简介
8.1.1 流程引擎的来历
8.1.2 解决方案
8.1.3 特性简介
8.2 流程引擎实现
8.2.1 流程组件
8.2.2 流程组件配置
8.2.3 流程组件管理
8.2.4 流程配置
8.2.5 流程管理
8.2.6 流程执行
8.3 流程引擎特性
8.3.1 流程可继承性
8.3.2 灵活的EL表达式
8.3.3 流程可重入
8.3.4 流程可转出
8.3.5 强大异常处理
8.4 流程编辑器
8.4.1 创建流程
8.4.2 界面说明
8.4.3 操作说明
8.5 本章总结
第9章 元数据实践
9.1 元数据简介
9.1.1 问题背景
9.1.2 解决途径
9.2 基础元数据设计
9.2.1 支持语言类型
9.2.2 标准数据类型
9.2.3 业务数据类型
9.2.4 标准字段
9.3 数据库元数据设计
9.3.1 表及索引
9.3.2 视图
9.4 元数据开发指南
9.4.1 元数据加载机制
9.4.2 元数据处理器
9.5 元数据开发实践
9.5.1 Eclipse插件
9.5.2 应用配置
9.5.3 生成方言模板
9.5.4 生成标准数据类型
9.5.5 生成业务数据类型
9.5.6 生成标准字段
9.5.7 生成数据库表
9.5.8 定义元数据
9.5.9 生成Java代码
9.5.10 生成SQL
9.6 本章总结
第10章 展现层开发实践
10.1 展示层简介
10.1.1 Servlet
10.1.2 JSP
10.1.3 模板语言
10.1.4 展示层常见问题
10.2 展示层方案设计
10.2.1 UI组件包开发
10.2.2 资源合并实践
10.2.3 避免重复代码
10.2.4 国际化问题
10.3 前端访问方案实践
10.3.1 组件包封装
10.3.2 宏接口定义
10.3.3 页面和布局编写
10.3.4 前端参数配置
10.4 本章总结
10.4.1 关键点:DRY原则的实现
10.4.2 关键点:JS文件的合并
10.4.3 关键点:CSS文件的合并
第11章 Web扩展实践
11.1 背景简介
11.2 监听器设计原理
11.2.1 应用配置管理
11.2.2 应用处理器(ApplicationProcessor)
11.2.3 Web监听器
11.2.4 监听器配置管理
11.3 过滤器设计原理
11.3.1 请求上下文(WebContext)
11.3.2 TinyFilter介绍
11.4 处理器设计原理
11.4.1 过滤器配置(TinyProcessorConfig)
11.4.2 过滤器配置管理(TinyProcessorConfigManager)
11.4.3 处理器管理接口(TinyProcessorManager
11.5 BasicTinyFilter类
11.5.1 拦截器接口
11.5.2 默认拦截器
11.6 SetLocaleTinyFilter类
11.6.1 Locale基础
11.6.2 Charset编码基础
11.6.3 Locale和charset的关系
11.6.4 设置locale和charset
11.6.5 使用方法
11.7 ParserTinyFilter类
11.7.1 基本使用方法
11.7.2 上传文件
11.7.3 高级选项
11.8 BufferedTinyFilter类
11.8.1 实现原理
11.8.2 使用方法
11.8.3 关闭buffer机制
11.9 LazyCommitTinyFilter类
11.9.1 什么是提交
11.9.2 实现原理
11.9.3 使用方法
11.10 RewriteTinyFilter类
11.10.1 概述
11.10.2 取得路径
11.10.3 匹配rules
11.10.4 匹配conditions
11.10.5 替换路径
11.10.6 替换参数
11.10.7 后续操作
11.10.8 重定向
11.10.9 自定义处理器
11.11 SessionTinyFilter类
11.11.1 概述
11.11.2 Session框架
11.11.3 Cookie Store
11.11.4 总结
11.12 SpringMVCTinyProcessor介绍
11.12.1 基于扩展协议的内容协商
11.12.2 约定开发
11.12.3 扩展协议
11.13 TinyWeb实践
11.13.1 准备工作
11.13.2 使用TinyHttpFilter
11.13.3 使用TinyProcessor
11.14 本章总结
第12章 Tiny统一界面框架实践
12.1 UIML简介
12.2 UIML开发指南
12.3 UIML使用实践
12.4 常见FAQ
12.5 本章总结
第13章 RESTful实践
13.1 RESTful简介
13.2 Spring RESTful实践
13.3 Tiny RESTful风格实践
13.4 Tiny RESTful实践
13.5 本章总结
附录A 相关资源
附录B 配置运行指南
|
內容試閱:
|
第1章 虚拟文件系统实践
VFS(Virtual File System),虚拟文件系统。那么什么是现实的文件系统,什么又是虚拟的文件系统呢?举个例子,我们的硬盘有C盘、D盘等,其下又有各种文件夹以及文件,那么我们认为它就是现实的文件系统;而虚拟文件系统呢,它是根据现实的文件系统,在内存中构建的一套虚拟系统,目的是方便我们程序操作现实的文件系统。可以说它(VFS)是我们对现实文件系统的一种抽象。
1.1 背 景 介 绍
一开始我们是没有做一个VFS的想法的,出于对Apache的绝对信任,我们选择了Apache VFS 2.0来作为Tiny框架的VFS解决方案。确实,它的API是统一的、优雅的,支持的协议种类也比较多,在简单评估之后,觉得就用它吧,总不能什么轮子都自己造。
于是Apache VFS就被依赖到框架,功能也完全良好。但是在压力测试的时候,却发现有内存泄露问题,DUMP一下内存,进行分析之后发现原来是Apache VFS 2.0惹的祸,看一看Apache VFS已经好久没有升级了,通过跟踪源码,发现有些地方比较诡异,有时候进入有时候不进入,查之良久而不得。想自己修改吧,代码结构太过复杂,尝试了几次没有成功,只好下决定把Apache VFS从里面拿掉,而拿掉之后,就需要实现类似的功能,不得已才决定自己写一个VFS。
1.2 什么是VFS
VFS(Virtual File System)的作用就是按照提供统一文件处理接口来访问不同来源的不同文件,即为各类文件系统提供了一个统一的操作界面和应用编程接口。VFS是一个可以使文件访问不用关心底层的存储方式及来源类型就可以工作的中间层。
一般来说,VFS框架都会设计一个FileObject(或类似)接口。它代表一个文件对 象,和Java的File类不同,它具有更多延伸的功能和信息,可以用来定义任何来源的文件对象。每个FileObject对象代表一个逻辑文件,能够被用来访问逻辑文件的内容和位置等信息。
1.3 VFS对比
Apache VFS是一款比较优秀的开源框架,提供了非常全面的功能支持;而Tiny VFS 则实现了几个主要的功能,同时提供了一套自定义扩展方案,接口清晰简洁。下面我们从功能点、代码量等方面对两者来做个对比。
1.3.1 Apache VFS
Apache VFS提供了一种虚拟文件系统,能够让你通过程序很方便地和本地文件、FTP文件及HTTP文件打交道。
从图1-1可以看出,真正的Java代码有21915行,如果包含注释就是40914行,代码规模还是非常大的。
图1 1 代码行1
1.3.2 Tiny VFS
Tiny的VFS框架,虽然支持的Schema较Apache VFS 稍少,但是主要功能都已实现,用户也可以根据需要自行扩展其他的模式提供者。
支持的Schema:
?JarSchemaProvider,注册本地jar模式提供者;
?WsJarSchemaProvider,注册wsjar协议的模式提供者;
?ZipSchemaProvider,注册本地zip模式提供者;
?FileSchemaProvider,注册file协议的模式提供者;
?HttpSchemaProvider,注册http协议的模式提供者;
?HttpsSchemaProvider,注册https协议的模式提供者;
?JBossVfsSchemaProvider,注册vfs虚拟协议的模式提供者;
?FtpSchemaProvider,注册ftp协议的模式提供者。
从图1-2可以看出,Java代码只有1523行,包含注释也不过2505行,代码结构更清晰、简洁,可维护性更强。
图1 2 代码行2
1.4 VFS框架设计思想
前面介绍了虚拟文件系统(VFS)的基础定义,以及Apache VFS和Tiny VFS。计算机技术发展的早期阶段,还没有网络概念,文件存储只能在本地。后来随着局域网和互联网的出现,程序员可以通过网络协议远程访问文件;而现在云存储的兴起,使得文件的操作更加简单:程序员甚至不用关心文件的真实物理位置,通过虚拟的云地址就可以完成 所有操作。如果针对不同的文件来源就要在程序中编写相应的处理代码,势必会导致开 发成本上升,维护升级困难,因此虚拟文件系统(VFS)的出现是计算机技术发展的必然结果。
VFS框架的出现,有如下几点优点:
?统一文件资源的访问方式,简化应用资源的开发。程序员不用关心文件是本地文件、FTP远端文件还是第三方运营商提供的云存储文件。
?屏蔽应用层通信协议和底层文件格式的差异,甚至隐藏不同客户端的代码差异。
?采用接口方式定义VFS,也方便以后对新协议的扩展,符合软件开发的开闭原则。
对一个虚拟文件系统而言,最基础的概念有三点:VFS管理器、SchemaProvider模式提供者和FileObject虚拟文件访问接口。三者关系如图1-3所示。
图1 3 VFS框架设计图
程序员可以通过VFS管理器获取指定路径的FileObject对象,但是实际上VFS自己不做具体的事情,它委托注册在VFS中的模式提供者做实际的解析,并将解析到的结果,也就是虚拟文件对象返回给调用者。
VFS管理器类似于总包,模式提供者相当于分包,FileObject对象就是最终结果。总包(VFS管理器)本身不做任何具体工作,它负责管理和对外对接,所有的具体工作都是分配给自己的分包(模式提供者)完成。接到一个任务,它会依次询问每个模式提供者是不是其职能范围:如果是,则委派这个分包完成工作任务;不是的话,就问下一个模式提供者;万一问到最后也没有模式提供者能完成的话,VFS管理器就会使用默认的模式提供者去完成工作任务。
开发者可以通过扩展并把扩展的新的模式提供者注册到VFS管理器,然后就可以通过VFS管理器解析特定来源的文件了。
1.5 VFS实现讲解
这里列举了几个重要的接口,来说明VFS的实现原理。
1.5.1 VFS管理器
VFS管理器是作为工具类提供的,因此采用静态工具类的方式进行展示。核心方法如表1-1所示。
表1 1 VFS方法说明
方 法 名方 法 说 明
addSchemaProvider增加新的模式提供者
getSchemaProvider根据模式名称获取对应的模式提供者
setDefaultSchemaProvider设置默认的模式提供者
resolveFile根据String类型的协议地址解析FileObject
resolveURL根据URL类型的协议地址解析FileObject
为了便于开发人员使用,VFS管理器内置了一些模式提供者,以支持常见的文件来源协议,如下:
static {
addSchemaProvidernew JarSchemaProvider;注册本地jar模式提供者
addSchemaProvidernew WsJarSchemaProvider;注册wsjar协议的模式 提供者
addSchemaProvidernew ZipSchemaProvider;注册本地zip模式提供者
addSchemaProvidernew FileSchemaProvider;注册file协议的模式提供者
addSchemaProvidernew HttpSchemaProvider;注册http协议的模式提供者
addSchemaProvidernew HttpsSchemaProvider;注册https协议的模式 提供者
addSchemaProvidernew FtpSchemaProvider;注册ftp协议的模式提供者
addSchemaProvidernew JBossVfsSchemaProvider;
注册其他vfs虚拟协议的模式提供者
}
通过addSchemaProvider方法,开发人员可以给VFS管理器增加新的模式提供者,从而扩展对新的URL协议或者格式的处理能力。
VFS管理器解析URL过程如下:
(1)根据资源路径path从缓存容器fileObjectCacheMap查询是否存在已经被解析的FileObject对象,如果存在,则进一步判断该对象是不是包资源和最近的修改时间戳,如果是没有被修改的包资源(FileObject对象)就直接返回,否则继续下一步。
(2)对资源路径resource进行转码。
(3)设置schemaProvider变量为默认的SchemaProvider模式提供者。
(4)遍历schemaProviderMap容器,判断模式提供者是否能处理资源路径resource,如果能处理,则设置schemaProvider变量为当前的模式提供者,并中断循环。
(5)调用schemaProvider的resolver接口,获得FileObject对象。
(6)判断FileObject对象是不是包资源,如果是则放入缓存容器,并记录修改的时 间戳。
(7)返回解析结果。
resolveFile代码示例如下:
public static FileObject resolveFileString resourceResolve {
String resource=resourceResolve;
根据协议地址从缓存中查询FileObject
FileObject fileObject = fileObjectCacheMap.getresource;
if fileObject != null fileObject.isInPackage {
检查FileObject的最近修改时间戳和缓存中的是否一致,如果一致的话就直接返回 结果
long oldTime = fileModifyTimeMap.getresource;
long newTime = fileObject.getLastModifiedTime;
if oldTime == newTime {
return fileObject;
}
}
取得默认的模式提供者FileSchemaProvider
SchemaProvider schemaProvider = schemaProviderMap.getdefaultSchema;
for SchemaProvider provider : schemaProviderMap.values {
遍历模式提供者,判断协议地址是否匹配当前模式提供者
if provider.isMatchresource {
schemaProvider = provider;
break;
}
}
返回解析结果
fileObject = schemaProvider.resolverresource;
如果fileObject是包资源,则更新fileObject缓存和时间戳信息
if fileObject != null fileObject.isInPackage {
fileObjectCacheMap.putresource, fileObject;
fileModifyTimeMap.putresource, fileObject.getLastModifiedTime;
}
return fileObject;
}
从解析效率和优化性能的角度出发,VFS管理器在解析匹配虚拟文件时使用了缓存 机制:会优先根据路径从缓存中获取资源,避免重复解析资源。如果是包资源(如jar 包、zip包),只要资源没有被修改,也只会被解析一次,从而提升整体性能,提升查找 速度。
1.5.2 SchemaProvider模式提供者
模式提供者是虚拟文件解析的执行者,由VFS管理器调度。如果需要解析新的模式,只需要实现对应的SchemaProvider接口,并注册到VFS管理器即可,接口方法说明如表1-2所示。
表1 2 SchemaProvider方法说明
方 法 名方 法 说 明
getSchema返回处理的模式
isMatch是否匹配。如果返回true,则表示此提供者可以处理;返回false表示不能处理
resolver解析资源,并返回文件对象
|
|