Spring高級程式設計

Spring高級程式設計

Spring是一個完整的J2EE框架和解決方案,完整並且模組化,你可以用的他的全部也可以只用他的一部分特性,Spring 包含 IoC, AOP, 事務處理,ORM, 當然也包括一個簡單的MVC框架。作為最強大、套用最廣泛的企業級Java開發框架,Spring因其強大的適應性和可擴展性而適用於各種企業級系統。

基本信息

摘要

本書對Spring開發框架的核心概念及關鍵模組進行了深入剖析,並結合示例展示了它們的具體套用。本書共分 4部分。第一部分介紹 Spring框架的基礎知識,重點闡述了 AOP和 IOC的基本概念;第二部分介紹 Spring對數據持久化的支持,從基礎的 JDBC開始,講解了 Spring對套用最廣泛的 ORM框架 iBATIS和 Hibernate的支持;第三部分闡述了 Spring企業級組件,介紹了任務調度、Mail服務、動態語言等企業級組件相關的知識;第四部分闡述如何使用 Spring進行 Java EE 5開發,從遠程調用和事務管理開始,接著介紹了 Spring MVC、Web工作流、AJAX、JMX、單元測試以及性能調優等 Java EE相關開發知識。

本書由 Spring框架核心開發人員撰寫,適合各層次 Java開發人員,特別是企業級 Java開發人員閱讀參考。

目錄

第一部分 Spring入門

第1章 Spring簡介 2

1.1 Spring是什麼 2

1.1.1 依賴注入之外的特性 4

1.1.2 使用Spring進行面向方面編程 4

1.1.3 數據訪問 5

1.1.4 簡化與整合Java EE 5

1.1.5 基於Spring的任務調度 6

1.1.6 Spring對郵件的支持 6

1.1.7 動態語言 6

1.1.8 遠程訪問 6

1.1.9 事務管理 7

1.1.10 Spring MVC框架 7

1.1.11 Spring Web Flow 7

1.1.12 AJAX技術 7

1.1.13 國際化 8

1.1.14 簡化異常處理 8

1.2 Spring項目 8

1.2.1 Spring的起源 8

1.2.2 Spring .NET 8

1.2.3 Spring IDE 9

1.2.4 Spring安全系統(原Acegi) 9

1.2.5 Spring的替代方案 9

1.3 示例代碼 10

1.4 小結 10

第2章 Spring入門 11

2.1 獲取Spring框架 11

2.1.1 從CVS上籤出Spring 11

2.1.2 從源碼構建Spring 12

2.1.3 檢查Spring發布包 13

2.1.4 Spring發布包 13

2.1.5 Spring依賴的包 14

2.1.6 示例套用 16

2.1.7 配置Spring和IDE 18

2.2 HelloWorld示例 20

2.3 Spring版本的“Hello, World”示例 23

2.3.1 依賴注入 24

2.3.2 Spring的侵入性 26

2.4 小結 26

第3章 控制反轉 27

3.1 控制反轉和依賴注入 27

3.2 控制反轉的類型 27

3.2.1 上下文依賴查找 29

3.2.2 構造方法依賴注入 30

3.2.3 設定方法依賴注入 31

3.2.4 依賴注入與依賴查找 32

3.2.5 設定方法注入與構造方法注入 33

3.3 Spring中的控制反轉 34

3.4 基於Spring的依賴注入 34

3.4.1 bean和BeanFactory 34

3.4.2 BeanFactory實現 35

3.4.3 XML bean定義 36

3.4.4 構造方法注入 37

3.4.5 注入參數 40

3.4.6 理解bean的命名 50

3.4.7 bean的實例化模式 52

3.4.8 解析依賴 55

3.4.9 bean的自動裝配 57

3.4.10 依賴檢查 61

3.4.11 bean的繼承 62

3.5 小結 64

第4章 進階 66

4.1 Spring對應用程式可移植性的影響 67

4.2 管理bean的生命周期 67

4.2.1 嵌入bean的創建 68

4.2.2 嵌入bean的銷毀 74

4.3 讓bean可被Spring感知 79

4.3.1 使用BeanNameAware接口 80

4.3.2 使用BeanFactoryAware接口 81

4.4 使用方法注入(method injection) 83

4.4.1 查找方法注入 83

4.4.2 方法替換 88

4.5 使用FactoryBean接口 91

4.5.1 MessageDigestFactoryBean類 91

4.5.2 直接訪問FactoryBean 94

4.6 BeanFactoryPostProcessor類 94

4.7 JavaBean的屬性修改器 101

4.7.1 內建的PropertyEditor 101

4.7.2 創建自定義PropertyEditor 104

4.8 BeanPostProcessor類 108

4.8.1 實現一個BeanPostProcessor 110

4.8.2 使用BeanPostProcessor類的實機選擇 114

4.9 Spring ApplicationContext 115

4.9.1 ApplicationContext的實現類 115

4.9.2 使用ApplicationContext-Aware 116

4.9.3 控制bean的初始化 117

4.9.4 使用基於註解的配置 118

4.9.5 使用MessageSource進行國際化 123

4.9.6 在獨立套用中使用MessageSource 130

4.9.7 MessageSourceResolvable接口 130

4.9.8 使用應用程式事件 130

4.9.9 對於事件用法的考慮 132

4.9.10 訪問資源 133

4.10 小結 134

第5章 Spring AOP基礎 135

5.1 AOP概念 136

5.2 AOP的類型 136

5.2.1 靜態AOP 137

5.2.2 動態AOP 137

5.2.3 選擇一種AOP類型 137

5.3 Spring中的AOP 137

5.3.1 AOP聯盟 138

5.3.2 AOP的Hello World 138

5.3.3 Spring AOP架構 140

5.3.4 ProxyFactory類 140

5.3.5 在Spring中創建通知 141

5.4 Spring里的通知者和切入點 155

5.4.1 切入點接口 156

5.4.2 使用ComposablePointcut 172

5.4.3 切入點總結 175

5.5 代理詳解 176

5.5.1 理解代理 176

5.5.2 使用JDK動態代理 176

5.5.3 使用CGLIB代理 177

5.5.4 兩者的性能比較 177

5.5.5 選用代理 180

5.6 小結 180

第6章 AOP進階 182

6.1 @AspectJ註解 182

6.2 @AspectJ方面詳解 186

6.2.1 切入點 186

6.2.2 切入點表達式 189

6.2.3 探討切入點表達式 191

6.2.4 在XML中使用@Pointcuts 194

6.2.5 通知的類型 194

6.2.6 參數綁定 201

6.2.7 引入 202

6.2.8 方面的生命周期 208

6.3 AOP的框架服務 209

6.3.1 使用AOP命名空間創建第一個方面 209

6.3.2 AOP命名空間中的切入點 211

6.3.3 使用AOP命名空間創建通知 212

6.3.4 AOP命名空間中的引入 217

6.4 風格選擇 219

6.5 使用Spring AOP代理 220

6.6 AspectJ集成 225

6.6.1 創建第一個AspectJ方面 225

6.6.2 編譯示例程式 227

6.6.3 AspectJ方面的作用域 229

6.7 載入時織入 230

6.7.1 第一個載入時織入示例 230

6.7.2 LoadTimeWeaver的查找策略 232

6.8 AOP實踐 232

6.9 小結 235

第7章 Spring schema與命名空間 236

7.1 新配置的緣由 236

7.2 Spring 2.5包含的schema 238

7.2.1 beans schema 238

7.2.2 上下文schema 239

7.2.3 util schema 239

7.2.4 tx schema 242

7.2.5 aop schema 242

7.2.6 jee schema 242

7.2.7 lang schema 243

7.3 schema背後 244

7.4 自定義schema 246

7.5 IDE配置 249

7.6 小結 252

第8章 Spring模式 253

8.1 目錄結構 253

8.1.1 簡單套用 253

8.1.2 複雜套用 255

8.1.3 打包和命名 255

8.2 設計模式簡介 255

8.2.1 面向接口編程 256

8.2.2 創建模式 256

8.2.3 結構模式 260

8.2.4 行為模式 262

8.3 Spring套用模式 264

8.3.1 分層設計 265

8.3.2 高性能分頁 266

8.3.3 多錯誤報告 268

8.3.4 用戶界面事務 271

8.3.5 後台進程 274

8.3.6 郵件通知 278

8.3.7 錯誤收集和日誌 280

8.4 小結 283

第二部分 數據訪問

第9章 Spring對JDBC的支持 286

9.1 JDBC的主要概念 286

9.1.1 使用DriverManager和Connection 288

9.1.2 使用PreparedStatement 289

9.1.3 使用CallableStatement類 292

9.1.4 其他JDBC概念 293

9.2 Spring對數據訪問支持的概念 293

9.3 Spring對JDBC數據訪問的支持 294

9.4 使用JdbcTemplate類 294

9.4.1 JdbcTemplate類的execute方法 296

9.4.2 JdbcTemplate類的query方法和該方法的擴展 299

9.4.3 JdbcTemplat類的update方法 303

9.4.4 JdbcTemplate類的batchUpdate方法 304

9.5 RdbmsOperation子類 305

9.5.1 SqlUpdate子類 306

9.5.2 BatchSqlUpdate子類 311

9.5.3 SqlCall類和StoredProcedure子類 312

9.5.4 SqlQuery類和它的子類 314

9.5.5 JdbcTemplate類和RdbmsOperation類的比較 321

9.6 大二進制對象 321

9.7 JdbcDaoSupport類 324

9.8 簡單的Spring JDBC 326

9.8.1 SimpleJdbcTemplate類 326

9.8.2 SimpleJdbcCall類 329

9.8.3 SimpleJdbcInsert類 331

9.8.4 SimpleJdbcDaoSupport類 332

9.9 小結 333

第10章 集成iBATIS 334

10.1 iBATIS簡述 334

10.1.1 iBATIS版本 334

10.1.2 基礎架構和配置 335

10.2 映射檔案 335

10.2.1 sqlMap檔案 337

10.2.2 配置iBATIS和Spring 339

10.3 查詢數據 341

10.3.1 簡單查詢操作 341

10.3.2 一對一查詢操作 344

10.3.3 一對多查詢操作 348

10.3.4 多對多查詢操作 350

10.4 更新數據 350

10.5 刪除數據 353

10.6 插入數據 354

10.7 iBATIS缺少的特性 356

10.8 整體性能 357

10.9 小結 358

第11章 Spring對Hibernate的支持 359

11.1 Hibernate入門 359

11.2 Hibernate打包 360

11.3 Hibernate支持的介紹 361

11.3.1 使用Hibernate Session 363

11.3.2 使用HibernateDaoSupport類 366

11.3.3 HibernateTemplate和Session間的選擇 368

11.4 在企業級應用程式中使用Hibernate 372

11.4.1 阻止更新髒數據 372

11.4.2 對象等價性 375

11.4.3 事務支持 378

11.4.4 延遲載入 382

11.5 處理大數據集 392

11.6 處理大對象 394

11.7 使用Hibernate處理其他DAO代碼 397

11.8 小結 398

第三部分 企業級套用組件

第12章 基於Spring的任務調度 400

12.1 使用JDK Timer調度任務 401

12.1.1 Timer觸發器類型 401

12.1.2 創建一個簡單任務 401

12.1.3 Spring對JDK Timer調度的支持 404

12.2 使用OpenSymphony Quartz來調度任務 409

12.2.1 Quartz簡介 410

12.2.2 Spring對Quartz的支持 418

12.3 任務調度時需考慮的因素 423

12.3.1 選擇一個調度器 423

12.3.2 剝離Job類中的任務邏輯 424

12.3.3 任務執行和執行緒池 424

12.4 小結 428

第13章 Spring的郵件支持 429

13.1 Spring Mail API結構 430

13.2 傳送簡單的電子郵件 430

13.2.1 編程式構造和傳送電子郵件 431

13.2.2 聲明式構造電子郵件 433

13.3 構造並傳送MIME訊息 436

13.3.1 傳送基本的HTML訊息 438

13.3.2 傳送帶有內嵌圖片的HTML訊息 439

13.3.3 傳送帶有附屬檔案的訊息 441

13.3.4 傳送帶有可替換純文本的HTML訊息 442

13.3.5 傳送複雜MIME訊息 445

13.4 深入了解企業級電子郵件處理 449

13.5 小結 458

第14章 動態語言 459

14.1 支持的動態語言概覽 459

14.1.1 BeanShell 459

14.1.2 Groovy 461

14.1.3 JRuby 462

14.2 使用動態語言定義Spring bean 463

14.2.1 動態語言支持的幕後 465

14.2.2 代理動態語言bean 466

14.2.3 性能 466

14.3 可刷新bean(refreshable bean) 468

14.4 基於BeanShell的bean 470

14.5 基於JRuby的bean 472

14.6 基於Groovy的bean 473

14.7 動態語言在Spring程式中的典型套用 473

14.8 小結 477

第四部分 Java EE 5套用開發

第15章 Spring遠程訪問 480

15.1 Spring Remoting架構 481

15.2 遠程方法調用 482

15.2.1 開放任意的服務 482

15.2.2 通過代理訪問RMI服務 484

15.2.3 開放CORBA服務 486

15.2.4 訪問CORBA服務 488

15.3 使用JAX-RPC實現Web服務 490

15.3.1 Apache Axis簡介 490

15.3.2 使用ServletEndpoint- Support創建Web服務 490

15.3.3 使用代理訪問RPC風格的Web服務 494

15.3.4 與Axis服務的JavaBean互動 497

15.4 使用JAX-WS Web服務 500

15.4.1 通過SimpleJaxWsService-Exporter公開Web服務 501

15.4.2 使用XFire公開Web服務 501

15.4.3 訪問JAX-WS Web服務 503

15.4.4 從其他客戶端訪問Java Web服務 504

15.5 使用HTTP Invoker創建Web服務 507

15.5.1 開發簡單服務 508

15.5.2 通過代理訪問HTTP Invoker服務 510

15.5.3 在HTTP Invoker服務中使用任意對象 511

15.5.4 使用HTTP基本認證 513

15.6 遠程架構的選擇 516

15.7 小結 517

第16章 事務管理 518

16.1 Spring事務抽象層簡介 518

16.2 分析事務屬性 519

16.2.1 探索TransactionDefinition接口 519

16.2.2 使用TransactionStatus接口 520

16.2.3 PlatformTransactionManager的實現 521

16.3 對一個事務管理示例的探索 521

16.4 編程式事務管理 529

16.4.1 使用TransactionTemplate類 531

16.4.2 編程式事務管理小結 532

16.5 聲明性事務管理 532

16.5.1 使用TransactionProxy-FactoryBean 532

16.5.2 在事務管理中使用代理的含義 534

16.6 AOP事務管理 535

16.6.1 使用基於註解的AOP事務管理 535

16.6.2 使用XML AOP事務管理 537

16.6.3 tx:advice標籤簡介 538

16.6.4 XML AOP小結 539

16.7 在多個事務性資源上使用事務 540

16.8 實現你自己的事務同步 541

16.9 小結 548

第17章 基於Spring MVC的Web套用開發 549

17.1 MVC架構 549

17.2 Spring MVC介紹 550

17.3 使用處理器映射 551

17.4 Spring控制器 553

17.4.1 AbstractController類 554

17.4.2 ParameterizableView-Controller類 555

17.4.3 MultiActionController類 555

17.5 攔截器 558

17.6 視圖、本地化和主題 559

17.6.1 以編程的方式使用視圖 559

17.6.2 使用視圖解析器 561

17.6.3 使用本地化訊息 565

17.6.4 使用Locale 565

17.6.5 使用主題 565

17.7 命令控制器 567

17.7.1 使用表單控制器 568

17.7.2 探索AbstractWizardForm- Controller 類 574

17.7.3 檔案上傳 578

17.8 處理異常 581

17.9 Spring與其他Web技術 583

17.9.1 使用JSP 583

17.9.2 使用Velocity 600

17.9.3 FreeMarker 604

17.9.4 使用XSLT視圖 608

17.9.5 使用PDF視圖 609

17.9.6 實現PDF視圖 610

17.9.7 使用Excel視圖 611

17.9.8 使用Tiles 613

17.9.9 JasperReports報表引擎 623

17.10 Spring的約定優於配置 627

17.10.1 控制器約定 628

17.10.2 MultiActionController約定 628

17.10.3 模型約定 629

17.10.4 視圖約定 630

17.11 使用註解配置控制器 631

17.11.1 @Controller註解 631

17.11.2 @RequestMapping註解 632

17.11.3 @RequestParam註解 633

17.11.4 @ModelAttribute註解 633

17.11.5 使用註解配置命令控制器 634

17.12 小結 635

第18章 Spring Web Flow 636

18.1 Spring Web Flow簡介 637

18.1.1 核心概念 637

18.1.2 獲取Spring Web Flow 640

18.1.3 Spring Web Flow依賴 642

18.2 Hello, Web Flow! 642

18.3 探索狀態 646

18.3.1 view狀態 647

18.3.2 decision狀態 647

18.3.3 end狀態 648

18.4 處理轉換 648

18.5 高級概念 650

18.5.1 表達式語言和範圍 650

18.5.2 實現action 653

18.5.3 模型數據綁定 654

18.5.4 局部視圖刷新 658

18.5.5 映射流的輸入與輸出參數 658

18.5.6 使用子流 659

18.6 幕後的Spring Web Flow 660

18.6.1 流執行架構 660

18.6.2 流執行者 662

18.6.3 流定義註冊表 662

18.6.4 流執行倉庫 665

18.7 集成Spring MVC 666

18.7.1 流處理 666

18.7.2 視圖解析 667

18.8 使用Spring Security構建安全的流 668

18.8.1 第一步:添加SecurityFlow- ExecutionListener 668

18.8.2 第二步:處理基本的認證和授權 668

18.8.3 第三步:在流定義中定義安全規則 670

18.9 問題解決 672

18.9.1 帶狀態的導航控制 672

18.9.2 瀏覽器導航欄支持和雙提交(double submit) 672

18.10 測試流定義 673

18.11 小結 674

第19章 Spring與AJAX 675

19.1 DWR 675

19.2 安裝DWR 676

19.3 針對DWR的Spring配置 676

19.4 關於完整示例 677

19.5 測試DWR配置 682

19.6 運行完整示例 682

19.7 DWR腳本基礎 683

19.7.1 使用簡單的回調函式 683

19.7.2 調用元數據對象 684

19.8 engine.js檔案 684

19.8.1 調用批處理 684

19.8.2 調用順序 684

19.8.3 錯誤和警告處理 684

19.9 util.js腳本 685

19.10 DWR的安全性 685

19.11 DWR的優缺點 686

19.12 小結 687

第20章 使用Spring JMX 688

20.1 JMX進階 688

20.2 開放Java Bean 689

20.2.1 MBeanExporter類 689

20.2.2 MBeanServer FactoryBean類 691

20.2.3 在已有的MBean伺服器上開放Bean 692

20.2.4 Bean註冊行為 692

20.3 控制對象名 693

20.4 控制管理接口 693

20.4.1 MBeanInfoAssembler接口 693

20.4.2 MethodNameBasedMBean-InfoAssembler接口 694

20.4.3 用Java接口來控制管理接口 696

20.4.4 使用源碼級元數據 698

20.5 遠程使用Spring JMX 701

20.5.1 開放遠程MBean 701

20.5.2 訪問遠程MBean 702

20.5.3 代理MBean 702

20.6 Spring JMX通知 703

20.6.1 通知監聽器 703

20.6.2 發布通知 704

20.7 小結 708

第21章 使用Spring進行測試 709

21.1 進行單元測試 709

21.2 單元測試 711

21.3 集成測試 715

21.3.1 使用AbstractSpring- ContextTests 722

21.3.2 使用AbstractDependency- InjectionSpringContext-Tests類 723

21.3.3 使用AbstractTransac-tionalSpringContextTest 726

21.3.4 使用AbstractAnnotation-AwareTransactionalTest 728

21.3.5 JNDI 731

21.4 Spring TestContext Framework 733

21.4.1 套用上下文及使用TestContext Framework進行依賴注入 733

21.4.2 使用TestContext Framework進行依賴注入 735

21.4.3 TestContext Framework中的事務 736

21.4.4 支持類 738

21.5 測試覆蓋 740

21.6 小結 740

第22章 Spring性能調優 741

22.1 性能與回響 741

22.2 探索企業套用的性能問題 741

22.3 測量Java EE套用的性能 742

22.3.1 測量目標 742

22.3.2 確定必要的數據集 747

22.3.3 改善數據訪問層 748

22.3.4 提高事務管理 757

22.3.5 控制遠程調用的性能 758

22.3.6 了解視圖性能 758

22.4 使用快取 759

22.5 性能測試 760

22.6 監控應用程式的狀態和性能 762

22.7 更多的性能調優資源 764

22.8 小結 764

序言

我最終決定不參加編寫本書時,心情萬分沉重。在這裡我要感謝Jan,是他挺身而出,組織編寫了本書。在過去三年中,Pro Spring已成為我生活的重要組成部分,最後放棄絕不是揮一揮衣袖那么輕鬆。由於我和Juergen還在為Spring框架2.0努力,我知道我沒有時間參與本書的寫作,畢竟軟體開發與寫作不能同時進行。幸運的是,Jan幫我完成了這個心愿。

當Jan和Apress出版社還計畫著發布Pro Spring 2.0時,我和Juergen已經對Spring框架進行了很多的變更,無意中導致他們很難跟上Spring的變化。我至今清楚地記得,在更新所有的JSP表單標籤時我有些難為情,我知道我給Jan增加了多少工作量。

Spring 2.5剛發布,Jan就做出了一個明智的選擇,放棄Spring 2.0而採用Spring 2.5。Spring框架2.5體現了Spring框架和企業級Java框架的最新進展。對所有勤勉認真的Java開發人員來說,這本關於這個重要工具的專業指南應該是必讀的。

我至今仍記得,在Cake解決方案起始,我們決定再聘請一個開發人員。總的來說我們缺乏招聘的經驗,招程式設計師更是難上加難。當時我們只是想招到個大學畢業生就不錯了,但是沒有想到就此找來的Jan是這么能幹。

在開始工作的第一個星期,他從頭編寫了一個桌面郵件程式包,順利地投入使用。在過去的5年中,Jan一直都是大部分Cake子項目的核心人物,其中多為基於Spring框架的大型Java產品。他的Spring知識來自於極其豐富的實踐經驗:自Spring 1.0版本以來,Jan一直在實際的項目中使用Spring並構建了成功的系統。

令我讚賞的是,Jan意識到編寫本書的工作量很大,僅靠他一個人不能完成,所以他組織了Cake解決方案組的其他成員來協助他。我感到格外興奮,有這樣一群真正的程式設計師、一群真正體會到Spring精髓的人來與大家分享知識,毫無疑問,很多人都會發現本書是不可缺少的參考書。

因此,儘管無法參與本書的編寫有些遺憾,但是我仍很高興,Jan出色地完成了許多人一直都在期盼的Pro Spring的更新版本。

希望大家盡情享受閱讀的樂趣!

前言

最近,Java業界發生了巨變,從如EJB(Enterprise JavaBean)的“重量級”架構體系向如Spring的輕量級框架遷移。Hibernate和AOP(面向方面編程)等更簡單的實現機制代替了複雜並且依賴容器的服務(如CMP)和事務管理系統。Spring核心層提供了一個完善的基於控制反轉(IoC)的輕量級容器,用戶可以使用它建立自己的應用程式。在容器上,Spring提供了大量實用的服務,將很多高質量開源項目集成到統一的框架上。

Spring框架的品質已經顯現,它在很多套用中已經取代了傳統的Java EE架構。因此,越來越多的開發者認識到需要對Spring技術有一個全面的了解。儘管Spring有著相當豐富的文檔資源和案例,但我們還是發現,仍然有許多開發者為了解如何使用Spring,特別是如何有效地運用Spring而苦苦探究。因此,我們決定為Pro Spring寫一個新版本。

起初,我們以為只需要在原有基礎上更新幾章即可推出Pro Spring 2.5。然而,我們很快就意識到,Spring 2.5帶來了許多新的功能和改進,雖然我們一直保持著Pro Spring的名字,但這卻是一本全新的書。

通過本書,你將學習如何使用Spring來建立更好的Web套用和單機套用,如何在框架中進行恰當的選擇。我們的目標是為你提供全面的知識,幫助你在自己的應用程式中有效地使用Spring,同時讓你更深入了解Spring的機制。

例如,你可以:

在AOP上下文中了解控制反轉的相關基礎知識;

通過查看簡單易懂的套用實例,了解Spring的強大功能和無縫集成能力;

學習如何使用包括基於AOP的Spring聲明式事務管理框架在內的Spring特性替換常用的EJB特性;

使用Spring內置的JMX引擎高效管理Spring組件和套用;

了解如何使用Quartz在Spring套用中實現任務調度。

閱讀完本書後,你將獲得使用Spring及其相關開源項目構建高效套用的所有知識。

致謝

任何書籍的編寫都需要進行大量的幕後工作,在作者身後,是一支由編輯、校對和技術審稿人組成的傑出團隊。本書也不例外,我們要感謝所有為本書付出心血的人。我們要感謝Rick,本書的技術審稿人,他盡心盡力的工作保證了本書的質量。感謝Apress出類拔萃的編輯團隊,特別是SofiaMarchant、Tom Welsh編輯、Heather Lang、Kelly Winquist等人。如果沒有他們的幫助,我們無法完成本書。同時,我們還要感謝Rob Harrop為本書作序。最後,我衷心地感謝Cake解決方案的總經理GuyRemond,是他讓我們的團隊可以占用一些工作時間撰寫本書!

相關詞條

相關搜尋

熱門詞條

聯絡我們