亚洲国产日韩欧美一区二区三区,精品亚洲国产成人av在线,国产99视频精品免视看7,99国产精品久久久久久久成人热,欧美日韩亚洲国产综合乱

Verzeichnis suchen
前言 簡(jiǎn)介 概覽 使用場(chǎng)景 Spring 2.0和 2.5的新特性 簡(jiǎn)介 控制反轉(zhuǎn)(IoC)容器 新的bean作用域 更簡(jiǎn)單的XML配置 可擴(kuò)展的XML編寫(xiě) Annotation(注解)驅(qū)動(dòng)配置 在classpath中自動(dòng)搜索組件 面向切面編程(AOP) 更加簡(jiǎn)單的AOP XML配置 對(duì)@AspectJ 切面的支持 對(duì)bean命名pointcut( bean name pointcut element)的支持 對(duì)AspectJ裝載時(shí)織入(AspectJ load-time weaving)的支持 中間層 在XML里更為簡(jiǎn)單的聲明性事務(wù)配置 對(duì)Websphere 事務(wù)管理的完整支持 JPA 異步的JMS JDBC Web層 Spring MVC合理的默認(rèn)值 Portlet 框架 基于Annotation的控制器 Spring MVC的表單標(biāo)簽庫(kù) 對(duì)Tiles 2 支持 對(duì)JSF 1.2支持 JAX-WS支持 其他 動(dòng)態(tài)語(yǔ)言支持 增強(qiáng)的測(cè)試支持 JMX 支持 將Spring 應(yīng)用程序上下文部署為JCA adapter 計(jì)劃任務(wù) 對(duì)Java 5 (Tiger) 支持 移植到Spring 2.5 改變 支持的JDK版本 Spring 2.5的Jar打包 XML配置 Deprecated(淘汰)的類和方法 Apache OJB iBATIS Hibernate JDO UrlFilenameViewController 更新的樣例應(yīng)用 改進(jìn)的文檔 核心技術(shù) IoC(控制反轉(zhuǎn))容器 簡(jiǎn)介 基本原理 - 容器和bean 容器 配置元數(shù)據(jù) 實(shí)例化容器 XML配置元數(shù)據(jù)的結(jié)構(gòu) 多種bean bean的命名 bean的別名 實(shí)例化bean 用構(gòu)造器來(lái)實(shí)例化 使用靜態(tài)工廠方法實(shí)例化 使用實(shí)例工廠方法實(shí)例化 使用容器 依賴 注入依賴 構(gòu)造器注入 構(gòu)造器參數(shù)解析 構(gòu)造器參數(shù)類型匹配 構(gòu)造參數(shù)索引 Setter注入 一些例子 依賴配置詳解 直接變量(基本類型、Strings類型等。) idref元素 引用其它的bean(協(xié)作者) 內(nèi)部bean 集合 集合的合并 強(qiáng)類型集合(僅適用于Java5+) Nulls XML配置文件的簡(jiǎn)寫(xiě)及其他 XML-based configuration metadata shortcuts 使用p名稱空間配置屬性 組合屬性名稱 使用depends-on 延遲初始化bean 自動(dòng)裝配(autowire)協(xié)作者 將bean排除在自動(dòng)裝配之外 依賴檢查 方法注入 Lookup方法注入 自定義方法的替代方案 Bean的作用域 Singleton作用域 Prototype作用域 Singleton beans和prototype-bean的依賴 其他作用域 初始化web配置 Request作用域 Session作用域 global session作用域 作用域bean與依賴 選擇創(chuàng)建代理的類型 自定義作用域 創(chuàng)建自定義作用域 使用自定義作用域 定制bean特性 生命周期回調(diào) 初始化回調(diào) 析構(gòu)回調(diào) 缺省的初始化和析構(gòu)方法 組合生命周期機(jī)制 在非web應(yīng)用中優(yōu)雅地關(guān)閉Spring IoC容器 了解自己 BeanFactoryAware BeanNameAware bean定義的繼承 容器擴(kuò)展點(diǎn) 用BeanPostProcessor定制bean 使用BeanPostProcessor的Hello World示例 RequiredAnnotationBeanPostProcessor示例 用BeanFactoryPostProcessor定制配置元數(shù)據(jù) PropertyPlaceholderConfigurer示例 PropertyOverrideConfigurer示例 使用FactoryBean定制實(shí)例化邏輯 The ApplicationContext BeanFactory 還是 ApplicationContext? 利用MessageSource實(shí)現(xiàn)國(guó)際化 事件 底層資源的訪問(wèn) ApplicationContext在WEB應(yīng)用中的實(shí)例化 粘合代碼和可怕的singleton 以J2EE RAR文件的形式部署Spring ApplicationContext 基于注解(Annotation-based)的配置 @Autowired 基于注解的自動(dòng)連接微調(diào) CustomAutowireConfigurer @Resource @PostConstruct 與 @PreDestroy 對(duì)受管組件的Classpath掃描 @Component和更多典型化注解 自動(dòng)檢測(cè)組件 使用過(guò)濾器自定義掃描 自動(dòng)檢測(cè)組件的命名 為自動(dòng)檢測(cè)的組件提供一個(gè)作用域 用注解提供限定符元數(shù)據(jù) 注冊(cè)一個(gè)LoadTimeWeaver 資源 簡(jiǎn)介 Resource接口 內(nèi)置 Resource 實(shí)現(xiàn) UrlResource ClassPathResource FileSystemResource ServletContextResource InputStreamResource ByteArrayResource ResourceLoader接口 ResourceLoaderAware 接口 把Resource作為屬性來(lái)配置 Application context 和Resource 路徑 構(gòu)造application context 創(chuàng)建 ClassPathXmlApplicationContext 實(shí)例 - 簡(jiǎn)介 Application context構(gòu)造器中資源路徑的通配符 Ant風(fēng)格的pattern 潛在的可移植性 classpath*: 前綴 其他關(guān)于通配符的說(shuō)明 FileSystemResource 說(shuō)明 校驗(yàn),數(shù)據(jù)綁定,BeanWrapper,與屬性編輯器 簡(jiǎn)介 使用Spring的Validator接口進(jìn)行校驗(yàn) 從錯(cuò)誤代碼到錯(cuò)誤信息 Bean處理和BeanWrapper 設(shè)置和獲取屬性值以及嵌套屬性 內(nèi)建的PropertyEditor實(shí)現(xiàn) 注冊(cè)用戶自定義的PropertyEditor 使用PropertyEditorRegistrars 使用Spring進(jìn)行面向切面編程(AOP) 簡(jiǎn)介 AOP概念 Spring AOP的功能和目標(biāo) AOP代理 @AspectJ支持 啟用@AspectJ支持 聲明一個(gè)切面 聲明一個(gè)切入點(diǎn)(pointcut) 切入點(diǎn)指示符(PCD)的支持 組合切入點(diǎn)表達(dá)式 共享通用切入點(diǎn)定義 示例 聲明通知 前置通知 后置通知(After returning advice) 異常通知(After throwing advice) 最終通知(After (finally) advice) 環(huán)繞通知 通知參數(shù)(Advice parameters) 訪問(wèn)當(dāng)前的連接點(diǎn) 傳遞參數(shù)給通知 確定參數(shù)名 處理參數(shù) 通知順序 引入(Introduction) 切面實(shí)例化模型 例子 基于Schema的AOP支持 聲明一個(gè)切面 聲明一個(gè)切入點(diǎn) 聲明通知 前置通知 后置通知 異常通知 最終通知 環(huán)繞通知 通知參數(shù) 通知順序 引入 切面實(shí)例化模型 Advisor 例子 AOP聲明風(fēng)格的選擇 Spring AOP還是完全用AspectJ? Spring AOP中使用@AspectJ還是XML? 混合切面類型 代理機(jī)制 理解AOP代理 以編程方式創(chuàng)建@AspectJ代理 在Spring應(yīng)用中使用AspectJ 在Spring中使用AspectJ進(jìn)行domain object的依賴注入 @Configurable對(duì)象的單元測(cè)試 Working with multiple application contexts Spring中其他的AspectJ切面 使用Spring IoC來(lái)配置AspectJ的切面 在Spring應(yīng)用中使用AspectJ加載時(shí)織入(LTW) 第一個(gè)例子 切面 'META-INF/aop.xml' 相關(guān)類庫(kù)(JARS) Spring配置 特定環(huán)境的配置 通用Java應(yīng)用 Tomcat WebLogic 更多資源 Spring AOP APIs 簡(jiǎn)介 Spring中的切入點(diǎn)API 概念 切入點(diǎn)運(yùn)算 AspectJ切入點(diǎn)表達(dá)式 便利的切入點(diǎn)實(shí)現(xiàn) 靜態(tài)切入點(diǎn) 正則表達(dá)式切入點(diǎn) 屬性驅(qū)動(dòng)的切入點(diǎn) 動(dòng)態(tài)切入點(diǎn) 控制流切入點(diǎn) 切入點(diǎn)的超類 自定義切入點(diǎn) Spring的通知API 通知的生命周期 Spring里的通知類型 攔截環(huán)繞通知 前置通知 異常通知 后置通知 引入通知 Spring里的Advisor API 使用ProxyFactoryBean創(chuàng)建AOP代理 基礎(chǔ) JavaBean屬性 基于JDK和CGLIB的代理 對(duì)接口進(jìn)行代理 對(duì)類進(jìn)行代理 使用“全局”通知器 簡(jiǎn)化代理定義 使用ProxyFactory通過(guò)編程創(chuàng)建AOP代理 操作被通知對(duì)象 使用“自動(dòng)代理(autoproxy)”功能 自動(dòng)代理bean定義 BeanNameAutoProxyCreator DefaultAdvisorAutoProxyCreator AbstractAdvisorAutoProxyCreator 使用元數(shù)據(jù)驅(qū)動(dòng)的自動(dòng)代理 使用TargetSource 熱交換目標(biāo)源 池化目標(biāo)源 原型目標(biāo)源 ThreadLocal目標(biāo)源 定義新的Advice類型 更多資源 測(cè)試 簡(jiǎn)介 單元測(cè)試 Mock對(duì)象 JNDI Servlet API Portlet API 單元測(cè)試支持類 通用工具類 Spring MVC 集成測(cè)試 概覽 使用哪個(gè)支持框架 通用目標(biāo) 上下文管理及緩存 測(cè)試fixtures依賴注入 事務(wù)管理 集成測(cè)試支持類 JDBC測(cè)試支持 常用注解 JUnit 3.8遺留支持 上下文管理及緩存 測(cè)試fixture依賴注入 字段級(jí)別(Field Level)注入 事務(wù)管理 JUnit 3.8 遺留支持類 Java 5+ 專有支持 使用注解的事務(wù)相關(guān)測(cè)試 JPA支持類 Spring TestContext Framework 主要的抽象 上下文管理和緩存 測(cè)試fixture的依賴注入 事務(wù)管理 TestContext支持類 JUnit 3.8支持類 JUnit 4.4支持類 定制JUnit 4.4運(yùn)行器 TestNG支持類 TestContext框架注解支持 PetClinic示例 更多資源 中間層數(shù)據(jù)訪問(wèn) 事務(wù)管理 簡(jiǎn)介 動(dòng)機(jī) 關(guān)鍵抽象 使用資源同步的事務(wù) 高層次方案 低層次方案 TransactionAwareDataSourceProxy 聲明式事務(wù)管理 理解Spring的聲明式事務(wù)管理實(shí)現(xiàn) 第一個(gè)例子 回滾 為不同的bean配置不同的事務(wù)語(yǔ)義 <tx:advice/> 有關(guān)的設(shè)置 使用 @Transactional @Transactional 有關(guān)的設(shè)置 事務(wù)傳播 required RequiresNew Nested 通知事務(wù)操作 結(jié)合AspectJ使用 @Transactional 編程式事務(wù)管理 使用TransactionTemplate 指定事務(wù)設(shè)置 使用PlatformTransactionManager 選擇編程式事務(wù)管理還是聲明式事務(wù)管理 與特定應(yīng)用服務(wù)器集成 IBM WebSphere BEA WebLogic Oracle OC4J 常見(jiàn)問(wèn)題的解決方法 對(duì)一個(gè)特定的 DataSource 使用了錯(cuò)誤的事務(wù)管理器 更多的資源 DAO支持 簡(jiǎn)介 一致的異常層次 一致的DAO支持抽象類 使用JDBC進(jìn)行數(shù)據(jù)訪問(wèn) 簡(jiǎn)介 選擇一種工作模式 Spring JDBC包結(jié)構(gòu) 利用JDBC核心類控制JDBC的基本操作和錯(cuò)誤處理 JdbcTemplate類 一些示例 查詢(SELECT) 更新(INSERT/UPDATE/DELETE) 其他操作 JdbcTemplate 的最佳實(shí)踐 NamedParameterJdbcTemplate類 SimpleJdbcTemplate類 DataSource接口 SQLExceptionTranslator接口 執(zhí)行SQL語(yǔ)句 執(zhí)行查詢 更新數(shù)據(jù)庫(kù) 獲取自動(dòng)生成的主鍵 控制數(shù)據(jù)庫(kù)連接 DataSourceUtils類 SmartDataSource接口 AbstractDataSource類 SingleConnectionDataSource類 DriverManagerDataSource類 TransactionAwareDataSourceProxy類 DataSourceTransactionManager類 NativeJdbcExtractor JDBC批量操作 使用JdbcTemplate進(jìn)行批量操作 使用SimpleJdbcTemplate進(jìn)行批量操作 通過(guò)使用SimpleJdbc類簡(jiǎn)化JDBC操作 使用SimpleJdbcInsert插入數(shù)據(jù) 使用SimpleJdbcInsert來(lái)獲取自動(dòng)生成的主鍵 指定SimpleJdbcInsert所使用的字段 使用SqlParameterSource提供參數(shù)值 使用SimpleJdbcCall調(diào)用存儲(chǔ)過(guò)程 聲明SimpleJdbcCall使用的參數(shù) 如何定義SqlParameters 使用SimpleJdbcCall調(diào)用內(nèi)置函數(shù) 使用SimpleJdbcCall返回的ResultSet/REF Cursor 用Java對(duì)象來(lái)表達(dá)JDBC操作 SqlQuery類 MappingSqlQuery類 SqlUpdate類 StoredProcedure類 SqlFunction類 參數(shù)和數(shù)據(jù)處理的基本原則 為參數(shù)設(shè)置SQL類型信息 處理BLOB 和 CLOB對(duì)象 在IN語(yǔ)句中傳入一組參數(shù)值 處理復(fù)雜類型的存儲(chǔ)過(guò)程調(diào)用 使用ORM工具進(jìn)行數(shù)據(jù)訪問(wèn) 簡(jiǎn)介 Hibernate 資源管理 在Spring容器中創(chuàng)建 SessionFactory The HibernateTemplate 不使用回調(diào)的基于Spring的DAO實(shí)現(xiàn) 基于Hibernate3的原生API實(shí)現(xiàn)DAO 編程式的事務(wù)劃分 聲明式的事務(wù)劃分 事務(wù)管理策略 容器資源 vs 本地資源 在應(yīng)用服務(wù)器中使用Hibernate的注意事項(xiàng) JDO 建立PersistenceManagerFactory JdoTemplate和JdoDaoSupport 基于原生的JDO API實(shí)現(xiàn)DAO 事務(wù)管理 JdoDialect Oracle TopLink SessionFactory 抽象層 TopLinkTemplate and TopLinkDaoSupport 基于原生的TopLink API的DAO實(shí)現(xiàn) 事務(wù)管理 iBATIS SQL Maps 創(chuàng)建SqlMapClient 使用 SqlMapClientTemplate 和 SqlMapClientDaoSupport 基于原生的iBATIS API的DAO實(shí)現(xiàn) JPA 在Spring環(huán)境中建立JPA LocalEntityManagerFactoryBean 從JNDI中獲取 EntityManagerFactory LocalContainerEntityManagerFactoryBean Tomcat(5.0以上)加載時(shí)的織入配置 使用VM代理的全局加載時(shí)織入 上下文范圍內(nèi)的加載時(shí)織入配置 處理多持久化單元 JpaTemplate 和 JpaDaoSupport 基于原生的JPA實(shí)現(xiàn)DAO 異常轉(zhuǎn)化 事務(wù)管理 JpaDialect The Web Web MVC framework Web框架 概述 與其他MVC實(shí)現(xiàn)框架的集成 Spring Web MVC框架的特點(diǎn) DispatcherServlet 控制器 AbstractController 和 WebContentGenerator 其它的簡(jiǎn)單控制器 MultiActionController 命令控制器 處理器映射(handler mapping) BeanNameUrlHandlerMapping SimpleUrlHandlerMapping 攔截器(HandlerInterceptor) 視圖與視圖解析 視圖解析器(ViewResolver) 視圖解析鏈 重定向(Rediret)到另一個(gè)視圖 RedirectView redirect:前綴 forward:前綴 本地化解析器 AcceptHeaderLocaleResolver CookieLocaleResolver SessionLocaleResolver LocaleChangeInterceptor 使用主題 簡(jiǎn)介 如何定義主題 主題解析器 Spring對(duì)分段文件上傳(multipart file upload)的支持 介紹 使用MultipartResolver 在表單中處理分段文件上傳 使用Spring的表單標(biāo)簽庫(kù) 配置 form標(biāo)簽 input標(biāo)簽 checkbox標(biāo)簽 checkboxes標(biāo)簽 radiobutton標(biāo)簽 radiobuttons標(biāo)簽 password標(biāo)簽 select標(biāo)簽 option標(biāo)簽 options標(biāo)簽 textarea標(biāo)簽 hidden標(biāo)簽 errors標(biāo)簽 處理異常 慣例優(yōu)先原則(convention over configuration) 對(duì)控制器的支持:ControllerClassNameHandlerMapping 對(duì)模型的支持:ModelMap(ModelAndView) 對(duì)視圖的支持:RequestToViewNameTranslator 基于注解的控制器配置 建立dispatcher實(shí)現(xiàn)注解支持 使用@Controller定義一個(gè)控制器 使用@RequestMapping映射請(qǐng)求 使用@RequestParam綁定請(qǐng)求參數(shù)到方法參數(shù) 使用@ModelAttribute提供一個(gè)從模型到數(shù)據(jù)的鏈接 使用@SessionAttributes指定存儲(chǔ)在會(huì)話中的屬性 自定義WebDataBinder初始化 使用@InitBinder自定義數(shù)據(jù)綁定 配置一個(gè)定制的WebBindingInitializer 更多資源 集成視圖技術(shù) 簡(jiǎn)介 JSP和JSTL 視圖解析器 'Plain-old' JSPs versus JSTL 'Plain-old' JSP與JSTL 幫助簡(jiǎn)化開(kāi)發(fā)的額外的標(biāo)簽 Tiles 需要的資源 如何集成Tiles UrlBasedViewResolver類 ResourceBundleViewResolver類 SimpleSpringPreparerFactory 和 SpringBeanPreparerFactory Velocity和FreeMarker 需要的資源 Context 配置 創(chuàng)建模板 高級(jí)配置 velocity.properties FreeMarker 綁定支持和表單處理 用于綁定的宏 簡(jiǎn)單綁定 表單輸入生成宏 輸入域 選擇輸入域 重載HTML轉(zhuǎn)碼行為并使你的標(biāo)簽符合XHTML XSLT 寫(xiě)在段首 Bean 定義 標(biāo)準(zhǔn)MVC控制器代碼 把模型數(shù)據(jù)轉(zhuǎn)化為XML 定義視圖屬性 文檔轉(zhuǎn)換 小結(jié) 文檔視圖(PDF/Excel) 簡(jiǎn)介 配置和安裝 文檔視圖定義 Controller 代碼 Excel視圖子類 PDF視圖子類 JasperReports 依賴的資源 配置 配置ViewResolver 配置View 關(guān)于報(bào)表文件 使用 JasperReportsMultiFormatView 構(gòu)造ModelAndView 使用子報(bào)表 配置子報(bào)表文件 配置子報(bào)表數(shù)據(jù)源 配置Exporter的參數(shù) 集成其它Web框架 簡(jiǎn)介 通用配置 JavaServer Faces DelegatingVariableResolver FacesContextUtils Struts ContextLoaderPlugin DelegatingRequestProcessor DelegatingActionProxy ActionSupport Classes Tapestry 注入 Spring 托管的 beans 將 Spring Beans 注入到 Tapestry 頁(yè)面中 組件定義文件 添加抽象訪問(wèn)方法 將 Spring Beans 注入到 Tapestry 頁(yè)面中 - Tapestry 4.0+ 風(fēng)格 WebWork 更多資源 Portlet MVC框架 介紹 控制器 - MVC中的C 視圖 - MVC中的V Web作用范圍的Bean DispatcherPortlet ViewRendererServlet 控制器 AbstractController 和 PortletContentGenerator 其它簡(jiǎn)單的控制器 Command控制器 PortletWrappingController 處理器映射 PortletModeHandlerMapping ParameterHandlerMapping PortletModeParameterHandlerMapping 增加 HandlerInterceptors HandlerInterceptorAdapter ParameterMappingInterceptor 視圖和它們的解析 Multipart文件上傳支持 使用 PortletMultipartResolver 處理表單里的文件上傳 異常處理 Portlet應(yīng)用的部署 整合 使用Spring進(jìn)行遠(yuǎn)程訪問(wèn)與Web服務(wù) 簡(jiǎn)介 使用RMI暴露服務(wù) 使用RmiServiceExporter暴露服務(wù) 在客戶端鏈接服務(wù) 使用Hessian或者Burlap通過(guò)HTTP遠(yuǎn)程調(diào)用服務(wù) 為Hessian和co.配置DispatcherServlet 使用HessianServiceExporter暴露你的bean 在客戶端連接服務(wù) 使用Burlap 對(duì)通過(guò)Hessian或Burlap暴露的服務(wù)使用HTTP Basic認(rèn)證 使用HTTP調(diào)用器暴露服務(wù) Exposing the service object 在客戶端連接服務(wù) Web Services 使用JAX-RPC暴露基于servlet的web服務(wù) 使用JAX-RPC訪問(wèn)web服務(wù) 注冊(cè)JAX-RPC Bean映射 注冊(cè)自己的JAX-RPC 處理器 使用JAX-WS暴露基于servlet的web服務(wù) 使用JAX-WS暴露單獨(dú)web服務(wù) 使用Spring支持的JAX-WS RI來(lái)暴露服務(wù) 使用JAX-WS訪問(wèn)web服務(wù) 使用XFire來(lái)暴露Web服務(wù) JMS 服務(wù)端配置 客戶端配置 對(duì)遠(yuǎn)程接口不提供自動(dòng)探測(cè)實(shí)現(xiàn) 在選擇這些技術(shù)時(shí)的一些考慮 Enterprise Java Beans (EJB) 集成 簡(jiǎn)介 訪問(wèn)EJB 概念 訪問(wèn)本地的無(wú)狀態(tài)Session Bean(SLSB) 訪問(wèn)遠(yuǎn)程SLSB Accessing EJB 2.x SLSBs versus EJB 3 SLSBs 使用Spring提供的輔助類實(shí)現(xiàn)EJB組件 EJB 2.x base classes EJB 3 注入攔截 JMS (Java Message Service) 簡(jiǎn)介 使用Spring JMS JmsTemplate 連接工廠 目的地管理 消息偵聽(tīng)容器 SimpleMessageListenerContainer DefaultMessageListenerContainer ServerSessionMessageListenerContainer 事務(wù)管理 發(fā)送消息 使用消息轉(zhuǎn)換器 SessionCallback 和 ProducerCallback 接收消息 同步接收 異步接收 - 消息驅(qū)動(dòng)的POJO SessionAwareMessageListener接口 MessageListenerAdapter 事務(wù)中的消息處理 JCA消息端點(diǎn)的支持 JMS命名空間支持 JMX 介紹 將Bean暴露為JMX 創(chuàng)建MBeanServer 重用原有的MBeanServer 延遲初始化的MBean MBean的自動(dòng)注冊(cè) 控制注冊(cè)行為 控制Bean的管理接口 MBeanInfoAssembler接口 使用源碼級(jí)元數(shù)據(jù) 使用JDK 5.0的注解 源代碼級(jí)的元數(shù)據(jù)類型 AutodetectCapableMBeanInfoAssembler接口 用Java接口定義管理接口 使用MethodNameBasedMBeanInfoAssembler 控制Bean的ObjectName 從Properties讀取Properties 使用MetadataNamingStrategy <context:mbean-export/>元素 JSR-160連接器 服務(wù)器端連接器 客戶端連接器 基于Burlap/Hessian/SOAP的JMX 通過(guò)代理訪問(wèn)MBean 通知 為通知注冊(cè)監(jiān)聽(tīng)器 發(fā)布通知 更多資源 JCA CCI 簡(jiǎn)介 配置CCI 連接器配置 在Spring中配置ConnectionFactory 配置CCI連接 使用一個(gè) CCI 單連接 使用Spring的 CCI訪問(wèn)支持 記錄轉(zhuǎn)換 CciTemplate類 DAO支持 自動(dòng)輸出記錄生成 總結(jié) 直接使用一個(gè)CCI Connection接口和Interaction接口 CciTemplate 使用示例 建模CCI訪問(wèn)為操作對(duì)象 MappingRecordOperation MappingCommAreaOperation 自動(dòng)生成輸出記錄 總結(jié) MappingRecordOperation 使用示例 MappingCommAreaOperation 使用示例 事務(wù) Spring郵件抽象層 簡(jiǎn)介 使用Spring郵件抽象 MailSender 和 SimpleMailMessage 的基本用法 使用 JavaMailSender 和 MimeMessagePreparator 使用MimeMessageHelper 發(fā)送附件和嵌入式資源(inline resources) 附件 內(nèi)嵌資源 使用模板來(lái)創(chuàng)建郵件內(nèi)容 一個(gè)基于Velocity的示例 Spring中的定時(shí)調(diào)度(Scheduling)和線程池(Thread Pooling) 簡(jiǎn)介 使用OpenSymphony Quartz 調(diào)度器 使用JobDetailBean 使用 MethodInvokingJobDetailFactoryBean 使用triggers和SchedulerFactoryBean來(lái)包裝任務(wù) 使用JDK Timer支持類 創(chuàng)建定制的timers 使用 MethodInvokingTimerTaskFactoryBean類 最后:使用TimerFactoryBean來(lái)設(shè)置任務(wù) SpringTaskExecutor抽象 TaskExecutor接口 TaskExecutor類型 使用TaskExecutor 動(dòng)態(tài)語(yǔ)言支持 介紹 第一個(gè)示例 定義動(dòng)態(tài)語(yǔ)言支持的bean 公共概念 <lang:language/> 元素 Refreshable bean 內(nèi)置動(dòng)態(tài)語(yǔ)言源文件 理解dynamic-language-backed bean上下文中的構(gòu)造器注入 JRuby beans Groovy beans 通過(guò)回調(diào)定制Groovy對(duì)象 BeanShell beans 場(chǎng)景 Spring MVC控制器的腳本化 Validator的腳本化 Bits and bobs AOP - 通知腳本化bean 作用域 更多的資源 注解和源代碼級(jí)的元數(shù)據(jù)支持 簡(jiǎn)介 Spring的元數(shù)據(jù)支持 注解 @Required Spring中的其它@Annotations Jakarta Commons Attributes集成 元數(shù)據(jù)和Spring AOP自動(dòng)代理 基本原理 聲明式事務(wù)管理 示例程序 演示案例 介紹 使用動(dòng)態(tài)語(yǔ)言實(shí)現(xiàn)的Spring MVC控制器 構(gòu)建與部署 使用SimpleJdbcTemplate和@Repository實(shí)現(xiàn)DAO 域?qū)ο?/a> Data Access Object 構(gòu)建 XML Schema-based configuration Introduction XML Schema-based configuration Referencing the schemas The util schema <util:constant/> Setting a bean property or constructor arg from a field value <util:property-path/> Using <util:property-path/> to set a bean property or constructor-argument <util:properties/> <util:list/> <util:map/> <util:set/> The jee schema <jee:jndi-lookup/> (simple) <jee:jndi-lookup/> (with single JNDI environment setting) <jee:jndi-lookup/> (with multiple JNDI environment settings) <jee:jndi-lookup/> (complex) <jee:local-slsb/> (simple) <jee:local-slsb/> (complex) <jee:remote-slsb/> The lang schema The jms schema The tx (transaction) schema The aop schema The context schema <property-placeholder/> <annotation-config/> <component-scan/> <load-time-weaver/> <spring-configured/> <mbean-export/> The tool schema The beans schema Setting up your IDE Setting up Eclipse Setting up IntelliJ IDEA Integration issues XML parsing errors in the Resin v.3 application server Extensible XML authoring Introduction Authoring the schema Coding a NamespaceHandler Coding a BeanDefinitionParser Registering the handler and the schema 'META-INF/spring.handlers' 'META-INF/spring.schemas' Using a custom extension in your Spring XML configuration Meatier examples Nesting custom tags within custom tags Custom attributes on 'normal' elements Further Resources spring-beans-2.0.dtd spring.tld Introduction The bind tag The escapeBody tag The hasBindErrors tag The htmlEscape tag The message tag The nestedPath tag The theme tag The transform tag spring-form.tld Introduction The checkbox tag The checkboxes tag The errors tag The form tag The hidden tag The input tag The label tag The option tag The options tag The password tag The radiobutton tag The radiobuttons tag The select tag The textarea tag Spring 2.5開(kāi)發(fā)手冊(cè)中文化項(xiàng)目 聲明 致謝 參與人員 項(xiàng)目歷程
Figuren

12.6.?JPA

org.springframework.orm.jpa 包下的)Spring JPA以類似整合Hibernate或者JDO的方式, 提供了對(duì) Java Persistence API 的全面支持,同時(shí)為提供附加的特性,必須了解底層的實(shí)現(xiàn)。

12.6.1.?在Spring環(huán)境中建立JPA

Spring JPA 提供了三種方法創(chuàng)建JPA EntityManagerFactory

12.6.1.1.?LocalEntityManagerFactoryBean

LocalEntityManagerFactoryBean負(fù)責(zé)創(chuàng)建一個(gè)適合于僅使用JPA進(jìn)行數(shù)據(jù)訪問(wèn)的環(huán)境的 EntityManager。 Factory bean將使用JPA PersistenceProvider 類的自動(dòng)檢測(cè)機(jī)制(根據(jù)JPA的 Java SE啟動(dòng)),而在絕大多數(shù)情況下,只需要指定persistence unit名稱:

<beans>

   <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean">
      <property name="persistenceUnitName" value="myPersistenceUnit"/>
   </bean>

</beans>

這種JPA部署方式最為簡(jiǎn)單,但卻最受限制。例如,不能連接到現(xiàn)有的JDBCDataSource, 并且不支持全局事務(wù)。甚至,持久化類的織入(字節(jié)碼轉(zhuǎn)換)也是特定于提供者的,經(jīng)常需要在啟動(dòng)時(shí)指定一個(gè)特定的JVM代理。 總之,這種方法實(shí)際上只適用于獨(dú)立的應(yīng)用程序和測(cè)試環(huán)境(這正是JPA規(guī)范設(shè)計(jì)它的原因)。

僅在簡(jiǎn)單部署環(huán)境中只使用這種方式,比如獨(dú)立的應(yīng)用程序和集成測(cè)試。

12.6.1.2.?從JNDI中獲取 EntityManagerFactory

從JNDI獲取 EntityManagerFactory (例如在Java EE 5環(huán)境中),僅通過(guò)修改XML配置即可實(shí)現(xiàn):

<beans>

    <jee:jndi-lookup id="entityManagerFactory" jndi-name="persistence/myPersistenceUnit"/>

</beans>

在標(biāo)準(zhǔn)的Java EE 5啟動(dòng)過(guò)程中,Java EE服務(wù)器自動(dòng)檢測(cè)持久化單元(例如應(yīng)用程序文件包中的META-INF/persistence.xml) ,以及Java EE部署描述符中定義給那些持久化單元命名上下文位置的環(huán)境的persistence-unit-ref項(xiàng)(例如web.xml)。

在這種情況下,整個(gè)持久化單元部署,包括持久化類的織入(字碼碼轉(zhuǎn)換)都取決于Java EE服務(wù)器。 JDBC DataSource 通過(guò)在META-INF/persistence.xml 文件中的JNDI位置進(jìn)行定義;EntityManager事務(wù)與服務(wù)器的JTA子系統(tǒng)整合。Spring僅僅用獲得的EntityManagerFactory, 通過(guò)依賴注入將它傳遞給應(yīng)用程序?qū)ο?,并為它管理事?wù)(一般通過(guò)JtaTransactionManager)。

注意,如果在同一個(gè)應(yīng)用程序中使用了多個(gè)持久化單元,JNDI獲取的這種持久化單元的bean名稱 應(yīng)該與應(yīng)用程序用來(lái)引用它們的持久化單元名稱相符(例如@PersistenceUnit@PersistenceContext注解)。

在部署到Java EE 5服務(wù)器時(shí)使用該方法。關(guān)于如何將自定義JPA提供者部署到服務(wù)器,以及允許使用服務(wù)器提供的缺省提供者之外的JPA提供者,請(qǐng)查看服務(wù)器文檔的相關(guān)說(shuō)明。

12.6.1.3.?LocalContainerEntityManagerFactoryBean

LocalContainerEntityManagerFactoryBean 提供了對(duì)JPA EntityManagerFactory 的全面控制,非常適合那種需要細(xì)粒度定制的環(huán)境。LocalContainerEntityManagerFactoryBean 將基于 persistence.xml 文件創(chuàng)建 PersistenceUnitInfo 類,并提供 dataSourceLookup 策略和 loadTimeWeaver。 因此它可以在JNDI之外的用戶定義的數(shù)據(jù)源之上工作,并控制織入流程。

<beans>
        
 <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
  <property name="dataSource" ref="someDataSource"/>
  <property name="loadTimeWeaver">
    <bean class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver"/>
  </property>
 </bean>
 
</beans>

這是最為強(qiáng)大的JPA配置方式,允許在應(yīng)用程序中靈活進(jìn)行本地配置。它支持連接現(xiàn)有JDBC DataSource , 支持本地事務(wù)和全局事務(wù)等等。然而,它也將需求強(qiáng)加到了運(yùn)行時(shí)環(huán)境中,例如,如果持久化提供者需要字節(jié)碼轉(zhuǎn)換,則必須有織入ClassLoader的能力。

注意,這個(gè)選項(xiàng)可能與Java EE 5服務(wù)器內(nèi)建的JPA功能相沖突。因此,當(dāng)運(yùn)行在完全Java EE 5環(huán)境中時(shí), 要考慮從JNDI獲取EntityManagerFactory。另一種可以替代的方法是,在 LocalContainerEntityManagerFactoryBean定義中通過(guò)“persistenceXmlLocation”指定相關(guān)位置, 例如“META-INF/my-persistence.xml”,并且只將包含該名稱的描述符放在應(yīng)用程序包文件中。因?yàn)镴ava EE 5服務(wù)器將只 查找默認(rèn)的META-INF/persistence.xml文件,它會(huì)忽略這種定制的持久化單元,因而避免與前面Spring 驅(qū)動(dòng)的JPA配置沖突。(例如,適用于Rdsin 3.1)。

在基于Spring的應(yīng)用程序環(huán)境中使用該方式可獲得全部JPA功能。這包括web容器,如Tomcat, 以及獨(dú)立的應(yīng)用程序和包含復(fù)雜持久化需求的集成測(cè)試。

LoadTimeWeaver 接口由Spring提供,允許JPA ClassTransformer 實(shí)例 能夠根據(jù)環(huán)境(web容器/應(yīng)用服務(wù)器)以特定的方式插入。 通過(guò)Java 5 代理掛鉤 ClassTransformers經(jīng)常是無(wú)效的 ―― 代理通常在 整個(gè)虛擬機(jī) 環(huán)境下工作,并且監(jiān)控 每一個(gè) 被加載的類 ―― 這在生產(chǎn)環(huán)境下一般是不提倡的。

Spring提供了大量用于不同環(huán)境的 LoadTimeWeaver 實(shí)現(xiàn)類, 允許 ClassTransformer 實(shí)例能夠僅用于每個(gè)classloader ,而不是每個(gè)虛擬機(jī)。

接下來(lái)的一節(jié)將討論在Tomcat以及使用Spring的VM代理情況下的典型JPA織入配置。關(guān)于設(shè)置常用加載時(shí)織入的詳細(xì)內(nèi)容, 請(qǐng)參見(jiàn)AOP一章中的第?6.8.4.5?節(jié) “Spring配置”一節(jié),它涵蓋了Tomcat、VM代理以及WebLogic、OC4J、GlassFish和Resin。

12.6.1.3.1.?Tomcat(5.0以上)加載時(shí)的織入配置

Apache Tomcat 缺省的ClassLoader(類裝載器)并不支持類的切換, 但是它允許使用用戶自定義的類裝載器。Spring提供了 TomcatInstrumentableClassLoader 類 (在org.springframework.instrument.classloading.tomcat 包中),這個(gè)類繼承自Tomcat的類裝載器 (WebappClassLoader)并且允許JPA ClassTransformer 的實(shí)例來(lái)“增強(qiáng)”所有由它加載的類。 簡(jiǎn)單說(shuō),JPA轉(zhuǎn)化器(JPA transformer)僅僅在(使用 TomcatInstrumentableClassLoader 的)特定web應(yīng)用程序中才能被使用。

為使用用戶自定義的類裝載器:

  1. spring-tomcat-weaver.jar 復(fù)制到 $CATALINA_HOME/server/lib 下 (其中$CATALINA_HOME 表示Tomcat的安裝路徑)。

  2. 通過(guò)修改web application context使Tomcat使用用戶自定義的類裝載器(而不是默認(rèn)的類裝載器):

    <Context path="/myWebApp" docBase="/my/webApp/location">
        <Loader loaderClass="org.springframework.instrument.classloading.tomcat.TomcatInstrumentableClassLoader"/>
    </Context>

    Tomcat 5.0.x 和 5.5.x 系列支持多個(gè)上下文路徑(context locations): 服務(wù)器配置文件($CATALINA_HOME/conf/server.xml), 默認(rèn)的上下文配置($CATALINA_HOME/conf/context.xml)會(huì)影響所有被部署的web應(yīng)用程序、 單獨(dú)部署在Server端的web應(yīng)用程序的配置($CATALINA_HOME/conf/[enginename]/[hostname]/my-webapp-context.xml) 或者與web應(yīng)用程序一起(your-webapp.war/META-INF/context.xml)。從效率的角度說(shuō), 我們推薦在web-app的內(nèi)部配置的方式,因?yàn)閮H僅使用JPA的應(yīng)用程序會(huì)使用用戶自定義的類裝載器。 更多具體有關(guān)可用的上下文路徑的內(nèi)容請(qǐng)參見(jiàn)Tomcat 5.x的文檔。

    注意,5.5.20之前的版本有一個(gè)XML配置解析的bug,造成 server.xml 中無(wú)法使用Loader標(biāo)簽,無(wú)論是否指定了classloader,也不管這個(gè)classloader是官方的還是自定義的。

            

    如果你正在使用的是Tomcat 5.5.20以上的版本,就可以將useSystemClassLoaderAsParent設(shè)置成         false來(lái)解決這個(gè)問(wèn)題:

    <Context path="/myWebApp" docBase="/my/webApp/location">
        <Loader loaderClass="org.springframework.instrument.classloading.tomcat.TomcatInstrumentableClassLoader"
                useSystemClassLoaderAsParent="false"/>
    </Context>
  1. spring-tomcat-weaver.jar復(fù)制到$CATALINA_HOME/lib (where $CATALINA_HOME表示Tomcat安裝根目錄的位置)。

  2. 通過(guò)編輯web應(yīng)用程序上下文文件,使Tomcat使用自定義的ClassLoader(而不是默認(rèn)的ClassLoader):

    <Context path="/myWebApp" docBase="/my/webApp/location">
        <Loader loaderClass="org.springframework.instrument.classloading.tomcat.TomcatInstrumentableClassLoader"/>
    </Context>

    Tomcat 6.0.x (類似于5.0.x/5.5.x)系列支持幾種上下文路徑:(context locations): 服務(wù)器配置文件($CATALINA_HOME/conf/server.xml), 默認(rèn)的上下文配置($CATALINA_HOME/conf/context.xml)會(huì)影響所有被部署的web應(yīng)用程序、 單獨(dú)部署在Server端的web應(yīng)用程序的配置($CATALINA_HOME/conf/[enginename]/[hostname]/my-webapp-context.xml) 或者與web應(yīng)用程序一起(your-webapp.war/META-INF/context.xml)。從效率的角度說(shuō), 我們推薦在web-app的內(nèi)部配置的方式,因?yàn)閮H僅使用JPA的應(yīng)用程序會(huì)使用用戶自定義的類裝載器。 更多具體有關(guān)可用的上下文路徑的內(nèi)容請(qǐng)參見(jiàn)Tomcat 5.x documentation。

  • Tomcat 5.0.x/5.5.x

  • Tomcat 6.0.x

所有Tomcat版本所需的最后一步,是在配置LocalContainerEntityManagerFactoryBean的時(shí),使用 相應(yīng)的LoadTimeWeaver

<bean id="emf" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
  <property name="loadTimeWeaver">
    <bean class="org.springframework.instrument.classloading.ReflectiveLoadTimeWeaver"/>
  </property>
</bean>

利用這種方法,依賴工具的JPA應(yīng)用程序無(wú)需代理就可以在Tomcat上運(yùn)行。這在宿主應(yīng)用程序依賴不同的JPA實(shí)現(xiàn)時(shí)尤為重要, 因?yàn)镴PA轉(zhuǎn)化器只適用于ClassLoader級(jí)別,它們之間是彼此隔離的。

注意

如果Tomcat使用TopLink作為JPA提供者,請(qǐng)將核心的toplink jar包放在$CATALINA_HOME/shared/lib文件夾中,而不再放到war中。

12.6.1.3.2.?使用VM代理的全局加載時(shí)織入

對(duì)于需要類工具,同時(shí)現(xiàn)有的LoadTimeWeaver實(shí)現(xiàn)不提供這種支持的環(huán)境,JDK代理是唯一的解決方案。對(duì)于這種情況,Spring提供了 需要特定于Spring(但非常常用)的VM代理(spring-agent.jar)的InstrumentationLoadTimeWeaver

<bean id="emf" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
  <property name="loadTimeWeaver">
    <bean class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver"/>
  </property>
</bean>

請(qǐng)注意在啟動(dòng)虛擬機(jī)時(shí),同時(shí)啟動(dòng)Spring代理,方法是提供下列JVM選項(xiàng):

-javaagent:/path/to/spring-agent.jar
12.6.1.3.3.?上下文范圍內(nèi)的加載時(shí)織入配置

自Spring 2.5,可以使用context:load-time-weaver元素來(lái)配置 上下文范圍的LoadTimeWeaver了。這種“全局”織入器由所有JPA LocalContainerEntityManagerFactoryBeans自動(dòng)揀選。

這是配置加載時(shí)織入器的推薦方法,提供平臺(tái)(ebLogic, OC4J, GlassFish, Tomcat, Resin, VM agent)的自動(dòng)檢測(cè),以及織入器到所有織入器知道的bean的自動(dòng)傳播。

<context:load-time-weaver/>

<bean id="emf" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    ...
</bean>

關(guān)于如何建立常用加載時(shí)織入的詳細(xì)內(nèi)容,請(qǐng)參見(jiàn)第?6.8.4.5?節(jié) “Spring配置”一節(jié),它涵蓋了 Tomcat、VM代理,以及WebLogic, OC4J, GlassFish和Resin。

12.6.1.4.?處理多持久化單元

對(duì)于那些依靠多個(gè)持久化單元位置(例如存放在classpath中的多個(gè)jar中)的應(yīng)用程序, Spring提供了作為中央倉(cāng)庫(kù)的PersistenceUnitManager, 避免了持久化單元查找過(guò)程(的潛在開(kāi)銷)。缺省實(shí)現(xiàn)允許指定多個(gè)位置 (默認(rèn)情況下classpath會(huì)搜索META-INF/persistence.xml文件),它們會(huì)被解析然后通過(guò)持久化單元名稱被獲?。?/p>

<bean id="pum" class="org.springframework.orm.jpa.persistenceunit.DefaultPersistenceUnitManager">
  <property name="persistenceXmlLocation">
    <list>
     <value>org/springframework/orm/jpa/domain/persistence-multi.xml</value>
     <value>classpath:/my/packagecustom-persistence.xml</value>
     <value>classpath*:META-INF/persistence.xml</value>
    </list>
  </property>
  <property name="dataSources">
   <map>
    <entry key="localDataSource" value-ref="local-db"/>
    <entry key="remoteDataSource" value-ref="remote-db"/>
   </map>
  </property>
  <!-- if no datasource is specified, use this one -->
  <property name="defaultDataSource" ref="remoteDataSource"/>
</bean>

<bean id="emf" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
  <property name="persistenceUnitManager" ref="pum"/>
</bean>

要注意的是,缺省實(shí)現(xiàn)允許在將持久化單元信息傳入JPA provider之前用 PersistenceUnitPostProcessor(它允許選擇持久化單元)修改它們, 傳入的過(guò)程可以是通過(guò)屬性聲明式地傳入(影響其中所有的單元)或編程式地傳入。 如果沒(méi)有指定persistenceUnitManager,LocalContainerEntityManagerFactoryBean 會(huì)創(chuàng)建一個(gè)并在內(nèi)部使用它。

12.6.2.?JpaTemplateJpaDaoSupport

每個(gè)基于JPA的DAO都將通過(guò)依賴注入接收一個(gè) EntityManagerFactory 實(shí)例。 這樣的DAO可以通過(guò)指定的 EntityManagerFactory 來(lái)操作原生JPA的API進(jìn)行數(shù)據(jù)訪問(wèn), 也可以直接使用Spring的 JpaTemplate

<beans>

  <bean id="myProductDao" class="product.ProductDaoImpl">
    <property name="entityManagerFactory" ref="entityManagerFactory"/>
  </bean>

</beans>
public class JpaProductDao implements ProductDao {
  
    private JpaTemplate jpaTemplate;

    public void setEntityManagerFactory(EntityManagerFactory emf) {
        this.jpaTemplate = new JpaTemplate(emf);
    }

    public Collection loadProductsByCategory(final String category) throws DataAccessException {
        return (Collection) this.jpaTemplate.execute(new JpaCallback() {
            public Object doInJpa(EntityManager em) throws PersistenceException {
                Query query = em.createQuery("from Product as p where p.category = :category");
                query.setParameter("category", category);
                List result = query.getResultList(); 
                // do some further processing with the result list
                return result;
            }
        });
    }
}

JpaCallback 實(shí)現(xiàn)允許任意類型的JPA數(shù)據(jù)訪問(wèn)。 JpaTemplate 將確保 EntityManager 正確地打開(kāi)和關(guān)閉,并且能夠自動(dòng)地參與到事務(wù)中去。 除此之外,JpaTemplate 能夠恰當(dāng)?shù)靥幚懋惓#_保資源的及時(shí)清理以及必要時(shí)的事務(wù)回滾。 Template實(shí)例不僅是線程安全的,而且它是可重用的,因而它能夠作為實(shí)例變量被一個(gè)類持有。 注意, JpaTemplate 提供了簡(jiǎn)單的諸如find、load、merge等操作的快捷函數(shù)來(lái)替代默認(rèn)的回調(diào)實(shí)現(xiàn)。

不僅如此,Spring還提供了一個(gè)方便的 JpaDaoSupport 基類,提供了 get/setEntityManagerFactory 方法以及 getJpaTemplate() 方法供子類調(diào)用:

public class ProductDaoImpl extends JpaDaoSupport implements ProductDao {
  
    public Collection loadProductsByCategory(String category) throws DataAccessException {
        Map<String, String> params = new HashMap<String, String>();
        params.put("category", category);
        return getJpaTemplate().findByNamedParams("from Product as p where p.category = :category", params);
    }
}

除了直接使用Spring的 JpaTemplate之外,也可以使用原生JPA的API來(lái)實(shí)現(xiàn)基于Spring的DAO, 此時(shí)你需要自行明確地處理EntityManager。正如在相應(yīng)的Hibernate章節(jié)描述的一樣,這種做法的主要優(yōu) 點(diǎn)在于你的數(shù)據(jù)訪問(wèn)代碼可以在整個(gè)過(guò)程中拋出checked exceptions。JpaDaoSupport 為這種情況提 供了多種函數(shù)支持,包括獲取和釋放一個(gè)具備事務(wù)管理功能的 EntityManager 和相關(guān)的異常轉(zhuǎn)化。

JpaTemplate主要以JdoTemplate和HibernateTemplate的同胞而存在,為使用它的人們提供相同的風(fēng)格。 對(duì)于新啟動(dòng)的項(xiàng)目,要考慮采用原生的JPA風(fēng)格編寫(xiě)數(shù)據(jù)訪問(wèn)對(duì)象的代碼,基于通過(guò)JPA@PersistenceContext注解 獲取的一個(gè)“共享EntityManager”引用(利用Spring的PersistenceAnnotationBeanPostProcessor;詳情如下。)

12.6.3.?基于原生的JPA實(shí)現(xiàn)DAO

注意

雖然EntityManagerFactory實(shí)例是線程安全的, 但EntityManager實(shí)例確實(shí)不是這樣。被注入的JPA EntityManager的行為和從應(yīng)用服務(wù)器JNDI環(huán)境中獲取的沒(méi)有區(qū)別, 和JPA規(guī)范定義的一樣。如果存在一個(gè)被注入的JPA EntityManager, 它會(huì)代理對(duì)當(dāng)前事務(wù)化的EntityManager的所有調(diào)用; 否則每個(gè)操作都會(huì)創(chuàng)建一個(gè)EntityManager,確保線程安全。

你完全可以使用原生的JPA的API進(jìn)行編程,而無(wú)需對(duì)Spring產(chǎn)生任何依賴,這可以通過(guò)一個(gè)被注入的 EntityManagerFactoryEntityManager 來(lái)完成。 注意,如果 PersistenceAnnotationBeanPostProcessor 被啟用,Spring就能夠識(shí)別字段或者方法級(jí)別的 @PersistenceUnit@PersistenceContext 注解。相應(yīng)的DAO實(shí)現(xiàn)看起來(lái)像這樣:

public class ProductDaoImpl implements ProductDao {

    private EntityManagerFactory emf;

    @PersistenceUnit
    public void setEntityManagerFactory(EntityManagerFactory emf) {
        this.emf = emf;
    }

    public Collection loadProductsByCategory(String category) {
        EntityManager em = this.emf.createEntityManager();
        try {
             Query query = em.createQuery("from Product as p where p.category = ?1");
             query.setParameter(1, category);
             return query.getResultList();
        }
        finally {
            if (em != null) {
                em.close();
            }
        }
    }
}

上述的DAO不對(duì)Spring產(chǎn)生任何依賴,而它就如同使用Spring的 JpaTemplate 那樣,仍然非常適合 在Spring的application context中進(jìn)行配置。此外,這樣的DAO可以利用注解來(lái)要求缺省EntityManagerFactory 的注入:

<beans>

  <!-- bean post-processor for JPA annotations -->
  <bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor"/>

  <bean id="myProductDao" class="product.ProductDaoImpl"/>

</beans>

注意:作為顯式定義PersistenceAnnotationBeanPostProcessor的另一種方法, 可以考慮在應(yīng)用程序上下文配置中使用Spring 2.5的context:annotation-config XML元素。 它會(huì)自動(dòng)為基于注解的配置注冊(cè)Spring所有標(biāo)準(zhǔn)的后置處理器(包括CommonAnnotationBeanPostProcessor等等)。

<beans>

  <!-- post-processors for all standard config annotations -->
  <context:annotation-config/>

  <bean id="myProductDao" class="product.ProductDaoImpl"/>

</beans>

這類DAO的主要問(wèn)題在于每次總是從工廠中獲取一個(gè)新的 EntityManager 實(shí)例。 這一點(diǎn)可以通過(guò)對(duì) EntityManager 而不是factory進(jìn)行注入來(lái)解決:

public class ProductDaoImpl implements ProductDao {

    @PersistenceContext
    private EntityManager em;

    public Collection loadProductsByCategory(String category) {
       Query query = em.createQuery("from Product as p where p.category = :category");
       query.setParameter("category", category);
       return query.getResultList(); 
    }
}

注意:@PersistenceContext注解有一個(gè)可選的屬性type,它的默認(rèn)值是 PersistenceContextType.TRANSACTION。該默認(rèn)需要你接收一個(gè)“共享EntityManager”代理。 另一種方式,PersistenceContextType.EXTENDED則完全不同:它會(huì)產(chǎn)生一個(gè)所謂的“擴(kuò)展EntityManager”, 這個(gè)不是線程安全的,因此不應(yīng)該用在當(dāng)前被訪問(wèn)的組件中,例如Spring管理的singleton bean。 擴(kuò)展的EntityManager只能用在有狀態(tài)的組件中,例如,在會(huì)話中,EntityManager的生命周期與當(dāng)前事務(wù)無(wú)關(guān),完全取決于應(yīng)用程序。

被注入的 EntityManager 由Spring管理(能夠感知當(dāng)前的事務(wù))。 值得注意的是,即使這種新的實(shí)現(xiàn)更傾向于方法級(jí)別的注入(使用 EntityManager 而不是 EntityManagerFactory), 對(duì)于注解的使用,application context的XML配置則無(wú)需任何改變。

這種DAO風(fēng)格的主要優(yōu)點(diǎn)在于它僅僅依賴JPA,而無(wú)需依賴任何的Spring的類。除此之外,由于JPA的注解可被理解,注入能夠被Spring容器自動(dòng)應(yīng)用。 從無(wú)入侵性的角度來(lái)說(shuō),這一點(diǎn)非常有吸引力,它對(duì)于JPA開(kāi)發(fā)者來(lái)說(shuō)也更自然。

12.6.4.?異常轉(zhuǎn)化

然而,DAO不僅會(huì)拋出普通的 PersistenceException 異常(這是一個(gè)無(wú)需聲明和捕獲的unchecked exception), 還會(huì)拋出諸如 IllegalArgumentExceptionIllegalStateException 之類的異常。 這意味著,DAO的調(diào)用者只能以普通的錯(cuò)誤來(lái)處理這些異常,除非完全依賴JPA自身的異常體系。因而,除非你將DAO的調(diào)用者綁定到具體的實(shí)現(xiàn)策略上去, 否則將無(wú)法捕獲特定的異常原因(諸如樂(lè)觀鎖異常)。這種折中平衡或許可以被接受,如果你的應(yīng)用完全基于JPA或者無(wú)需進(jìn)行特殊的異常處理。不過(guò), Spring提供了一個(gè)允許你進(jìn)行透明的異常轉(zhuǎn)化的解決方案:通過(guò)使用 @Repository 注解:

@Repository
public class ProductDaoImpl implements ProductDao {

    // class body here...

}
<beans>

  <!-- Exception translation bean post processor -->
  <bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor"/>

  <bean id="myProductDao" class="product.ProductDaoImpl"/>

</beans>

后置處理器將自動(dòng)地尋找所有的異常轉(zhuǎn)化器(PersistenceExceptionTranslator 接口的實(shí)現(xiàn)), 并通知所有標(biāo)有 @Repository 注解的bean,從而能夠使得被找到的異常轉(zhuǎn)化器能夠在拋出異常時(shí)進(jìn)行相應(yīng)的異常轉(zhuǎn)化工作。

總之:DAO能夠基于普通的Java持久層API和注解來(lái)實(shí)現(xiàn),但同樣也能享受到由Spring管理事務(wù)、IoC和透明的異常轉(zhuǎn)化 (轉(zhuǎn)化成為Spring的異常體系)等好處。

Vorheriger Artikel: N?chster Artikel: