“开源中国”知名博主“悠然”扛鼎大作!作者在开源中国开博两年,博客浏览量近百万次!
开源中国创始人红薯先生、特赞CTO黄勇先生、恒生电子CTO范径武先生倾情作序并推荐!
图书正式上市前一周作者博客预售,300多读者已经付款购买!
奉行“好的软件架构是‘品’出来的,好的软件架构一定是简单的”的原则写作!
本书是一本怎样的书?
1. 基于Java EE技术路线;
2. 面向企业级应用;
3. 以实践为主,每章解决一个具体问题,每章都提供开发案例;
4. 重点解决企业级架构中的问题及其解决方案;
5.可以保证书中的问题解决方案一定是相当不错的解。
特色鲜明,上乘之作!
1. 全面涵盖缓存、文件处理、模板语言、服务层、数据库架构、数据库水平扩展、元数据、Web架构、前端界面等企业级应用架构技术;
2. 提供大量的原创实践及原理性讲述,让读者对企业级Java EE架构有较为深入的理解;
3. 每章解决一个具体问题,采用“问题背景→需求分析→解决思路→架构设计→实践示例→章节总结”的顺序组织内容;
4. 注重内容的实用性和可操作性,每章都给出了实践性很强的开发案例。
《企业级Java EE架构设计精深实践》全面、深入介绍了企业级Java EE设计的相关内容,内容涵盖了Java EE架构设计的常见问题。《企业级Java EE架构设计精深实践》每一章讲解一个Java EE领域的具体问题,采用问题背景、需求分析、解决思路、架构设计、实践示例和章节总结的顺序组织内容,旨在通过分析相关领域中的常用框架及存在问题,给出相应的解决方案,提高读者分析和解决问题的能力,并增强其架构设计的能力。
《企业级Java EE架构设计精深实践》共13章。内容主要包括虚拟文件系统实践、缓存实践、文件处理框架实践、模板语言实践、数据库访问层实践、数据库扩展实践、服务层实践、流程引擎实践、元数据实践、展现层开发实践、Web扩展实践、Tiny统一界面框架实践和RESTful实践。附录中给出了相关学习资源和配置运行指南。
《企业级Java EE架构设计精深实践》语言简洁,思路清晰,示例丰富、完整,适合具有一定Java基础的读者阅读,尤其适合从事企业级Java EE软件架构和设计的人员阅读。
快速了解本书13个技术专题:
虚拟文件系统实践
缓存实践
文件处理框架实践
模板语言实践
数据库访问层实践
数据库扩展实践
服务层实践
流程引擎实践
元数据实践
展现层开发实践
Web扩展实践
Tiny统一界面框架实践
RESTful实践
第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 {
addSchemaProvider(new JarSchemaProvider());//注册本地jar模式提供者
addSchemaProvider(new WsJarSchemaProvider());//注册wsjar协议的模式 提供者
addSchemaProvider(new ZipSchemaProvider());//注册本地zip模式提供者
addSchemaProvider(new FileSchemaProvider());//注册file协议的模式提供者
addSchemaProvider(new HttpSchemaProvider());//注册http协议的模式提供者
addSchemaProvider(new HttpsSchemaProvider());//注册https协议的模式 提供者
addSchemaProvider(new FtpSchemaProvider());//注册ftp协议的模式提供者
addSchemaProvider(new 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 resolveFile(String resourceResolve) {
String resource=resourceResolve;
//根据协议地址从缓存中查询FileObject
FileObject fileObject = fileObjectCacheMap.get(resource);
if (fileObject != null && fileObject.isInPackage()) {
//检查FileObject的最近修改时间戳和缓存中的是否一致,如果一致的话就直接返回 结果
long oldTime = fileModifyTimeMap.get(resource);
long newTime = fileObject.getLastModifiedTime();
if (oldTime == newTime) {
return fileObject;
}
}
//取得默认的模式提供者FileSchemaProvider
SchemaProvider schemaProvider = schemaProviderMap.get(defaultSchema);
for (SchemaProvider provider : schemaProviderMap.values()) {
//遍历模式提供者,判断协议地址是否匹配当前模式提供者
if (provider.isMatch(resource)) {
schemaProvider = provider;
break;
}
}
//返回解析结果
fileObject = schemaProvider.resolver(resource);
//如果fileObject是包资源,则更新fileObject缓存和时间戳信息
if (fileObject != null && fileObject.isInPackage()) {
fileObjectCacheMap.put(resource, fileObject);
fileModifyTimeMap.put(resource, fileObject.getLastModifiedTime());
}
return fileObject;
}
从解析效率和优化性能的角度出发,VFS管理器在解析匹配虚拟文件时使用了缓存 机制:会优先根据路径从缓存中获取资源,避免重复解析资源。如果是包资源(如jar 包、zip包),只要资源没有被修改,也只会被解析一次,从而提升整体性能,提升查找 速度。
1.5.2 SchemaProvider模式提供者
模式提供者是虚拟文件解析的执行者,由VFS管理器调度。如果需要解析新的模式,只需要实现对应的SchemaProvider接口,并注册到VFS管理器即可,接口方法说明如表1-2所示。
表1 2 SchemaProvider方法说明
方 法 名 方 法 说 明
getSchema 返回处理的模式
isMatch 是否匹配。如果返回true,则表示此提供者可以处理;返回false表示不能处理
resolver 解析资源,并返回文件对象
第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 配置运行指南
这本书主要是通过对比各种流行的框架和技术来展示Tiny框架强悍又便利的优点。从前端模板展现、数据库访问、缓存,再到文件系统、服务分层、流程引擎、元数据和RESTful,同时还延伸到了系统扩展,可以说是面面俱到。 这本书在介绍Tiny框架的同时对与其对应的一些Java EE开源框架或技术也做了简单的讲解,同时包括对同类产品的分析。以悠然如此善于深入分析各类产品的技术来看,可知对这些问题领域的分析及其解决方案便是本书的精华所在,不得不推荐!
——开源中国创始人 红薯
Tiny框架的作者悠然是一位乐于分享的技术专家,他在“开源中国社区”上分享了大量的技术文章。现在Tiny团队将他们几年的研究成果成书,并毫无保留地分享给各位技术爱好者。我也非常荣幸地提前看到了全书内容,相信本书一定会让您在架构和设计方面有所收获。
——特赞(tezign.com)CTO 黄勇
本书得益于作者的深厚功底及勇敢实践,并以企业应用中遇到的十多个真实应用场景作为主题进行架构实践,对这些主题按问题概述、分析问题、解决问题的过程进行了有益探索。书中的问题解决方案可以保证是相当不错的解,应该说都体现了作者在这方面所做的努力。
——恒生电子执行总裁/CTO 范径武