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

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

6.8.?在Spring應用中使用AspectJ

到目前為止本章討論的一直是純Spring AOP。在這一節(jié)里面我們將介紹如何使用AspectJ compiler/weaver 來代替Spring AOP或者作為它的補充,因為有些時候Spring AOP單獨提供的功能也許并不能滿足你的需要。

Spring提供了一個小巧的AspectJ aspect library,你可以在程序發(fā)行版本中單獨使用 spring-aspects.jar文件,并將其加入到classpath下以使用其中的切面。 第?6.8.1?節(jié) “在Spring中使用AspectJ進行domain object的依賴注入”和第?6.8.2?節(jié) “Spring中其他的AspectJ切面” 討論了該庫以及如何使用該庫。 第?6.8.3?節(jié) “使用Spring IoC來配置AspectJ的切面”討論了如何對通過AspectJ compiler織入的AspectJ切面進行依賴注入。 最后第?6.8.4?節(jié) “在Spring應用中使用AspectJ加載時織入(LTW)”介紹了使用AspectJ的Spring應用程序如何進行加載期織入(load-time weaving)。

6.8.1.?在Spring中使用AspectJ進行domain object的依賴注入

Spring容器對application context中定義的bean進行實例化和配置。同樣也可以通過bean factory 來為一個已經存在且已經定義為spring bean的對象應用所包含的配置信息。 spring-aspects.jar中包含了一個annotation-driven的切面, 提供了能為任何對象進行依賴注入的能力。這樣的支持旨在為 脫離容器管理而創(chuàng)建的對象進行依賴注入。領域對象經常處于這樣的情形: 它們可能是通過new操作符創(chuàng)建的對象,也可能是由ORM工具查詢數據庫所返回的結果。

@Configurable注解標記了一個類可以通過Spring-driven方式來配置。 在最簡單的情況下,我們只把它當作標記注解:

package com.xyz.myapp.domain;
                
                import org.springframework.beans.factory.annotation.Configurable;
                
                @Configurable
                public class Account {
                // ...
            }

當只是簡單地作為一個標記接口來使用的時候,Spring將采用和該已注解的類型 (比如Account類)全名(com.xyz.myapp.domain.Account) 一致的bean原型定義來配置一個新實例。由于一個bean默認的名字就是它的全名, 所以一個比較方便的辦法就是省略定義中的id屬性:

<bean class="com.xyz.myapp.domain.Account" scope="prototype">
                <property name="fundsTransferService" ref="fundsTransferService"/>
            </bean>

如果你希望明確的指定bean原型定義的名字,你可以在注解中直接定義:

package com.xyz.myapp.domain;
                
                import org.springframework.beans.factory.annotation.Configurable;
                
                @Configurable("account")
                public class Account {
                // ...
            }

Spring會查找名字為"account"的bean定義,并使用它作定義來配置一個新的 Account實例。

你也可以使用自動裝配來避免手工指定原型定義的名字。只要設置@Configurable 注解中的autowire屬性就可以讓Spring進行自動裝配: 指定@Configurable(autowire=Autowire.BY_TYPE)或者 @Configurable(autowire=Autowire.BY_NAME可以讓自動裝配分別按照類型或名字進行。 作為另外一種選擇,在Spring2.5中最好是在域或方法級使用@Autowired@Resource為你的@Configurable beans指定 明確的、注解驅動的依賴注入。(詳情請參看第?3.11?節(jié) “基于注解(Annotation-based)的配置”)

最后,你可以通過使用dependencyCheck 屬性,讓Spring對新創(chuàng)建和配置的對象的對象引用進行 依賴檢查(例如:@Configurable(autowire=Autowire.BY_NAME,dependencyCheck=true))。 如果這個屬性設置為true,Spring會在配置結束后校驗(除了primitives和collections類型) 所有的屬性是否都被設置。

僅僅使用注解并沒有做任何事情。但是spring-aspects.jar 中的AnnotationBeanConfigurerAspect會在注解存在時起作用。實質上切面指明: “在初始化一個由@Configurable 注解的新對象時, Spring按照注解中的屬性來配置這個新創(chuàng)建的對象”。這種情況下,initialization 指新初始化的(比如用new初始化)的對象以及能進行反序列化的 Serializable對象(例如通過 readResolve()方法)。

注意

在上一段中一個關鍵的階段就是“inessence”。多數情況下,“ 當從一個新對象初始化返回之后”的精確語義很不錯...這種語境下, “初始化之后”的意思是依賴將在對象被構造之后注入 - 這意味著在類的構造器塊中依賴將不可用。如果你希望它能在構造器代碼塊執(zhí)行 之前被注入,并從而在構造器中使用它, 那么你需要在@Configurable接口聲明上做類似的定義:

@Configurable(preConstruction=true)

你可以在 AspectJ Programming Guide一書的附錄中 找到更多有關在AspectJ中各種切面類型的語義信息。

要實現(xiàn)上述的操作,已注解的類型必須由AspectJ weaver來織入 - 你可以使用一個構建時的ant/maven任務來完成 (參見AspectJ Development Environment Guide)或者使用加載時織入(參見 第?6.8.4?節(jié) “在Spring應用中使用AspectJ加載時織入(LTW)”)。 類AnnotationBeanConfigurerAspect本身也需要Spring來配置(獲得bean factory的引用,使用bean factory配置新的對象)。為此Spring的 context命名空間 定義了一個非常方便的標簽。只要簡單的在application context配置中包含下面的內容。

<context:spring-configured/>

如果你使用DTD代替Schema,對應的定義如下:

<bean 
                class="org.springframework.beans.factory.aspectj.AnnotationBeanConfigurerAspect"
            factory-method="aspectOf"/>

在切面配置完成之前創(chuàng)建的@Configurable 對象實例會導致在log中留下一個warning,并且任何對于該對象的配置都不會生效。 舉一個例子,一個Spring管理配置的bean在被Spring初始化的時候創(chuàng)建了一個domain object。 對于這樣的情況,你需要定義bean屬性中的"depends-on"屬性來手動指定該bean依賴于configuration切面。

<bean id="myService"
                class="com.xzy.myapp.service.MyService"
                depends-on="org.springframework.beans.factory.aspectj.AnnotationBeanConfigurerAspect">
                
                <!-- ... -->
                
            </bean>

6.8.1.1.?@Configurable對象的單元測試

提供@Configurable支持的一個目的就是使得domain object的單元測試 可以獨立進行,不需要通過硬編碼查找各種倚賴關系。如果@Configurable 類型沒有通過AspectJ織入,則在單元測試過程中注解不會起到任何作用, 測試中你可以簡單的為對象的mock或者stub屬性賦值,并且和正常情況一樣去使用該對象。 如果@Configurable類型通過AspectJ織入, 我們依然可以脫離容器進行單元測試,不過每次創(chuàng)建一個新的@Configurable 對象時都會看到一個warning,標示該對象沒有被Spring配置。

6.8.1.2.?Working with multiple application contexts

6.8.1.2.?Working with multiple application contexts

AnnotationBeanConfigurerAspect通過一個AspectJ singleton切面來實現(xiàn)對 @Configurable的支持。一個singleton切面的作用域和一個 靜態(tài)變量的作用域是一樣的,那就是說,對于每一個classloader有一個切面來定義類型。 這就意味著如果你在一個classloader層次結構中定義了多個application context的時候就需要考慮 在哪里定義<aop:spring-configured/> bean和在哪個classpath下 放置spring-aspects.jar。

考慮一下典型的Spring web項目,一般都是由一個父application context定義大部分business service和 所需要的其他資源,然后每一個servlet擁有一個子application context定義。所有這些context共存于 同一個classloader體系下,因此AnnotationBeanConfigurerAspect僅保持 一個對context的引用。在這樣的情況下,我們推薦在父application context中定義 <aop:spring-configured/> bean:這里所定義的service可能是 你希望注入domain object的。這樣做的結果是你不能為子application context中 使用@Configurable的domain object配置bean引用(可能你也根本就不希望那么做?。?。

當在一個容器中部署多個web-app的時候,請確保每一個web-application使用自己的classloader 來加載spring-aspects.jar中的類(例如將spring-aspects.jar放在WEB-INF/lib目錄下)。 如果spring-aspects.jar被放在了容器的classpath下(因此也被父classloader加載),則所有的 web application將共享一個aspect實例,這可能并不是你所想要的。

6.8.2.?Spring中其他的AspectJ切面

除了@Configurable切面, spring-aspects.jar包含了一個AspectJ切面可以用來為 那些使用了@Transactional注解的類型和方法驅動Spring事務管理。 提供這個的主要目的是有些用戶希望脫離Spring容器使用Spring的事務管理。

解析@Transactional注解的切面是 AnnotationTransactionAspect。當使用這個切面時, 你必須注解這個實現(xiàn)類(和/或這個類中的方法),而不是 這個類實現(xiàn)的接口(如果有)。AspectJ允許在接口上注解的Java規(guī)則 不被繼承。

類之上的一個@Transactional注解為該類中任何 public操作的執(zhí)行指定了默認的事務語義。

類內部方法上的一個@Transactional注解會覆蓋類注解(如果存在) 所給定的默認的事務語義。具有public、protected和default修飾符的方法都可以被注解。 直接注解protected和default方法是讓這個操作的執(zhí)行獲得事務劃分的唯一途徑。

對于AspectJ程序員,希望使用Spring管理配置和事務管理支持,不過他們不想(或者不能)使用注解, spring-aspects.jar也包含了一些抽象 切面供你繼承來提供你自己的切入點定義。參見AbstractBeanConfigurerAspectAbstractTransactionAspect的Javadoc獲取更多信息。 作為一個例子,下面的代碼片斷展示了如何編寫一個切面,然后通過和類全名匹配的bean原型定義來 配置domian object中定義的所有實例:

public aspect DomainObjectConfiguration extends AbstractBeanConfigurerAspect {
                
                public DomainObjectConfiguration() {
                setBeanWiringInfoResolver(new ClassNameBeanWiringInfoResolver());
                }
                
                // the creation of a new bean (any object in the domain model)
                protected pointcut beanCreation(Object beanInstance) :
                initialization(new(..)) &&
                SystemArchitecture.inDomainModel() && 
                this(beanInstance);
                
            }

6.8.3.?使用Spring IoC來配置AspectJ的切面

當在Spring application中使用AspectJ的時候,很自然的會想到用Spring來管理這些切面。 AspectJ runtime自身負責切面的創(chuàng)建,這意味著通過Spring來管理AspectJ 創(chuàng)建切面依賴于切面所使用的AspectJ instantiation model(per-clause)。

大多數AspectJ切面都是singleton切面。管理這些切面非常容易, 和通常一樣創(chuàng)建一個bean定義引用該切面類型就可以了,并且在bean定義中包含 'factory-method="aspectOf"'這個屬性。 這確保Spring從AspectJ獲取切面實例而不是嘗試自己去創(chuàng)建該實例。示例如下:

<bean id="profiler" class="com.xyz.profiler.Profiler"
                factory-method="aspectOf">
                <property name="profilingStrategy" ref="jamonProfilingStrategy"/>
            </bean>

non-singleton切面的配置稍難一點,然而它可以通過定義一個bean原型定義并且使用 spring-aspects.jar中的@Configurable支持, 當切面實例由AspectJ runtime創(chuàng)建后進行配置。

如果你希望一些@AspectJ切面使用AspectJ來織入(例如使用load-time織入domain object) 而另一些@AspectJ切面使用Spring AOP,并且這些切面都由Spring來管理,那你就需要告訴Spring AOP @AspectJ自動代理支持那些切面需要被自動代理。你可以通過在 <aop:aspectj-autoproxy>聲明中使用一個或多個 <include/>元素。每個元素指定了一種命名格式, 只有bean命名至少符合其中一種情況下才會使用Spring AOP自動代理配置:

<aop:aspectj-autoproxy>
                <aop:include name="thisBean"/>
                <aop:include name="thatBean"/>
            </aop:aspectj-autoproxy>

注意

不要被<aop:aspectj-autoproxy/>元素的名字所誤導: 用它會導致Spring AOP 代理的創(chuàng)建。在這中只是使用@AspectJ 類型的切面聲明,但并不會涉及AspectJ運行時。

6.8.4.?在Spring應用中使用AspectJ加載時織入(LTW)

加載時織入(Load-time weaving(LTW))指的是在虛擬機載入字節(jié)碼文件時動態(tài)織入AspectJ切面。 本 節(jié)關注于在Spring Framework中特的定context下配置和使用LTW:并沒有LTW的介紹。 關于LTW和僅使用AspectJ配置LTW的詳細信息(根本不涉及Spring),請查看 LTW section of the AspectJ Development Environment Guide。

Spring框架的值添加為AspectJ LTW在動態(tài)織入過程中提供了更細粒度的控制。使用Java(5+)的代理 能使用一個叫‘Vanilla’的AspectJ LTW,這需要在啟動JVM的時候將某個VM參數設置為開。 這種JVM范圍的設置在一些情況下或許不錯,但通常情況下顯得有些粗顆粒。而用Spring的LTW能讓你在 per-ClassLoader的基礎上打開LTW, 這顯然更加細粒度并且對“單JVM多應用”的環(huán)境更具意義(例如在一個典型應用服務器環(huán)境中一樣)。

另外,在某些環(huán)境下,這能讓你使用LTW而 不對應用服務器的啟動腳本做任何改動,不然則需要添加 -javaagent:path/to/aspectjweaver.jar或者(以下將會提及的)-javaagent:path/to/spring-agent.jar。 開發(fā)人員只需簡單修改應用上下文的一個或幾個文件就能使用LTW,而不需依靠那些管理著部署配置 比如啟動腳本的系統(tǒng)管理員。

經過以上講解之后,先讓我們來過一遍一個使用Spring的AspectJ LTW的快速示例,接著是一個 有對元素詳細講解的示例。如果想要一個完整的示例,請參看Petclinic(寵物診所)的應用實例。

6.8.4.1.?第一個例子

假設你是一個應用開人員,被指派診斷一個系統(tǒng)的若干性能問題。與其拿出性能分析工具, 我們不如開啟一個簡單的分析切面,使我們能很快地得到一些性能指標,這樣我們就能馬上 針對特定區(qū)域使用一些較細粒度的分析工具。

這就是一個分析切面。沒什么特別的,只是一個快餐式的基于時間的模擬分析器, 使用類@AspectJ風格的切面聲明。

package foo;
                    
                    import org.aspectj.lang.ProceedingJoinPoint;
                    import org.aspectj.lang.annotation.Aspect;
                    import org.aspectj.lang.annotation.Around;
                    import org.aspectj.lang.annotation.Pointcut;
                    import org.springframework.util.StopWatch;
                    import org.springframework.core.annotation.Order;
                    
                    @Aspect
                    public class ProfilingAspect {
                    
                    @Around("methodsToBeProfiled()")
                    public Object profile(ProceedingJoinPoint pjp) throws Throwable {
                    StopWatch sw = new StopWatch(getClass().getSimpleName());
                    try {
                    sw.start(pjp.getSignature().getName());
                    return pjp.proceed();
                    } finally {
                    sw.stop();
                    System.out.println(sw.prettyPrint());
                    }
                    }
                    
                    @Pointcut("execution(public * foo..*.*(..))")
                    public void methodsToBeProfiled(){}
                    }
                

我們還需要創(chuàng)建一個“META-INF/aop.xml”文件,以告知AspectJ weaver 我們要把ProfilingAspect織入到類中。這個文件慣例,即在Java classpath中 出現(xiàn)一個文件稱作“META-INF/aop.xml”是標準的AspectJ。

<!DOCTYPE aspectj PUBLIC
                    "-//AspectJ//DTD//EN" "http://www.eclipse.org/aspectj/dtd/aspectj.dtd">
                    <aspectj>
                    
                    <weaver>
                    
                    <!-- only weave classes in our application-specific packages -->
                    <include within="foo.*"/>
                    
                    </weaver>
                    
                    <aspects>
                    
                    <!-- weave in just this aspect -->        
                    <aspect name="foo.ProfilingAspect"/>
                    
                    </aspects>
                    
                </aspectj>

現(xiàn)在來看Spring特定的配置部分。我們需要配置一個LoadTimeWeaver (稍后會有解釋,暫時不多深究)。當將一個或多個“META-INF/aop.xml”文件中的切面 配置織入你的應用程序的類中時,這個加載時織入器是必須的。這樣的好處是不需要很多的配置, 正如下面你看到的一樣(還有另外一些參數供你指定,我們將在后面詳細介紹)。

<?xml version="1.0" encoding="UTF-8"?>
                    <beans xmlns="http://www.springframework.org/schema/beans"
                    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                    xmlns:context="http://www.springframework.org/schema/context"
                    xsi:schemaLocation="
                    http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
                    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd">
                    
                    <!-- a service object; we will be profiling it's methods -->
                    <bean id="entitlementCalculationService"
                    class="foo.StubEntitlementCalculationService"/>
                    
                    <!-- this switches on the load-time weaving -->
                    <context:load-time-weaver/>
                    
                </beans>

現(xiàn)在萬事俱備 - 切面,META-INF/aop.xml文件,以及Spring的配置 - 讓我們創(chuàng)建一個帶有main(..)方法的簡單驅動類來演示LTW的作用吧。

package foo;
                    
                    import org.springframework.context.support.ClassPathXmlApplicationContext;
                    
                    public final class Main {
                    
                    public static void main(String[] args) {
                    
                    ApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml", Main.class);
                    
                    EntitlementCalculationService entitlementCalculationService
                    = (EntitlementCalculationService) ctx.getBean("entitlementCalculationService");
                    
                    // the profiling aspect is 'woven' around this method execution
                    entitlementCalculationService.calculateEntitlement();
                    }
                }

最后還有一件事要做。此節(jié)之前的介紹說過可以有選擇性的基于Spring的 per-ClassLoader來啟動LTW,而且的確如此。不過,對此例來說, 我們將使用Java代理(由Spring提供)來啟動LTW。這個就是用以運行上面Main 類的命令行語句:

java -javaagent:C:/projects/foo/lib/global/spring-agent.jar foo.Main

-javaagent是一個Java 5+標記,用來指定和激活 使JVM上的程序運行的代理。Spring框架裝載了一個InstrumentationSavingAgent 代理,在上面的例子中被作為了-javaagent參數的值打包在 spring-agent.jar中。

Main程序運行的輸出如下所示。(我已經在 calculateEntitlement()的實現(xiàn)中插入了Thread.sleep(..) 語句,以免讓模擬分析器獲取0毫秒 - 這里的01234毫秒并非是AOP引入的系統(tǒng)開銷。)

Calculating entitlement
                    
                    StopWatch 'ProfilingAspect': running time (millis) = 1234
                    ------ ----- ----------------------------
                    ms     %     Task name
                    ------ ----- ----------------------------
                01234  100%  calculateEntitlement

因為這個LTW使用成熟的AspectJ,我們并不局限于通知Spring beans的方法;接下來這個稍有變化的 Main程序將生成同樣的結果。

package foo;
                    
                    import org.springframework.context.support.ClassPathXmlApplicationContext;
                    
                    public final class Main {
                    
                    public static void main(String[] args) {
                    
                    new ClassPathXmlApplicationContext("beans.xml", Main.class);
                    
                    EntitlementCalculationService entitlementCalculationService =
                    new StubEntitlementCalculationService();
                    
                    // the profiling aspect will be 'woven' around this method execution
                    entitlementCalculationService.calculateEntitlement();
                    }
                }

注意以上程序我們只是引導了Spring容器,然后完全在Spring上下文之外創(chuàng)建了一個 StubEntitlementCalculationService的實例...分析通知仍然得到織入。

上面的例子雖然簡單了些,但Spring中基本的LTW支持都已介紹完了, 此節(jié)余下內容將對使用這些配置和用法背后的理由作詳細解釋。

注意

ProfilingAspect在此例中雖然基本但是頗為有用。這是一個很好的開發(fā)時切面的例子,開發(fā)者可以在開發(fā)過程中使用它(廢話), 然后也能從已部署到UAT或者生產環(huán)境的應用中輕易的脫離。

6.8.4.2.?切面

你在LTW中使用的切面必須是AspectJ切面。你可以使用AspectJ語言或者類@AspectJ風格來編寫你的切面。 后一種方式當然只能在Java 5+中使用,但它說明了你的切面可以同時對AspectJ和Spring AOP切面有效。 此外,編譯后的切面類需要被注冊到classpath下。

6.8.4.3.?'META-INF/aop.xml'

AspectJ LTW的基礎設施是用一個或多個位于Java classpath上的(可以是直接的文件形式, 也可以是更典型的jar包形式)META-INF/aop.xml文件配置起來的。

有關文件的結構和內容都在AspectJ的參考文檔中有詳細介紹,有興趣的讀者 請參考這些資源。(很慶幸這一節(jié)比較簡短,但aop.xml文件 是100% AspectJ的 - 沒有任何使用Spring特定的信息或語義,因此我也沒有什么可貢獻的。 與其重寫這些已由AspectJ開發(fā)者提供的令人滿意的章節(jié),我不如領你到這里。)

6.8.4.4.?相關類庫(JARS)

你至少需要以下類庫來讓Spring框架支持AspectJ LTW:

  1. spring.jar(2.5或更高版本)

  2. aspectjrt.jar (1.5或更高版本)

  3. aspectjweaver.jar (1.5或更高版本)

如果你正在使用 由Spring提供的代理來激活檢測(instrumentation)功能,你會需要:

  1. spring-agent.jar

6.8.4.5.?Spring配置

Spring LTW功能的關鍵組件是LoadTimeWeaver接口 (在org.springframework.instrument.classloading包中), 以及Spring分發(fā)包中大量的實現(xiàn)。LoadTimeWeaver的實現(xiàn)負責 在運行時把一個或多個java.lang.instrument.ClassFileTransformers類添加到 ClassLoader中,這能產生各種各樣有趣的應用,LTW切面恰好便是其中之一。

提示

如果你對運行時類文件變換的思想還不熟悉,推薦你在繼續(xù)之前閱讀 java.lang.instrument包的Javadoc API文檔。 這其實并不難-反而有些惱人-因為有用的文件并不多...關鍵的接口和類都將會在此節(jié)呈現(xiàn)給你。

用XML為ApplicationContext配置一個 LoadTimeWeaver簡單得只需要添加一行。 (請注意幾乎肯定你需要使用ApplicationContext作為你的 Spring容器 - 一般來說只有BeanFactory是不夠的, 因為LTW功能需要用到BeanFactoryPostProcessors。)

當要使用Spring框架的LTW功能時,你需要配置一個LoadTimeWeaver, 一般可以用<context:load-time-weaver/>元素來完成。 下面為一個有效的使用默認設置的<context:load-time-weaver/>定義。

<?xml version="1.0" encoding="UTF-8"?>
                    <beans xmlns="http://www.springframework.org/schema/beans"
                    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                    xmlns:context="http://www.springframework.org/schema/context"
                    xsi:schemaLocation="
                    http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
                    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd">
                    
                    <context:load-time-weaver/>
                    
                </beans>

上面<context:load-time-weaver/> bean的定義會自動為你定義和注冊若干 特定LTW的基礎設施beans,比如一個LoadTimeWeaver 和一個AspectJWeavingEnabler。請注意 <context:load-time-weaver/>是怎樣在context 命名空間下被定義的;還要注意被引用的XML Schema文件只在Spring 2.5或更高版本中才可用。

上面的配置為你定義并注冊了一個默認的LoadTimeWeaver bean。 默認的LoadTimeWeaver是一個 DefaultContextLoadTimeWeaver類,它更傾向于去裝飾一個能自動檢測的LoadTimeWeaver類:LoadTimeWeaver 的確切類型會根據你的運行時環(huán)境“自動檢測”出來(概述如下表)。

表?6.1.?DefaultContextLoadTimeWeaver LoadTimeWeaversDefaultContextLoadTimeWeaver類和LoadTimeWeavers接口

運行時環(huán)境 LoadTimeWeaver的接口實現(xiàn)

BEA's Weblogic 10環(huán)境下

WebLogicLoadTimeWeaver

Oracle's OC4J環(huán)境下

OC4JLoadTimeWeaver

GlassFish環(huán)境下

GlassFishLoadTimeWeaver

以SpringInstrumentationSavingAgent

啟動的JVM中

(java -javaagent:path/to/spring-agent.jar)

InstrumentationLoadTimeWeaver

不過,我們更希望這些類加載器能遵循共同的規(guī)范 (例如適用TomcatInstrumentableClassLoader和Resin)

ReflectiveLoadTimeWeaver


請注意當使用DefaultContextLoadTimeWeaver時只有 LoadTimeWeavers實現(xiàn)類能進行自動檢測: 當然,你也可以通過指定將類的完全限定名作為<context:load-time-weaver/> 元素中weaver-class屬性的值 來指定究竟想使用哪個LoadTimeWeaver的實現(xiàn)。如下例:

<?xml version="1.0" encoding="UTF-8"?>
                    <beans xmlns="http://www.springframework.org/schema/beans"
                    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                    xmlns:context="http://www.springframework.org/schema/context"
                    xsi:schemaLocation="
                    http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
                    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd">
                    
                    <context:load-time-weaver
                    weaver-class="org.springframework.instrument.classloading.ReflectiveLoadTimeWeaver"/>
                    
                </beans>

<context:load-time-weaver/>元素上定義和注冊的 LoadTimeWeaver接口可以在Spring容器中以 loadTimeWeaver名字找到。 記住LoadTimeWeaver接口只是作為Spring LTW基礎設施的一個機制 用來添加一個或多個ClassFileTransformers的。 ClassFileTransformer類實際是利用 ClassPreProcessorAgentAdapter類(包含在 org.aspectj.weaver.loadtime中)來進行LTW的。 有關ClassPreProcessorAgentAdapter的細節(jié)請參見 類級別的javadoc,織入實際怎樣生效的具體內容已經超出本節(jié)討論范圍。

讓我們來討論<context:load-time-weaver/>的最后一個屬性: aspectj-weaving。 這是一個簡單的LTW開關,就這么簡單。 它可以接受如下所述的三種值,如果不顯示設置此屬性則其默認值為autodetect

表?6.2.?aspectj-weaving屬性值

屬性值 注釋

on

AspectJ織入功能開啟,切面將會在加載時適當時機被織入。

off

LTW功能關閉...不會在加載時織入切面。

autodetect

如果Spring LTW基礎設施能找到至少一個META-INF/aop.xml 文件,那么AspectJ織入將會開啟,否則關閉。此為默認值。


6.8.4.6.?特定環(huán)境的配置

這最后一節(jié)包括所有你在諸如應用服務器和web容器中使用Spring的LTW功能時需要的額外設置和配置。

6.8.4.6.1.?通用Java應用

你可能在各種Java應用中通過使用由Spring提供的檢測代理啟用Spring的LTW功能 (獨立應用或者基于應用服務器的應用)。這樣的話,可以通過指定 -javaagent:path/to/spring-agent.jar選項來啟動虛擬機。 請注意這需要修改虛擬機的啟動腳本,但在某些應用服務器環(huán)境下是禁止這么做的 (這取決于你的操作策略)。

6.8.4.6.2.?Tomcat

對于部署在Apache Tomcat 5.0或更高版本上的web應用,Spring將一個 TomcatInstrumentableClassLoader注冊成為web應用的類加載器。 必須的Tomcat設置如下所示,你可以把它放在Tomcat WAR包根目錄下的核心文件 server.xml中或放到應用特定的META-INF/context.xml文件中。 Spring的spring-tomcat-weaver.jar需要被包含到Tomcat 的common lib路徑下以確保設置生效。

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

注意:當使用LTW時,我們一般推薦使用Tomcat 5.5.20或更高版本。 先前的版本對定制的ClassLoader設置會產生問題。

另外,請考慮使用在Tomcat啟動腳本中(見上面)指定由Spring提供的通用虛擬機代理。 這樣才能使檢測功能在所有已部署的web應用中可用,無論其上運行的是哪種類加載器。

有關更多基于Tomcat織入設置的詳細討論,請參考討論各種不同Tomcat版本內容的 第?12.6.1.3.1?節(jié) “Tomcat(5.0以上)加載時的織入配置”一節(jié)。雖然本節(jié)主要關注于 JPA persistence提供者的設置,但也談到了Tomcat各種特定設置適用于一般加載時織入的情況。

6.8.4.6.3.?WebLogic, OC4J, Resin, GlassFish

BEA WebLogic(版本10或更高),Oracle的JavaEE容器(OC4J 10.1.3.1或更高)以及 Resin(版本3.1或更高)提供具有本地檢測能力的類加載器。 Srping的原生LTW利用這些類加載器來激活AspectJ織入。你可以通過簡單地激活之前提到的 context:load-time-weaver來啟動LTW功能。具體來說,即你 需要通過修改啟動腳本來添加 -javaagent:path/to/spring-agent.jar。

GlassFish同樣也提供了檢測能力的類加載器,不過只能在它的EAR環(huán)境下使用。 對于GlassFish的web應用,可以使用跟上面tomcat相同的設置。

Article précédent: Article suivant: