无码不卡亚洲成?人片,亚洲精品无码久久久久,亚洲aⅴ无码专区在线观看春色http://www.tkk7.com/sxyx2008/category/45651.html溫馨提示:您的每一次轉載,體現了我寫此文的意義!!!煩請您在轉載時注明出處http://www.tkk7.com/sxyx2008/謝謝合作!!! zh-cnWed, 03 Apr 2013 10:08:27 GMTWed, 03 Apr 2013 10:08:27 GMT60基于maven的多框架和多視圖融合技術(Struts1、Struts2、Spring、SpringMVC、Hibernate、Ibatis、MyBatis、Spring Data JPA、DWR)http://www.tkk7.com/sxyx2008/archive/2012/09/25/388490.html雪山飛鵠雪山飛鵠Tue, 25 Sep 2012 03:40:00 GMThttp://www.tkk7.com/sxyx2008/archive/2012/09/25/388490.htmlhttp://www.tkk7.com/sxyx2008/comments/388490.htmlhttp://www.tkk7.com/sxyx2008/archive/2012/09/25/388490.html#Feedback0http://www.tkk7.com/sxyx2008/comments/commentRss/388490.htmlhttp://www.tkk7.com/sxyx2008/services/trackbacks/388490.html該項目基于maven3.0構建的,項目中融合了Struts1、Struts2、Spring、SpringMVC、Hibernate、Ibatis、MyBatis、Spring Data JPA、Spring JDBC、Spring DWR。頁面展現這里使用Struts1、Struts2、SpringMVC(jsp視圖、velocity視圖、freemarker視圖、pdf視圖、excel視圖、xml視圖、json視圖等)。是一個綜合性行的項目。該項目后期會陸續集成Spring的一些好的框架進來比如說Spring Web Flow、Spring Security 、Jbpm、WebService、Compass、Solr、nutch等??傊且粋€綜合性的項目。該項目不處理業務,主要是把目前自己工作中用到過的各種框架糅合到一個項目中。純粹是一個jee框架的糅合,主要是介紹各種技術。

介紹下目前使用的各個框架的版本信息

Struts1 1.3.10

Struts2 2.3.8

Spring 3.2.0.RELEASE

Hibernate 4.2.0.Final

Ibatis 2.3.4.726

MyBatis 3.1.1

Spring Data JPA 1.3.0.RELEASE

DWR 3.0.M1

項目中的持久化框架sql語句的跟蹤采用了log4jdbc4結合log4j,在控制臺可以看到完整的sql語句。

該項目中使用到的技術均與Spring已集成。除了DWR與Spring集成使用xml文件中配置bean外 其他的bean均使用注解完善。每一個與數據庫有關的都有事務處理。

項目結構圖


項目托管SVN地址:http://maven-framework-project.googlecode.com/svn/trunk/ (限于大陸google code 不穩定,導致經常無法訪問,該地址已不在同步,建議使用github地址)
項目托管GitHub地址:https://github.com/sxyx2008/maven-framework-project/(推薦使用)

最后希望有興趣的朋友可以加入進來,大家一起完善他。把自己的技術分享出來。如有任何問題可以與我聯系

聯系方式

QQ:184675420

Email:sxyx2008@gmail.com



雪山飛鵠 2012-09-25 11:40 發表評論
]]>
使用 Spring 2.5 注釋驅動的 IoC 功能http://www.tkk7.com/sxyx2008/archive/2012/03/13/371791.html雪山飛鵠雪山飛鵠Tue, 13 Mar 2012 03:36:00 GMThttp://www.tkk7.com/sxyx2008/archive/2012/03/13/371791.htmlhttp://www.tkk7.com/sxyx2008/comments/371791.htmlhttp://www.tkk7.com/sxyx2008/archive/2012/03/13/371791.html#Feedback0http://www.tkk7.com/sxyx2008/comments/commentRss/371791.htmlhttp://www.tkk7.com/sxyx2008/services/trackbacks/371791.html概述

注釋配置相對于 XML 配置具有很多的優勢:

  • 它可以充分利用 Java 的反射機制獲取類結構信息,這些信息可以有效減少配置的工作。如使用 JPA 注釋配置 ORM 映射時,我們就不需要指定 PO 的屬性名、類型等信息,如果關系表字段和 PO 屬性名、類型都一致,您甚至無需編寫任務屬性映射信息——因為這些信息都可以通過 Java 反射機制獲取。
  • 注釋和 Java 代碼位于一個文件中,而 XML 配置采用獨立的配置文件,大多數配置信息在程序開發完成后都不會調整,如果配置信息和 Java 代碼放在一起,有助于增強程序的內聚性。而采用獨立的 XML 配置文件,程序員在編寫一個功能時,往往需要在程序文件和配置文件中不停切換,這種思維上的不連貫會降低開發效率。

因此在很多情況下,注釋配置比 XML 配置更受歡迎,注釋配置有進一步流行的趨勢。Spring 2.5 的一大增強就是引入了很多注釋類,現在您已經可以使用注釋配置完成大部分 XML 配置的功能。在這篇文章里,我們將向您講述使用注釋進行 Bean 定義和依賴注入的內容。


原來我們是怎么做的

在使用注釋配置之前,先來回顧一下傳統上是如何配置 Bean 并完成 Bean 之間依賴關系的建立。下面是 3 個類,它們分別是 Office、Car 和 Boss,這 3 個類需要在 Spring 容器中配置為 Bean:

Office 僅有一個屬性:


清單 1. Office.java
            package com.baobaotao;
            public class Office {
            private String officeNo =”001”;
            //省略 get/setter
            @Override
            public String toString() {
            return "officeNo:" + officeNo;
            }
            }
            

Car 擁有兩個屬性:


清單 2. Car.java
            package com.baobaotao;
            public class Car {
            private String brand;
            private double price;
            // 省略 get/setter
            @Override
            public String toString() {
            return "brand:" + brand + "," + "price:" + price;
            }
            }
            

Boss 擁有 Office 和 Car 類型的兩個屬性:


清單 3. Boss.java
            package com.baobaotao;
            public class Boss {
            private Car car;
            private Office office;
            // 省略 get/setter
            @Override
            public String toString() {
            return "car:" + car + "\n" + "office:" + office;
            }
            }
            

我們在 Spring 容器中將 Office 和 Car 聲明為 Bean,并注入到 Boss Bean 中:下面是使用傳統 XML 完成這個工作的配置文件 beans.xml:


清單 4. beans.xml 將以上三個類配置成 Bean
            <?xml version="1.0" encoding="UTF-8" ?>
            <beans xmlns="http://www.springframework.org/schema/beans"
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xsi:schemaLocation="http://www.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
            <bean id="boss" class="com.baobaotao.Boss">
            <property name="car" ref="car"/>
            <property name="office" ref="office" />
            </bean>
            <bean id="office" class="com.baobaotao.Office">
            <property name="officeNo" value="002"/>
            </bean>
            <bean id="car" class="com.baobaotao.Car" scope="singleton">
            <property name="brand" value=" 紅旗 CA72"/>
            <property name="price" value="2000"/>
            </bean>
            </beans>
            

當我們運行以下代碼時,控制臺將正確打出 boss 的信息:


清單 5. 測試類:AnnoIoCTest.java
            import org.springframework.context.ApplicationContext;
            import org.springframework.context.support.ClassPathXmlApplicationContext;
            public class AnnoIoCTest {
            public static void main(String[] args) {
            String[] locations = {"beans.xml"};
            ApplicationContext ctx =
            new ClassPathXmlApplicationContext(locations);
            Boss boss = (Boss) ctx.getBean("boss");
            System.out.println(boss);
            }
            }
            

這說明 Spring 容器已經正確完成了 Bean 創建和裝配的工作。


使用 @Autowired 注釋

Spring 2.5 引入了 @Autowired 注釋,它可以對類成員變量、方法及構造函數進行標注,完成自動裝配的工作。來看一下使用 @Autowired 進行成員變量自動注入的代碼:


清單 6. 使用 @Autowired 注釋的 Boss.java
            package com.baobaotao;
            import org.springframework.beans.factory.annotation.Autowired;
            public class Boss {
            @Autowired
            private Car car;
            @Autowired
            private Office office;
            …
            }
            

Spring 通過一個 BeanPostProcessor@Autowired 進行解析,所以要讓 @Autowired 起作用必須事先在 Spring 容器中聲明 AutowiredAnnotationBeanPostProcessor Bean。


清單 7. 讓 @Autowired 注釋工作起來
            <?xml version="1.0" encoding="UTF-8" ?>
            <beans xmlns="http://www.springframework.org/schema/beans"
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xsi:schemaLocation="http://www.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
            <!-- 該 BeanPostProcessor 將自動起作用,對標注 @Autowired 的 Bean 進行自動注入 -->
            <bean class="org.springframework.beans.factory.annotation.
            AutowiredAnnotationBeanPostProcessor"/>
            <!-- 移除 boss Bean 的屬性注入配置的信息 -->
            <bean id="boss" class="com.baobaotao.Boss"/>
            <bean id="office" class="com.baobaotao.Office">
            <property name="officeNo" value="001"/>
            </bean>
            <bean id="car" class="com.baobaotao.Car" scope="singleton">
            <property name="brand" value=" 紅旗 CA72"/>
            <property name="price" value="2000"/>
            </bean>
            </beans>
            

這樣,當 Spring 容器啟動時,AutowiredAnnotationBeanPostProcessor 將掃描 Spring 容器中所有 Bean,當發現 Bean 中擁有 @Autowired 注釋時就找到和其匹配(默認按類型匹配)的 Bean,并注入到對應的地方中去。

按照上面的配置,Spring 將直接采用 Java 反射機制對 Boss 中的 caroffice 這兩個私有成員變量進行自動注入。所以對成員變量使用 @Autowired 后,您大可將它們的 setter 方法(setCar()setOffice())從 Boss 中刪除。

當然,您也可以通過 @Autowired 對方法或構造函數進行標注,來看下面的代碼:


清單 8. 將 @Autowired 注釋標注在 Setter 方法上
            package com.baobaotao;
            public class Boss {
            private Car car;
            private Office office;
            @Autowired
            public void setCar(Car car) {
            this.car = car;
            }
            @Autowired
            public void setOffice(Office office) {
            this.office = office;
            }
            …
            }
            

這時,@Autowired 將查找被標注的方法的入參類型的 Bean,并調用方法自動注入這些 Bean。而下面的使用方法則對構造函數進行標注:


清單 9. 將 @Autowired 注釋標注在構造函數上
            package com.baobaotao;
            public class Boss {
            private Car car;
            private Office office;
            @Autowired
            public Boss(Car car ,Office office){
            this.car = car;
            this.office = office ;
            }
            …
            }
            

由于 Boss() 構造函數有兩個入參,分別是 caroffice,@Autowired 將分別尋找和它們類型匹配的 Bean,將它們作為 Boss(Car car ,Office office) 的入參來創建 Boss Bean。


當候選 Bean 數目不為 1 時的應對方法

在默認情況下使用 @Autowired 注釋進行自動注入時,Spring 容器中匹配的候選 Bean 數目必須有且僅有一個。當找不到一個匹配的 Bean 時,Spring 容器將拋出 BeanCreationException 異常,并指出必須至少擁有一個匹配的 Bean。我們可以來做一個實驗:


清單 10. 候選 Bean 數目為 0 時
            <?xml version="1.0" encoding="UTF-8" ?>
            <beans xmlns="http://www.springframework.org/schema/beans"
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xsi:schemaLocation="http://www.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans-2.5.xsd ">
            <bean class="org.springframework.beans.factory.annotation.
            AutowiredAnnotationBeanPostProcessor"/>
            <bean id="boss" class="com.baobaotao.Boss"/>
            <!-- 將 office Bean 注釋掉 -->
            <!-- <bean id="office" class="com.baobaotao.Office">
            <property name="officeNo" value="001"/>
            </bean>-->
            <bean id="car" class="com.baobaotao.Car" scope="singleton">
            <property name="brand" value=" 紅旗 CA72"/>
            <property name="price" value="2000"/>
            </bean>
            </beans>
            

由于 office Bean 被注釋掉了,所以 Spring 容器中將沒有類型為 Office 的 Bean 了,而 Boss 的 office 屬性標注了 @Autowired,當啟動 Spring 容器時,異常就產生了。

當不能確定 Spring 容器中一定擁有某個類的 Bean 時,可以在需要自動注入該類 Bean 的地方可以使用 @Autowired(required = false),這等于告訴 Spring:在找不到匹配 Bean 時也不報錯。來看一下具體的例子:


清單 11. 使用 @Autowired(required = false)
            package com.baobaotao;
            import org.springframework.beans.factory.annotation.Autowired;
            import org.springframework.beans.factory.annotation.Required;
            public class Boss {
            private Car car;
            private Office office;
            @Autowired
            public void setCar(Car car) {
            this.car = car;
            }
            @Autowired(required = false)
            public void setOffice(Office office) {
            this.office = office;
            }
            …
            }
            

當然,一般情況下,使用 @Autowired 的地方都是需要注入 Bean 的,使用了自動注入而又允許不注入的情況一般僅會在開發期或測試期碰到(如為了快速啟動 Spring 容器,僅引入一些模塊的 Spring 配置文件),所以 @Autowired(required = false) 會很少用到。

和找不到一個類型匹配 Bean 相反的一個錯誤是:如果 Spring 容器中擁有多個候選 Bean,Spring 容器在啟動時也會拋出 BeanCreationException 異常。來看下面的例子:


清單 12. 在 beans.xml 中配置兩個 Office 類型的 Bean
            …
            <bean id="office" class="com.baobaotao.Office">
            <property name="officeNo" value="001"/>
            </bean>
            <bean id="office2" class="com.baobaotao.Office">
            <property name="officeNo" value="001"/>
            </bean>
            …
            

我們在 Spring 容器中配置了兩個類型為 Office 類型的 Bean,當對 Boss 的 office 成員變量進行自動注入時,Spring 容器將無法確定到底要用哪一個 Bean,因此異常發生了。

Spring 允許我們通過 @Qualifier 注釋指定注入 Bean 的名稱,這樣歧義就消除了,可以通過下面的方法解決異常:


清單 13. 使用 @Qualifier 注釋指定注入 Bean 的名稱
            @Autowired
            public void setOffice(@Qualifier("office")Office office) {
            this.office = office;
            }
            

@Qualifier("office") 中的 office 是 Bean 的名稱,所以 @Autowired@Qualifier 結合使用時,自動注入的策略就從 byType 轉變成 byName 了。@Autowired 可以對成員變量、方法以及構造函數進行注釋,而 @Qualifier 的標注對象是成員變量、方法入參、構造函數入參。正是由于注釋對象的不同,所以 Spring 不將 @Autowired@Qualifier 統一成一個注釋類。下面是對成員變量和構造函數入參進行注釋的代碼:

對成員變量進行注釋:


清單 14. 對成員變量使用 @Qualifier 注釋
            public class Boss {
            @Autowired
            private Car car;
            @Autowired
            @Qualifier("office")
            private Office office;
            …
            }
            

對構造函數入參進行注釋:


清單 15. 對構造函數變量使用 @Qualifier 注釋
            public class Boss {
            private Car car;
            private Office office;
            @Autowired
            public Boss(Car car , @Qualifier("office")Office office){
            this.car = car;
            this.office = office ;
            }
            }
            

@Qualifier 只能和 @Autowired 結合使用,是對 @Autowired 有益的補充。一般來講,@Qualifier 對方法簽名中入參進行注釋會降低代碼的可讀性,而對成員變量注釋則相對好一些。


使用 JSR-250 的注釋

Spring 不但支持自己定義的 @Autowired 的注釋,還支持幾個由 JSR-250 規范定義的注釋,它們分別是 @Resource、@PostConstruct 以及 @PreDestroy。

@Resource

@Resource 的作用相當于 @Autowired,只不過 @Autowired 按 byType 自動注入,面 @Resource 默認按 byName 自動注入罷了。@Resource 有兩個屬性是比較重要的,分別是 name 和 type,Spring 將 @Resource 注釋的 name 屬性解析為 Bean 的名字,而 type 屬性則解析為 Bean 的類型。所以如果使用 name 屬性,則使用 byName 的自動注入策略,而使用 type 屬性時則使用 byType 自動注入策略。如果既不指定 name 也不指定 type 屬性,這時將通過反射機制使用 byName 自動注入策略。

Resource 注釋類位于 Spring 發布包的 lib/j2ee/common-annotations.jar 類包中,因此在使用之前必須將其加入到項目的類庫中。來看一個使用 @Resource 的例子:


清單 16. 使用 @Resource 注釋的 Boss.java
            package com.baobaotao;
            import javax.annotation.Resource;
            public class Boss {
            // 自動注入類型為 Car 的 Bean
            @Resource
            private Car car;
            // 自動注入 bean 名稱為 office 的 Bean
            @Resource(name = "office")
            private Office office;
            }
            

一般情況下,我們無需使用類似于 @Resource(type=Car.class) 的注釋方式,因為 Bean 的類型信息可以通過 Java 反射從代碼中獲取。

要讓 JSR-250 的注釋生效,除了在 Bean 類中標注這些注釋外,還需要在 Spring 容器中注冊一個負責處理這些注釋的 BeanPostProcessor

<bean
            class="org.springframework.context.annotation.CommonAnnotationBeanPostProcessor"/>
            

CommonAnnotationBeanPostProcessor 實現了 BeanPostProcessor 接口,它負責掃描使用了 JSR-250 注釋的 Bean,并對它們進行相應的操作。

@PostConstruct 和 @PreDestroy

Spring 容器中的 Bean 是有生命周期的,Spring 允許在 Bean 在初始化完成后以及 Bean 銷毀前執行特定的操作,您既可以通過實現 InitializingBean/DisposableBean 接口來定制初始化之后 / 銷毀之前的操作方法,也可以通過 <bean> 元素的 init-method/destroy-method 屬性指定初始化之后 / 銷毀之前調用的操作方法。關于 Spring 的生命周期,筆者在《精通 Spring 2.x—企業應用開發精解》第 3 章進行了詳細的描述,有興趣的讀者可以查閱。

JSR-250 為初始化之后/銷毀之前方法的指定定義了兩個注釋類,分別是 @PostConstruct 和 @PreDestroy,這兩個注釋只能應用于方法上。標注了 @PostConstruct 注釋的方法將在類實例化后調用,而標注了 @PreDestroy 的方法將在類銷毀之前調用。


清單 17. 使用 @PostConstruct 和 @PreDestroy 注釋的 Boss.java
            package com.baobaotao;
            import javax.annotation.Resource;
            import javax.annotation.PostConstruct;
            import javax.annotation.PreDestroy;
            public class Boss {
            @Resource
            private Car car;
            @Resource(name = "office")
            private Office office;
            @PostConstruct
            public void postConstruct1(){
            System.out.println("postConstruct1");
            }
            @PreDestroy
            public void preDestroy1(){
            System.out.println("preDestroy1");
            }
            …
            }
            

您只需要在方法前標注 @PostConstruct@PreDestroy,這些方法就會在 Bean 初始化后或銷毀之前被 Spring 容器執行了。

我們知道,不管是通過實現 InitializingBean/DisposableBean 接口,還是通過 <bean> 元素的 init-method/destroy-method 屬性進行配置,都只能為 Bean 指定一個初始化 / 銷毀的方法。但是使用 @PostConstruct@PreDestroy 注釋卻可以指定多個初始化 / 銷毀方法,那些被標注 @PostConstruct@PreDestroy 注釋的方法都會在初始化 / 銷毀時被執行。

通過以下的測試代碼,您將可以看到 Bean 的初始化 / 銷毀方法是如何被執行的:


清單 18. 測試類代碼
            package com.baobaotao;
            import org.springframework.context.support.ClassPathXmlApplicationContext;
            public class AnnoIoCTest {
            public static void main(String[] args) {
            String[] locations = {"beans.xml"};
            ClassPathXmlApplicationContext ctx =
            new ClassPathXmlApplicationContext(locations);
            Boss boss = (Boss) ctx.getBean("boss");
            System.out.println(boss);
            ctx.destroy();// 關閉 Spring 容器,以觸發 Bean 銷毀方法的執行
            }
            }
            

這時,您將看到標注了 @PostConstructpostConstruct1() 方法將在 Spring 容器啟動時,創建 Boss Bean 的時候被觸發執行,而標注了 @PreDestroy 注釋的 preDestroy1() 方法將在 Spring 容器關閉前銷毀 Boss Bean 的時候被觸發執行。


使用 <context:annotation-config/> 簡化配置

Spring 2.1 添加了一個新的 context 的 Schema 命名空間,該命名空間對注釋驅動、屬性文件引入、加載期織入等功能提供了便捷的配置。我們知道注釋本身是不會做任何事情的,它僅提供元數據信息。要使元數據信息真正起作用,必須讓負責處理這些元數據的處理器工作起來。

而我們前面所介紹的 AutowiredAnnotationBeanPostProcessorCommonAnnotationBeanPostProcessor 就是處理這些注釋元數據的處理器。但是直接在 Spring 配置文件中定義這些 Bean 顯得比較笨拙。Spring 為我們提供了一種方便的注冊這些 BeanPostProcessor 的方式,這就是 <context:annotation-config/>。請看下面的配置:


清單 19. 調整 beans.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">
            <context:annotation-config/>
            <bean id="boss" class="com.baobaotao.Boss"/>
            <bean id="office" class="com.baobaotao.Office">
            <property name="officeNo" value="001"/>
            </bean>
            <bean id="car" class="com.baobaotao.Car" scope="singleton">
            <property name="brand" value=" 紅旗 CA72"/>
            <property name="price" value="2000"/>
            </bean>
            </beans>
            

<context:annotationconfig/> 將隱式地向 Spring 容器注冊 AutowiredAnnotationBeanPostProcessorCommonAnnotationBeanPostProcessor、PersistenceAnnotationBeanPostProcessor 以及 equiredAnnotationBeanPostProcessor 這 4 個 BeanPostProcessor。

在配置文件中使用 context 命名空間之前,必須在 <beans> 元素中聲明 context 命名空間。


使用 @Component

雖然我們可以通過 @Autowired@Resource 在 Bean 類中使用自動注入功能,但是 Bean 還是在 XML 文件中通過 <bean> 進行定義 —— 也就是說,在 XML 配置文件中定義 Bean,通過 @Autowired@Resource 為 Bean 的成員變量、方法入參或構造函數入參提供自動注入的功能。能否也通過注釋定義 Bean,從 XML 配置文件中完全移除 Bean 定義的配置呢?答案是肯定的,我們通過 Spring 2.5 提供的 @Component 注釋就可以達到這個目標了。

下面,我們完全使用注釋定義 Bean 并完成 Bean 之間裝配:


清單 20. 使用 @Component 注釋的 Car.java
            package com.baobaotao;
            import org.springframework.stereotype.Component;
            @Component
            public class Car {
            …
            }
            

僅需要在類定義處,使用 @Component 注釋就可以將一個類定義了 Spring 容器中的 Bean。下面的代碼將 Office 定義為一個 Bean:


清單 21. 使用 @Component 注釋的 Office.java
            package com.baobaotao;
            import org.springframework.stereotype.Component;
            @Component
            public class Office {
            private String officeNo = "001";
            …
            }
            

這樣,我們就可以在 Boss 類中通過 @Autowired 注入前面定義的 CarOffice Bean 了。


清單 22. 使用 @Component 注釋的 Boss.java
            package com.baobaotao;
            import org.springframework.beans.factory.annotation.Autowired;
            import org.springframework.beans.factory.annotation.Required;
            import org.springframework.beans.factory.annotation.Qualifier;
            import org.springframework.stereotype.Component;
            @Component("boss")
            public class Boss {
            @Autowired
            private Car car;
            @Autowired
            private Office office;
            …
            }
            

@Component 有一個可選的入參,用于指定 Bean 的名稱,在 Boss 中,我們就將 Bean 名稱定義為“boss”。一般情況下,Bean 都是 singleton 的,需要注入 Bean 的地方僅需要通過 byType 策略就可以自動注入了,所以大可不必指定 Bean 的名稱。

在使用 @Component 注釋后,Spring 容器必須啟用類掃描機制以啟用注釋驅動 Bean 定義和注釋驅動 Bean 自動注入的策略。Spring 2.5 對 context 命名空間進行了擴展,提供了這一功能,請看下面的配置:


清單 23. 簡化版的 beans.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">
            <context:component-scan base-package="com.baobaotao"/>
            </beans>
            

這里,所有通過 <bean> 元素定義 Bean 的配置內容已經被移除,僅需要添加一行 <context:component-scan/> 配置就解決所有問題了——Spring XML 配置文件得到了極致的簡化(當然配置元數據還是需要的,只不過以注釋形式存在罷了)。<context:component-scan/> 的 base-package 屬性指定了需要掃描的類包,類包及其遞歸子包中所有的類都會被處理。

<context:component-scan/> 還允許定義過濾器將基包下的某些類納入或排除。Spring 支持以下 4 種類型的過濾方式,通過下表說明:


表 1. 掃描過濾方式
過濾器類型 說明
注釋 假如 com.baobaotao.SomeAnnotation 是一個注釋類,我們可以將使用該注釋的類過濾出來。
類名指定 通過全限定類名進行過濾,如您可以指定將 com.baobaotao.Boss 納入掃描,而將 com.baobaotao.Car 排除在外。
正則表達式 通過正則表達式定義過濾的類,如下所示: com\.baobaotao\.Default.*
AspectJ 表達式 通過 AspectJ 表達式定義過濾的類,如下所示: com. baobaotao..*Service+

下面是一個簡單的例子:

<context:component-scan base-package="com.baobaotao">
            <context:include-filter type="regex"
            expression="com\.baobaotao\.service\..*"/>
            <context:exclude-filter type="aspectj"
            expression="com.baobaotao.util..*"/>
            </context:component-scan>
            

值得注意的是 <context:component-scan/> 配置項不但啟用了對類包進行掃描以實施注釋驅動 Bean 定義的功能,同時還啟用了注釋驅動自動注入的功能(即還隱式地在內部注冊了 AutowiredAnnotationBeanPostProcessorCommonAnnotationBeanPostProcessor),因此當使用 <context:component-scan/> 后,就可以將 <context:annotation-config/> 移除了。

默認情況下通過 @Component 定義的 Bean 都是 singleton 的,如果需要使用其它作用范圍的 Bean,可以通過 @Scope 注釋來達到目標,如以下代碼所示:


清單 24. 通過 @Scope 指定 Bean 的作用范圍
            package com.baobaotao;
            import org.springframework.context.annotation.Scope;
            …
            @Scope("prototype")
            @Component("boss")
            public class Boss {
            …
            }
            

這樣,當從 Spring 容器中獲取 boss Bean 時,每次返回的都是新的實例了。


采用具有特殊語義的注釋

Spring 2.5 中除了提供 @Component 注釋外,還定義了幾個擁有特殊語義的注釋,它們分別是:@Repository、@Service@Controller。在目前的 Spring 版本中,這 3 個注釋和 @Component 是等效的,但是從注釋類的命名上,很容易看出這 3 個注釋分別和持久層、業務層和控制層(Web 層)相對應。雖然目前這 3 個注釋和 @Component 相比沒有什么新意,但 Spring 將在以后的版本中為它們添加特殊的功能。所以,如果 Web 應用程序采用了經典的三層分層結構的話,最好在持久層、業務層和控制層分別采用 @Repository、@Service@Controller 對分層中的類進行注釋,而用 @Component 對那些比較中立的類進行注釋。


注釋配置和 XML 配置的適用場合

是否有了這些 IOC 注釋,我們就可以完全摒除原來 XML 配置的方式呢?答案是否定的。有以下幾點原因:

  • 注釋配置不一定在先天上優于 XML 配置。如果 Bean 的依賴關系是固定的,(如 Service 使用了哪幾個 DAO 類),這種配置信息不會在部署時發生調整,那么注釋配置優于 XML 配置;反之如果這種依賴關系會在部署時發生調整,XML 配置顯然又優于注釋配置,因為注釋是對 Java 源代碼的調整,您需要重新改寫源代碼并重新編譯才可以實施調整。
  • 如果 Bean 不是自己編寫的類(如 JdbcTemplate、SessionFactoryBean 等),注釋配置將無法實施,此時 XML 配置是唯一可用的方式。
  • 注釋配置往往是類級別的,而 XML 配置則可以表現得更加靈活。比如相比于 @Transaction 事務注釋,使用 aop/tx 命名空間的事務配置更加靈活和簡單。

所以在實現應用中,我們往往需要同時使用注釋配置和 XML 配置,對于類級別且不會發生變動的配置可以優先考慮注釋配置;而對于那些第三方類以及容易發生調整的配置則應優先考慮使用 XML 配置。Spring 會在具體實施 Bean 創建和 Bean 注入之前將這兩種配置方式的元信息融合在一起。


小結

Spring 在 2.1 以后對注釋配置提供了強力的支持,注釋配置功能成為 Spring 2.5 的最大的亮點之一。合理地使用 Spring 2.5 的注釋配置,可以有效減少配置的工作量,提高程序的內聚性。但是這并不意味著傳統 XML 配置將走向消亡,在第三方類 Bean 的配置,以及那些諸如數據源、緩存池、持久層操作模板類、事務管理等內容的配置上,XML 配置依然擁有不可替代的地位。



雪山飛鵠 2012-03-13 11:36 發表評論
]]>
SpringMvc多視圖整合(jsp、velocity、freemarker)http://www.tkk7.com/sxyx2008/archive/2011/07/13/354280.html雪山飛鵠雪山飛鵠Wed, 13 Jul 2011 09:14:00 GMThttp://www.tkk7.com/sxyx2008/archive/2011/07/13/354280.htmlhttp://www.tkk7.com/sxyx2008/comments/354280.htmlhttp://www.tkk7.com/sxyx2008/archive/2011/07/13/354280.html#Feedback1http://www.tkk7.com/sxyx2008/comments/commentRss/354280.htmlhttp://www.tkk7.com/sxyx2008/services/trackbacks/354280.html 
Spring配置文件
<?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:p
="http://www.springframework.org/schema/p"
    xmlns:context
="http://www.springframework.org/schema/context"
    xsi:schemaLocation
="
    http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context-3.0.xsd"
>
    
<context:component-scan
        
base-package="com.spring.action" />
    
<!--  
        org.springframework.web.servlet.view.ResourceBundleViewResolver
        用于多個視圖集成時,ResourceBundleViewResolver是通過解析資源文件來解析請求輸出文件的。
        <property name="basename" value="views"></property>,即表示在/WEB-INF/classes路徑下有一個
        views.properties文件,本例中views.properties的內容為
        welcome.(class)=org.springframework.web.servlet.view.velocity.VelocityView
        welcome.url=welcome.vm
        freemarker.(class)=org.springframework.web.servlet.view.freemarker.FreeMarkerView
        freemarker.url=freemarker.ftl
    
-->
    
<bean class="org.springframework.web.servlet.view.ResourceBundleViewResolver">
        
<property name="basename" value="views"></property>
        
<!-- 
            <property name="order" value="0"></property>
        
-->
    
</bean>
    
    
<!-- jsp視圖解析器 -->
    
<bean id="jspViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
        
<property name="prefix" value="/"/>
        
<property name="suffix" value=".jsp"/>
    
</bean>        
    
    
<!-- velocity視圖解析器 -->
    
<bean id="velocityViewResolver" class="org.springframework.web.servlet.view.velocity.VelocityViewResolver">
        
<property name="cache" value="true"/>
        
<property name="prefix" value="/"/>
        
<property name="suffix" value=".vm"/>
    
</bean>
    
    
<!-- velocity環境配置 -->
    
<bean id="velocityConfig" class="org.springframework.web.servlet.view.velocity.VelocityConfigurer">
        
<!-- velocity配置文件路徑 -->
        
<property name="configLocation" value="/WEB-INF/velocity.properties"/>
        
<!-- velocity模板路徑 -->
        
<property name="resourceLoaderPath" value="/WEB-INF/velocity/"/>
    
</bean>
    
    
<!-- FreeMarker環境配置 -->
    
<bean id="freemarkerConfig" class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
        
<!-- freemarker模板位置 -->
        
<property name="templateLoaderPath" value="/WEB-INF/freemarker/"/>
    
</bean>
    
    
<!-- FreeMarker視圖解析 -->
    
<bean id="freeMarkerViewResolver" class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver">
        
<property name="cache" value="true"/>
        
<property name="prefix" value="/"/>
        
<property name="suffix" value=".ftl"/>
    
</bean>
</beans>
views.properties
#welcome為modelAndView.setViewName("welcome");中的welcome   .(class)固定寫法
welcome.(class)=org.springframework.web.servlet.view.velocity.VelocityView
#welcome.url 路徑 welcome.vm模板名稱
welcome.url
=welcome.vm

#freemarker為modelAndView.setViewName(
"freemarker");中的freemarker   .(class)固定寫法
freemarker.(class)=org.springframework.web.servlet.view.freemarker.FreeMarkerView
#freemarker.url 路徑 freemarker.ftl模板名稱
freemarker.url
=freemarker.ftl
點我下載示例代碼

雪山飛鵠 2011-07-13 17:14 發表評論
]]>
Struts2、Spring、Hibernate、Lucene整合Compass實現搜索http://www.tkk7.com/sxyx2008/archive/2011/05/26/351109.html雪山飛鵠雪山飛鵠Thu, 26 May 2011 09:02:00 GMThttp://www.tkk7.com/sxyx2008/archive/2011/05/26/351109.htmlhttp://www.tkk7.com/sxyx2008/comments/351109.htmlhttp://www.tkk7.com/sxyx2008/archive/2011/05/26/351109.html#Feedback1http://www.tkk7.com/sxyx2008/comments/commentRss/351109.htmlhttp://www.tkk7.com/sxyx2008/services/trackbacks/351109.html        花時間嘗試著寫了個Struts2+Spring+Hibernate+Compass+Lucene整合的例子.代碼和jar包較多,有興趣的朋友可以去http://sshcompass.googlecode.com/svn/trunk/將工程撿下來。希望和大家一起探討Compass這個框架。


雪山飛鵠 2011-05-26 17:02 發表評論
]]>
基于注解的SpringMVC整合JPAhttp://www.tkk7.com/sxyx2008/archive/2010/11/02/336768.html雪山飛鵠雪山飛鵠Tue, 02 Nov 2010 02:47:00 GMThttp://www.tkk7.com/sxyx2008/archive/2010/11/02/336768.htmlhttp://www.tkk7.com/sxyx2008/comments/336768.htmlhttp://www.tkk7.com/sxyx2008/archive/2010/11/02/336768.html#Feedback3http://www.tkk7.com/sxyx2008/comments/commentRss/336768.htmlhttp://www.tkk7.com/sxyx2008/services/trackbacks/336768.html閱讀全文

雪山飛鵠 2010-11-02 10:47 發表評論
]]>
Spring AOP之HelloWorld annotation配置篇 http://www.tkk7.com/sxyx2008/archive/2010/10/29/336460.html雪山飛鵠雪山飛鵠Fri, 29 Oct 2010 03:11:00 GMThttp://www.tkk7.com/sxyx2008/archive/2010/10/29/336460.htmlhttp://www.tkk7.com/sxyx2008/comments/336460.htmlhttp://www.tkk7.com/sxyx2008/archive/2010/10/29/336460.html#Feedback0http://www.tkk7.com/sxyx2008/comments/commentRss/336460.htmlhttp://www.tkk7.com/sxyx2008/services/trackbacks/336460.html
UserDAO
package com.spring.dao;

import org.springframework.stereotype.Component;

@Component(
"userDAO")
public class UserDao {

    
public void say() {
        System.out.println(
"say method is called");
    }

    
public void smile() {
        System.out.println(
"smile method is called");
    }
    
    
public void cry() {
        System.out.println(
"cry method is called");
    }
    
    
public void jump() {
        System.out.println(
"jump method is called");
    }
}
不做過多解釋,不清楚的可參考上篇Spring AOP之HelloWorld xml配置
UserService
package com.spring.service;

import javax.annotation.Resource;

import org.springframework.stereotype.Component;

import com.spring.dao.UserDao;

@Component(
"userService")
public class UserService {
    
    @Resource(name
="userDAO")
    
private UserDao dao;

    
public UserDao getDao() {
        
return dao;
    }

    
public void setDao(UserDao dao) {
        
this.dao = dao;
    }
    
    
public void say() {
        dao.say();
    }

    
public void smile() {
        dao.smile();
    }
    
    
public void cry() {
        dao.cry();
    }
    
    
public void jump() {
        dao.jump();
    }
}
Aop攔截類
package com.spring.aop;

import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;

@Component(
"logIntercepter")
@Aspect
public class LogIntercepter {
    
    
/*public void before(){
        System.out.println("----------before-------------");
    }
    
    public void after(){
        System.out.println("----------after-------------");
    }
    
    public void exception(){
        System.out.println("----------exception-------------");
    }
    
    public void around(){
        System.out.println("----------exception-------------");
    }
*/
    
    @Before(
"execution(* com.spring.service..*.*(..))")
    
public void before(){
        System.out.println(
"----------before-------------");
    }
    
    @After(
"execution(* com.spring.service..*.*(..))")
    
public void after(){
        System.out.println(
"----------after-------------");
    }
    
    @AfterThrowing(
"execution(* com.spring.service..*.*(..))")
    
public void exception(){
        System.out.println(
"----------exception-------------");
    }
    
    
/*@Around("execution(* com.spring.service..*.*(..))")
    public void around(){
        System.out.println("----------exception-------------");
    }
*/
    

    
    
}
注意觀察
此類使用了@Aspect注解,你需要在spring配置文件中使用<aop:aspectj-autoproxy/>標簽開啟注解功能
接下來依次定義了一系列方法before、after、exception、around依次標注注解為@Before("execution(* com.spring.service..*.*(..))") 、@After("execution(* com.spring.service..*.*(..))")、@AfterThrowing("execution(* com.spring.service..*.*(..))")、@Around("execution(* com.spring.service..*.*(..))") ,分別為spring aop 的前置通知、后置通知、異常通知、環繞通知,當進入com.spring.service包或子包下的所有方法時他們都會起作用,其中異常通知,只有在該方法出現異常時才會調用
applicationContext.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:p
="http://www.springframework.org/schema/p"
    xmlns:context
="http://www.springframework.org/schema/context"
    xmlns:aop
="http://www.springframework.org/schema/aop"
    xsi:schemaLocation
="http://www.springframework.org/schema/beans 
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
    http://www.springframework.org/schema/context 
    http://www.springframework.org/schema/context/spring-context-3.0.xsd
    http://www.springframework.org/schema/aop
    http://www.springframework.org/schema/aop/spring-aop-3.0.xsd"
>
    
<context:annotation-config/>
    
<context:component-scan base-package="com.spring.*"/>
    
<aop:aspectj-autoproxy/>
    
    
<!-- 
        <aop:config>
            <aop:aspect id="aspect" ref="logIntercepter">
                <aop:pointcut expression="execution(* com.spring.service..*(..))" id="pointCut"/>
                <aop:before method="before" pointcut-ref="pointCut"/>
                <aop:after method="after" pointcut-ref="pointCut"/>
                <aop:after-throwing method="exception" pointcut-ref="pointCut"/>
                    <aop:around method="around" pointcut-ref="pointCut"/>
            </aop:aspect>
        </aop:config>
    
-->
        
</beans>
內容很簡單
就這三行
<context:annotation-config/>
<context:component-scan base-package="com.spring.*"/>
<aop:aspectj-autoproxy/>
其中注視部分為xml配置部分的代碼
單元測試
package com.spring.test;

import javax.annotation.Resource;

import org.junit.Test;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.AbstractJUnit4SpringContextTests;

import com.spring.service.UserService;

@ContextConfiguration(locations
="classpath:applicationContext.xml")
public class SpringTest extends AbstractJUnit4SpringContextTests {

    @Resource(name
="userService")
    
private UserService userService;
    
    @Test
    
public void test1(){
        userService.say();
        System.out.println();
        userService.smile();
        System.out.println();
        userService.cry();
    }
    
}
運行結果

----------before-------------
say method is called
----------after-------------

----------before-------------
smile method is called
----------after-------------

----------before-------------
cry method is called
----------after-------------

點我下載工程代碼



雪山飛鵠 2010-10-29 11:11 發表評論
]]>
Spring AOP之HelloWorld xml配置篇http://www.tkk7.com/sxyx2008/archive/2010/10/29/336454.html雪山飛鵠雪山飛鵠Fri, 29 Oct 2010 02:36:00 GMThttp://www.tkk7.com/sxyx2008/archive/2010/10/29/336454.htmlhttp://www.tkk7.com/sxyx2008/comments/336454.htmlhttp://www.tkk7.com/sxyx2008/archive/2010/10/29/336454.html#Feedback0http://www.tkk7.com/sxyx2008/comments/commentRss/336454.htmlhttp://www.tkk7.com/sxyx2008/services/trackbacks/336454.html
編寫dao
package com.spring.dao;

import org.springframework.stereotype.Component;

@Component(
"userDAO")
public class UserDao {

    
public void say() {
        System.out.println(
"say method is called");
    }

    
public void smile() {
        System.out.println(
"smile method is called");
    }
    
    
public void cry() {
        System.out.println(
"cry method is called");
    }
    
    
public void jump() {
        System.out.println(
"jump method is called");
    }
}
注意觀察包名。@Component("userDAO")等價于在spring配置文件中定義一個<bean id="userDAO"/>
編寫Service
package com.spring.service;

import javax.annotation.Resource;

import org.springframework.stereotype.Component;

import com.spring.dao.UserDao;

@Component(
"userService")
public class UserService {
    
    @Resource(name
="userDAO")
    
private UserDao dao;

    
public UserDao getDao() {
        
return dao;
    }

    
public void setDao(UserDao dao) {
        
this.dao = dao;
    }
    
    
public void say() {
        dao.say();
    }

    
public void smile() {
        dao.smile();
    }
    
    
public void cry() {
        dao.cry();
    }
    
    
public void jump() {
        dao.jump();
    }
}
注意觀察包名。@Component("userService")等價于在spring配置文件中定義一個<bean id="userService"/> @Resource(name="userDAO")將userDA注入進來
寫一個攔截器的類
package com.spring.aop;

import org.springframework.stereotype.Component;

@Component(
"logIntercepter")
public class LogIntercepter {
    
    
public void before(){
        System.out.println(
"----------before-------------");
    }
    
    
public void after(){
        System.out.println(
"----------after-------------");
    }
    
    
public void exception(){
        System.out.println(
"----------exception-------------");
    }
    
    
public void around(){
        System.out.println(
"----------exception-------------");
    }
}
注意觀察包名。@Component("logIntercepter")等價于在spring配置文件中定義一個<bean id="logIntercepter"/>
applicationContext.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:p
="http://www.springframework.org/schema/p"
    xmlns:context
="http://www.springframework.org/schema/context"
    xmlns:aop
="http://www.springframework.org/schema/aop"
    xsi:schemaLocation
="http://www.springframework.org/schema/beans 
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
    http://www.springframework.org/schema/context 
    http://www.springframework.org/schema/context/spring-context-3.0.xsd
    http://www.springframework.org/schema/aop
    http://www.springframework.org/schema/aop/spring-aop-3.0.xsd"
>
    
<context:annotation-config/>
    
<context:component-scan base-package="com.spring.*"/>
        
<aop:config>
            
<aop:aspect id="aspect" ref="logIntercepter">
                
<aop:pointcut expression="execution(* com.spring.service..*(..))" id="pointCut"/>
                
<aop:before method="before" pointcut-ref="pointCut"/>
                
<aop:after method="after" pointcut-ref="pointCut"/>
                
<aop:after-throwing method="exception" pointcut-ref="pointCut"/>
                
<!-- 
                    <aop:around method="around" pointcut-ref="pointCut"/>
                 
-->
            
</aop:aspect>
        
</aop:config>
</beans>
<context:annotation-config/>
 <context:component-scan base-package="com.spring.*"/>
兩行為開啟spring的注解配置
<aop:aspect id="aspect" ref="logIntercepter"> 引入具體的AOP操作類
<aop:pointcut expression="execution(* com.spring.service..*(..))" id="pointCut"/>聲明一個切入點,注意execution表達式的寫法
<aop:before method="before" pointcut-ref="pointCut"/> aop前置通知
<aop:after method="after" pointcut-ref="pointCut"/> aop后置通知,
<aop:after-throwing method="exception" pointcut-ref="pointCut"/> aop異常通知
以上結合起來意思就是在調用com.spring.service包或子包下的所有方法之前或之后或拋出異常時依次調用id為logIntercepter的類中的before after exception方法
測試用例
package com.spring.test;

import javax.annotation.Resource;

import org.junit.Test;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.AbstractJUnit4SpringContextTests;

import com.spring.service.UserService;

@ContextConfiguration(locations
="classpath:applicationContext.xml")
public class SpringTest extends AbstractJUnit4SpringContextTests {

    @Resource(name
="userService")
    
private UserService userService;
    
    @Test
    
public void test1(){
        userService.say();
        System.out.println();
        userService.smile();
        System.out.println();
        userService.cry();
    }
    
}
此單元測試基于spring的AbstractJUnit4SpringContextTests,你需要添加spring的關于單元測試的支持
在類上標注@ContextConfiguration(locations="classpath:applicationContext.xml")意思是去classpath路徑下加載applicationContext.xml
@Resource(name="userService")意思是把userService注入進來

最終輸出結果為:

----------before-------------
say method is called
----------after-------------

----------before-------------
smile method is called
----------after-------------

----------before-------------
cry method is called
----------after-------------




點我下載工程代碼

雪山飛鵠 2010-10-29 10:36 發表評論
]]>
Spring3.0.3使用之異常解決http://www.tkk7.com/sxyx2008/archive/2010/10/29/336441.html雪山飛鵠雪山飛鵠Fri, 29 Oct 2010 01:46:00 GMThttp://www.tkk7.com/sxyx2008/archive/2010/10/29/336441.htmlhttp://www.tkk7.com/sxyx2008/comments/336441.htmlhttp://www.tkk7.com/sxyx2008/archive/2010/10/29/336441.html#Feedback3http://www.tkk7.com/sxyx2008/comments/commentRss/336441.htmlhttp://www.tkk7.com/sxyx2008/services/trackbacks/336441.html溫馨提示:
        以下異常僅在Spring3.0.3版本中遇到,其他版本可能也會遇到,讀者可作參考。不保證會順利通過。
        近期在學習Spring3的一些新特性,一般在項目開發中為了方便期間,都是借助myeclipse工具來添加ssh支持,很少手動添jar包。這里想自虐一下,體驗一下jar包沖突或找不到類的那種感覺,在此也將在Spring3.0中AOP開發過程中遇到的異常什么的記錄出來,可以方便更多人,快速定位錯誤。

第一個異常
java.lang.NoClassDefFoundError: org/apache/commons/logging/LogFactory
有過開發經驗的一眼就可以看出,這是缺少commons-logging.jar包,因為spring中使用它來記錄日志,而spring3.0.3這個版本中并沒有該jar,自行到apache網站下載添加該jar即可

第二個異常
在使用AOP的注解時需要用到aopalliance.jar 、aspectjrt.jar 、aspectjweaver.jar,而此三個jar包并未在spring3.0.3的發布中提供需要開發者自行添加

第三個異常
org.springframework.aop.framework.AopConfigException: Cannot proxy target class because CGLIB2 is not available. Add CGLIB to the class path or specify proxy interfaces
從異常信息可以看出是cglib的問題,而我們去檢查項目,卻發現項目中并未cglib的jar,那么你可能想到的是缺少cglib這個jar包,沒錯,你的思路是正確的,你具有做javaee開發的思維,添加cglib-2.2.jar即可
第四個異常,這也是開發中每個人都會遇到的一個異常,堪稱ssh開發中的經典,如果你是一位技術主管,那么你可以同過此異常去考查一個新人,一看便知,他有沒有javaee開發經驗。呵呵,廢話這么多了,不知道你有沒有猜到是什么了。還是我來告訴你吧,那就是經典的asm.jar包沖突,你的答案正確嗎?不正確,沒關系,你只要記下如何解決就可以了,這個異常保證你在工作中遇到或在面試中問到,那么它的重要性可想而知了。

下面分環境來介紹該jar包沖突的解決方案。

在spring3.0以下的環境中(適應于ssh),若出現該jar包沖突,你需要刪除帶版本號的那個asm.jar,而保留不帶版本號的那個asm.jar即可

在spring3.0的環境中,大家仔細檢查的話發現spring也帶了一個名為org.springframework.asm-3.0.3.RELEASE.jar的jar包,而在開發中僅僅使用這個jar包還是不夠的,你還需要額外的去添加asm.jar,那么這個asm.jar到底是那個版本了?用大腿想想?記得胡叔叔上臺的時候提過與時俱進這個詞,呵呵,人家是說政治的,我這是說開發的,既然spring是3.0的版本,那么asm.jar這個jar包版本肯定也是3.0以上版本啦,要與時俱進嘛。下載地址http://forge.ow2.org/projects/asm/ 我們會看到一個3.3的版本。
可能見到的異常信息
 java.lang.NoClassDefFoundError: org/objectweb/asm/Type
org.objectweb.asm.ClassVisitor.visit
asm3.3.jar,你值得擁有!



雪山飛鵠 2010-10-29 09:46 發表評論
]]>
Exception in thread "main" java.lang.IllegalStateException: BeanFactory not initialized or already closed - call 'refresh' before accessing beans via the ApplicationContexthttp://www.tkk7.com/sxyx2008/archive/2010/10/14/335118.html雪山飛鵠雪山飛鵠Thu, 14 Oct 2010 05:28:00 GMThttp://www.tkk7.com/sxyx2008/archive/2010/10/14/335118.htmlhttp://www.tkk7.com/sxyx2008/comments/335118.htmlhttp://www.tkk7.com/sxyx2008/archive/2010/10/14/335118.html#Feedback0http://www.tkk7.com/sxyx2008/comments/commentRss/335118.htmlhttp://www.tkk7.com/sxyx2008/services/trackbacks/335118.html

不合法的狀態,beanFactory沒有初始化或者關閉,在上下文中刷新。

解決方法:ApplicationContext context = new ClassPathXmlAppliction("這里的參數沒有寫");




雪山飛鵠 2010-10-14 13:28 發表評論
]]>
Spring中@Autowired注解、@Resource注解的區別http://www.tkk7.com/sxyx2008/archive/2010/10/11/334451.html雪山飛鵠雪山飛鵠Mon, 11 Oct 2010 08:52:00 GMThttp://www.tkk7.com/sxyx2008/archive/2010/10/11/334451.htmlhttp://www.tkk7.com/sxyx2008/comments/334451.htmlhttp://www.tkk7.com/sxyx2008/archive/2010/10/11/334451.html#Feedback1http://www.tkk7.com/sxyx2008/comments/commentRss/334451.htmlhttp://www.tkk7.com/sxyx2008/services/trackbacks/334451.html   @Resource的作用相當于@Autowired,只不過@Autowired按byType自動注入,而@Resource默認按 byName自動注入罷了。@Resource有兩個屬性是比較重要的,分是name和type,Spring將@Resource注解的name屬性解析為bean的名字,而type屬性則解析為bean的類型。所以如果使用name屬性,則使用byName的自動注入策略,而使用type屬性時則使用byType自動注入策略。如果既不指定name也不指定type屬性,這時將通過反射機制使用byName自動注入策略。
  @Resource裝配順序
  1. 如果同時指定了name和type,則從Spring上下文中找到唯一匹配的bean進行裝配,找不到則拋出異常
  2. 如果指定了name,則從上下文中查找名稱(id)匹配的bean進行裝配,找不到則拋出異常
  3. 如果指定了type,則從上下文中找到類型匹配的唯一bean進行裝配,找不到或者找到多個,都會拋出異常
  4. 如果既沒有指定name,又沒有指定type,則自動按照byName方式進行裝配;如果沒有匹配,則回退為一個原始類型進行匹配,如果匹配則自動裝配;

雪山飛鵠 2010-10-11 16:52 發表評論
]]>
jboss上部署struts2+spring+hibernate異常處理http://www.tkk7.com/sxyx2008/archive/2010/08/23/329657.html雪山飛鵠雪山飛鵠Mon, 23 Aug 2010 06:30:00 GMThttp://www.tkk7.com/sxyx2008/archive/2010/08/23/329657.htmlhttp://www.tkk7.com/sxyx2008/comments/329657.htmlhttp://www.tkk7.com/sxyx2008/archive/2010/08/23/329657.html#Feedback1http://www.tkk7.com/sxyx2008/comments/commentRss/329657.htmlhttp://www.tkk7.com/sxyx2008/services/trackbacks/329657.html      jboss4.2.3
異常摘要:
java.lang.ClassCastException: com.sun.faces.config.WebConfiguration cannot be cast to com.sun.faces.config.WebConfiguration
java.lang.ClassCastException: com.sun.faces.config.WebConfiguration cannot be cast to com.sun.faces.config.WebConfiguration
    at com.sun.faces.config.WebConfiguration.getInstance(WebConfiguration.java:
154)
    at com.sun.faces.config.ConfigureListener.contextInitialized(ConfigureListener.java:
144)
    at org.jboss.web.jsf.integration.config.JBossJSFConfigureListener.contextInitialized(JBossJSFConfigureListener.java:
71)
    at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:
3856)
    at org.apache.catalina.core.StandardContext.start(StandardContext.java:
4361)
    at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:
790)
    at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:
770)
    at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:
553)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:
39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:
25)
    at java.lang.reflect.Method.invoke(Method.java:
597)
    at org.apache.tomcat.util.modeler.BaseModelMBean.invoke(BaseModelMBean.java:
296)
    at org.jboss.mx.server.RawDynamicInvoker.invoke(RawDynamicInvoker.java:
164)
    at org.jboss.mx.server.MBeanServerImpl.invoke(MBeanServerImpl.java:
659)
    at org.apache.catalina.core.StandardContext.init(StandardContext.java:
5312)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:
39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:
25)
    at java.lang.reflect.Method.invoke(Method.java:
597)
    at org.apache.tomcat.util.modeler.BaseModelMBean.invoke(BaseModelMBean.java:
296)
    at org.jboss.mx.server.RawDynamicInvoker.invoke(RawDynamicInvoker.java:
164)
    at org.jboss.mx.server.MBeanServerImpl.invoke(MBeanServerImpl.java:
659)
    at org.jboss.web.tomcat.service.TomcatDeployer.performDeployInternal(TomcatDeployer.java:
301)
    at org.jboss.web.tomcat.service.TomcatDeployer.performDeploy(TomcatDeployer.java:
104)
    at org.jboss.web.AbstractWebDeployer.start(AbstractWebDeployer.java:
375)
    at org.jboss.web.WebModule.startModule(WebModule.java:
83)
    at org.jboss.web.WebModule.startService(WebModule.java:
61)
    at org.jboss.system.ServiceMBeanSupport.jbossInternalStart(ServiceMBeanSupport.java:
289)
    at org.jboss.system.ServiceMBeanSupport.jbossInternalLifecycle(ServiceMBeanSupport.java:
245)
    at sun.reflect.GeneratedMethodAccessor3.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:
25)
    at java.lang.reflect.Method.invoke(Method.java:
597)
    at org.jboss.mx.interceptor.ReflectedDispatcher.invoke(ReflectedDispatcher.java:
155)
    at org.jboss.mx.server.Invocation.dispatch(Invocation.java:
94)
    at org.jboss.mx.server.Invocation.invoke(Invocation.java:
86)
    at org.jboss.mx.server.AbstractMBeanInvoker.invoke(AbstractMBeanInvoker.java:
264)
    at org.jboss.mx.server.MBeanServerImpl.invoke(MBeanServerImpl.java:
659)
    at org.jboss.system.ServiceController$ServiceProxy.invoke(ServiceController.java:
978)
    at $Proxy0.start(Unknown Source)
    at org.jboss.system.ServiceController.start(ServiceController.java:
417)
    at sun.reflect.GeneratedMethodAccessor9.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:
25)
    at java.lang.reflect.Method.invoke(Method.java:
597)
    at org.jboss.mx.interceptor.ReflectedDispatcher.invoke(ReflectedDispatcher.java:
155)
    at org.jboss.mx.server.Invocation.dispatch(Invocation.java:
94)
    at org.jboss.mx.server.Invocation.invoke(Invocation.java:
86)
    at org.jboss.mx.server.AbstractMBeanInvoker.invoke(AbstractMBeanInvoker.java:
264)
    at org.jboss.mx.server.MBeanServerImpl.invoke(MBeanServerImpl.java:
659)
    at org.jboss.mx.util.MBeanProxyExt.invoke(MBeanProxyExt.java:
210)
    at $Proxy44.start(Unknown Source)
    at org.jboss.web.AbstractWebContainer.start(AbstractWebContainer.java:
466)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:
39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:
25)
    at java.lang.reflect.Method.invoke(Method.java:
597)
    at org.jboss.mx.interceptor.ReflectedDispatcher.invoke(ReflectedDispatcher.java:
155)
    at org.jboss.mx.server.Invocation.dispatch(Invocation.java:
94)
    at org.jboss.mx.interceptor.AbstractInterceptor.invoke(AbstractInterceptor.java:
133)
    at org.jboss.mx.server.Invocation.invoke(Invocation.java:
88)
    at org.jboss.mx.interceptor.ModelMBeanOperationInterceptor.invoke(ModelMBeanOperationInterceptor.java:
142)
    at org.jboss.mx.interceptor.DynamicInterceptor.invoke(DynamicInterceptor.java:
97)
    at org.jboss.system.InterceptorServiceMBeanSupport.invokeNext(InterceptorServiceMBeanSupport.java:
238)
    at org.jboss.wsf.container.jboss42.DeployerInterceptor.start(DeployerInterceptor.java:
87)
    at org.jboss.deployment.SubDeployerInterceptorSupport$XMBeanInterceptor.start(SubDeployerInterceptorSupport.java:
188)
    at org.jboss.deployment.SubDeployerInterceptor.invoke(SubDeployerInterceptor.java:
95)
    at org.jboss.mx.server.Invocation.invoke(Invocation.java:
88)
    at org.jboss.mx.server.AbstractMBeanInvoker.invoke(AbstractMBeanInvoker.java:
264)
    at org.jboss.mx.server.MBeanServerImpl.invoke(MBeanServerImpl.java:
659)
    at org.jboss.mx.util.MBeanProxyExt.invoke(MBeanProxyExt.java:
210)
    at $Proxy45.start(Unknown Source)
    at org.jboss.deployment.MainDeployer.start(MainDeployer.java:
1025)
    at org.jboss.deployment.MainDeployer.deploy(MainDeployer.java:
819)
    at org.jboss.deployment.MainDeployer.deploy(MainDeployer.java:
782)
    at sun.reflect.GeneratedMethodAccessor21.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:
25)
    at java.lang.reflect.Method.invoke(Method.java:
597)
    at org.jboss.mx.interceptor.ReflectedDispatcher.invoke(ReflectedDispatcher.java:
155)
    at org.jboss.mx.server.Invocation.dispatch(Invocation.java:
94)
    at org.jboss.mx.interceptor.AbstractInterceptor.invoke(AbstractInterceptor.java:
133)
    at org.jboss.mx.server.Invocation.invoke(Invocation.java:
88)
    at org.jboss.mx.interceptor.ModelMBeanOperationInterceptor.invoke(ModelMBeanOperationInterceptor.java:
142)
    at org.jboss.mx.server.Invocation.invoke(Invocation.java:
88)
    at org.jboss.mx.server.AbstractMBeanInvoker.invoke(AbstractMBeanInvoker.java:
264)
    at org.jboss.mx.server.MBeanServerImpl.invoke(MBeanServerImpl.java:
659)
    at org.jboss.mx.util.MBeanProxyExt.invoke(MBeanProxyExt.java:
210)
    at $Proxy9.deploy(Unknown Source)
    at org.jboss.deployment.scanner.URLDeploymentScanner.deploy(URLDeploymentScanner.java:
421)
    at org.jboss.deployment.scanner.URLDeploymentScanner.scan(URLDeploymentScanner.java:
634)
    at org.jboss.deployment.scanner.AbstractDeploymentScanner$ScannerThread.doScan(AbstractDeploymentScanner.java:
263)
    at org.jboss.deployment.scanner.AbstractDeploymentScanner.startService(AbstractDeploymentScanner.java:
336)
    at org.jboss.system.ServiceMBeanSupport.jbossInternalStart(ServiceMBeanSupport.java:
289)
    at org.jboss.system.ServiceMBeanSupport.jbossInternalLifecycle(ServiceMBeanSupport.java:
245)
    at sun.reflect.GeneratedMethodAccessor3.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:
25)
    at java.lang.reflect.Method.invoke(Method.java:
597)
    at org.jboss.mx.interceptor.ReflectedDispatcher.invoke(ReflectedDispatcher.java:
155)
    at org.jboss.mx.server.Invocation.dispatch(Invocation.java:
94)
    at org.jboss.mx.server.Invocation.invoke(Invocation.java:
86)
    at org.jboss.mx.server.AbstractMBeanInvoker.invoke(AbstractMBeanInvoker.java:
264)
    at org.jboss.mx.server.MBeanServerImpl.invoke(MBeanServerImpl.java:
659)
    at org.jboss.system.ServiceController$ServiceProxy.invoke(ServiceController.java:
978)
    at $Proxy0.start(Unknown Source)
    at org.jboss.system.ServiceController.start(ServiceController.java:
417)
    at sun.reflect.GeneratedMethodAccessor9.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:
25)
    at java.lang.reflect.Method.invoke(Method.java:
597)
    at org.jboss.mx.interceptor.ReflectedDispatcher.invoke(ReflectedDispatcher.java:
155)
    at org.jboss.mx.server.Invocation.dispatch(Invocation.java:
94)
    at org.jboss.mx.server.Invocation.invoke(Invocation.java:
86)
    at org.jboss.mx.server.AbstractMBeanInvoker.invoke(AbstractMBeanInvoker.java:
264)
    at org.jboss.mx.server.MBeanServerImpl.invoke(MBeanServerImpl.java:
659)
    at org.jboss.mx.util.MBeanProxyExt.invoke(MBeanProxyExt.java:
210)
    at $Proxy4.start(Unknown Source)
    at org.jboss.deployment.SARDeployer.start(SARDeployer.java:
304)
    at org.jboss.deployment.MainDeployer.start(MainDeployer.java:
1025)
    at org.jboss.deployment.MainDeployer.deploy(MainDeployer.java:
819)
    at org.jboss.deployment.MainDeployer.deploy(MainDeployer.java:
782)
    at org.jboss.deployment.MainDeployer.deploy(MainDeployer.java:
766)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:
39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:
25)
    at java.lang.reflect.Method.invoke(Method.java:
597)
    at org.jboss.mx.interceptor.ReflectedDispatcher.invoke(ReflectedDispatcher.java:
155)
    at org.jboss.mx.server.Invocation.dispatch(Invocation.java:
94)
    at org.jboss.mx.interceptor.AbstractInterceptor.invoke(AbstractInterceptor.java:
133)
    at org.jboss.mx.server.Invocation.invoke(Invocation.java:
88)
    at org.jboss.mx.interceptor.ModelMBeanOperationInterceptor.invoke(ModelMBeanOperationInterceptor.java:
142)
    at org.jboss.mx.server.Invocation.invoke(Invocation.java:
88)
    at org.jboss.mx.server.AbstractMBeanInvoker.invoke(AbstractMBeanInvoker.java:
264)
    at org.jboss.mx.server.MBeanServerImpl.invoke(MBeanServerImpl.java:
659)
    at org.jboss.mx.util.MBeanProxyExt.invoke(MBeanProxyExt.java:
210)
    at $Proxy5.deploy(Unknown Source)
    at org.jboss.system.server.ServerImpl.doStart(ServerImpl.java:
482)
    at org.jboss.system.server.ServerImpl.start(ServerImpl.java:
362)
    at org.jboss.Main.boot(Main.java:
200)
    at org.jboss.Main$
1.run(Main.java:508)
    at java.lang.Thread.run(Thread.java:
619)
從異常信息可以看出是jboss服務器在解析jsf時出現了問題,但項目中沒用到jsf啊,仔細檢查,在工程目錄下發現了jsf-api.jar和jsf-impl.jar,移除jsf-api.jar和jsf-impl.jar兩個jar文件。問題解決。


雪山飛鵠 2010-08-23 14:30 發表評論
]]>
輕松配置log4j實現錯誤日志email通知http://www.tkk7.com/sxyx2008/archive/2010/07/14/326028.html雪山飛鵠雪山飛鵠Tue, 13 Jul 2010 17:44:00 GMThttp://www.tkk7.com/sxyx2008/archive/2010/07/14/326028.htmlhttp://www.tkk7.com/sxyx2008/comments/326028.htmlhttp://www.tkk7.com/sxyx2008/archive/2010/07/14/326028.html#Feedback2http://www.tkk7.com/sxyx2008/comments/commentRss/326028.htmlhttp://www.tkk7.com/sxyx2008/services/trackbacks/326028.html        需求描述:任何程序都會存在bug,雖然項目經過反復測試,已經上線運行了,但難免會遇到各種錯誤,在這里輕松配置log4j實現錯誤消息的email通知.
        兩個文件:web.xml log4j.properties
        web.xml
        在web.xml中添加如下代碼

<!-- 設置上下文參數 -->
    
<context-param>
        
<!-- log4j配置文件位置 -->
        
<param-name>log4jConfigLocation</param-name>
        
<param-value>/WEB-INF/classes/log4j.properties</param-value>
    
</context-param>
    
<context-param>
        
<param-name>log4jRefreshInterval</param-name>
        
<param-value>6000</param-value>
    
</context-param>
    
<!-- log4j監聽器 -->
    
<listener>
        
<listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
    
</listener>
        log4j.properties
## ROOT
log4j.rootLogger=INFO,CONSOLE,MAIL

## CONSOLE
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.Threshold=INFO
log4j.appender.CONSOLE.Target=System.out
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
#log4j.appender.CONSOLE.layout.ConversionPattern=[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n
log4j.appender.CONSOLE.layout.ConversionPattern=[\u8C03\u8BD5\u4FE1\u606F]%-5p %c %x - %m%n

## File
log4j.appender.A_default=org.apache.log4j.RollingFileAppender
log4j.appender.A_default.Threshold=INFO
log4j.appender.A_default.File=e\:/logs/log4j.log
log4j.appender.A_default.MaxFileSize=4000KB
log4j.appender.A_default.MaxBackupIndex=10
log4j.appender.A_default.layout=org.apache.log4j.PatternLayout
log4j.appender.A_default.layout.ConversionPattern=[\u8C03\u8BD5\u4FE1\u606F]%-5p %c %x - %m%n

## MAIL
log4j.appender.MAIL=org.apache.log4j.net.SMTPAppender
# 日志的錯誤級別
log4j.appender.MAIL.Threshold=ERROR
# 緩存文件大小,日志達到512K時發送Email
log4j.appender.MAIL.BufferSize=10
# 發送郵件的服務器
log4j.appender.MAIL.SMTPHost=smtp.163.com
# 郵件的標題
log4j.appender.MAIL.Subject=\u6D4B\u8BD5log4j\u8F93\u51FA\u9519\u8BEF\u4FE1\u606F\u5230\u65E5\u5FD7
# 用戶名
log4j.appender.MAIL.SMTPUsername=你的用戶名
# 密碼
log4j.appender.MAIL.SMTPPassword=你的密碼
# 發件人地址
log4j.appender.MAIL.From=xxxxx@163.com
# 日志郵件的接收者
log4j.appender.MAIL.To=xxx@qq.com
# 日志PatternLayout
log4j.appender.MAIL.layout=com.quartz.demo.Loger4JHTMLLayOut
# 日志的格式
log4j.appender.MAIL.layout.ConversionPattern=[ErrorMessage] %d - %c -%-4r [%t] %-5p %c %x - %m%n

        注:在以上log4j.properties文件中配置了自己的自定義layout,由于log4j默認采用的純文本方式.這樣不便于我們在郵件中查看,因此覆蓋它的layout,自定義屬于我們自己的layout
        自定義類com.quartz.demo.Loger4JHTMLLayOut完成了該功能
package com.quartz.demo;

import org.apache.log4j.HTMLLayout;

public class Loger4JHTMLLayOut extends HTMLLayout{
    
    @Override
    
public String getContentType() {
        
return "text/html;charset=utf-8"
    }

}

        即:只需設置contentType為text/html即可
        效果圖:

            log4j.properties

雪山飛鵠 2010-07-14 01:44 發表評論
]]>
Spring整合Quartz定時發送郵件http://www.tkk7.com/sxyx2008/archive/2010/07/13/325985.html雪山飛鵠雪山飛鵠Tue, 13 Jul 2010 10:03:00 GMThttp://www.tkk7.com/sxyx2008/archive/2010/07/13/325985.htmlhttp://www.tkk7.com/sxyx2008/comments/325985.htmlhttp://www.tkk7.com/sxyx2008/archive/2010/07/13/325985.html#Feedback2http://www.tkk7.com/sxyx2008/comments/commentRss/325985.htmlhttp://www.tkk7.com/sxyx2008/services/trackbacks/325985.html         核心jar:
                    郵件發送:commons-email-1.2.jar mail.jar(必須的)
                    quartz:quartz-all-1.8.3.jar quartz-all-1.8.3/lib/下所有jar
                    spring:spring-context-support.ajr(必須的)
        只貼出核心代碼:
        Email發送:使用apache commons-email跟mail
package com.ssh.commonsemail;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.mail.internet.InternetAddress;

import org.apache.commons.mail.SimpleEmail;

/**
 * 功能描述:此代碼主要實現郵件發送功能
 * 
@author coder
 *
 
*/

public class SendSimplEmail {
    
    
    
public static void sendMail()throws Exception{
        List
<InternetAddress> list=new ArrayList<InternetAddress>();
        list.add(
new InternetAddress("313698683@qq.com"));
        list.add(
new InternetAddress("184675420@qq.com"));
        SimpleEmail email
=new SimpleEmail();
        email.setFrom(
"184675420@163.com");
        email.setCharset(
"utf-8");
        email.setSentDate(
new Date());
        email.setSubject(
"測試Quartz");
        email.setHostName(
"smtp.163.com");
        email.setAuthentication(
"xxxx""xxxx");
        email.setTo(list);
        email.setContent(
"<h1>Hello,把鳳姐許配給你,你看咋樣?</h1>""text/html;charset=utf-8");
        email.send();
    }

    
    
}

        定義調度工作任務:繼承自org.springframework.scheduling.quartz.QuartzJobBean次類在spring-context-support.jar中
package com.ssh.quantz;

import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.scheduling.quartz.QuartzJobBean;

import com.ssh.commonsemail.SendSimplEmail;

/**
 * 發送email任務
 * 
@author coder
 *
 
*/

public class SendEmailJob extends QuartzJobBean{
    
    @Override
    
protected void executeInternal(JobExecutionContext context)
            
throws JobExecutionException {
        
try {
            
//調用郵件發送代碼
            SendSimplEmail.sendMail();
        }
 catch (Exception e) {
            e.printStackTrace();
        }

    }


    

}

        spring核心配置文件
<!-- 定義調度工作任務 -->
    
<bean id="quantzjobBean" class="org.springframework.scheduling.quartz.JobDetailBean">
        
<property name="jobClass">
            
<!-- 實現了org.springframework.scheduling.quartz.QuartzJobBean的JobBean -->
            
<value>com.ssh.quantz.SendEmailJob</value>
        
</property>
        
<!-- 調用業務邏輯 -->
        
<!--  
        <property name="jobDataAsMap">
            <map>
                <entry key="biz">
                    <ref bean="users"/>
                </entry>
            </map>
        </property>
        
-->
    
</bean>

    
<!-- 觸發任務條件 -->
    
<bean id="simpletriggerbean" class="org.springframework.scheduling.quartz.SimpleTriggerBean">
        
<property name="jobDetail" ref="quantzjobBean"></property>
        
<!-- 延遲一分鐘啟動 -->
        
<property name="startDelay">
            
<value>60000</value>
        
</property>
        
<!-- 每隔2分鐘調用一次 -->
        
<property name="repeatInterval">
            
<value>60000</value>
        
</property>
        
<!-- 執行10次 -->
        
<property name="repeatCount">
            
<value>10</value>
        
</property>
        
    
</bean>
    
    
<!-- 啟動調度 -->
    
<bean id="startQuartz" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
        
<property name="triggers">
            
<list>
                
<ref bean="simpletriggerbean"/>
            
</list>
        
</property>
    
</bean>


                        

雪山飛鵠 2010-07-13 18:03 發表評論
]]>
Spring 結合Hibernate 配置 C3P0 連接池http://www.tkk7.com/sxyx2008/archive/2009/11/16/302557.html雪山飛鵠雪山飛鵠Mon, 16 Nov 2009 07:08:00 GMThttp://www.tkk7.com/sxyx2008/archive/2009/11/16/302557.htmlhttp://www.tkk7.com/sxyx2008/comments/302557.htmlhttp://www.tkk7.com/sxyx2008/archive/2009/11/16/302557.html#Feedback2http://www.tkk7.com/sxyx2008/comments/commentRss/302557.htmlhttp://www.tkk7.com/sxyx2008/services/trackbacks/302557.html閱讀全文

雪山飛鵠 2009-11-16 15:08 發表評論
]]>
主站蜘蛛池模板: 亚洲色欲久久久久综合网| 亚洲一区二区三区四区在线观看| 成年私人影院免费视频网站| 亚洲GV天堂无码男同在线观看| 亚洲一区二区三区四区视频| 久久乐国产精品亚洲综合| 亚洲精品视频在线看| 女人张腿给男人桶视频免费版 | 久久精品国产精品亚洲| 亚洲欧洲中文日韩av乱码| 亚洲欧洲精品成人久久奇米网| 亚洲精品偷拍视频免费观看| 亚洲综合精品网站在线观看| 亚洲夜夜欢A∨一区二区三区| 成人黄18免费视频| 日韩免费福利视频| 国产免费久久精品99re丫y| 国产精品免费大片| 四虎国产精品永免费| 国产视频精品免费视频| 美女视频免费看一区二区| 免费一级毛片在线播放放视频| 亚洲熟女综合一区二区三区| 亚洲黄色免费电影| 亚洲人成伊人成综合网久久久 | 日韩精品亚洲专区在线观看| 亚洲女人被黑人巨大进入| 亚洲av中文无码乱人伦在线播放| 久久精品亚洲中文字幕无码麻豆| 亚洲卡一卡2卡三卡4麻豆| 久久丫精品国产亚洲av不卡| 亚洲a级在线观看| 国产天堂亚洲国产碰碰| 成人A毛片免费观看网站| 免费A级毛片无码视频| 最近2019中文字幕免费看最新| 免费一级一片一毛片| 热久久精品免费视频| 久久久久一级精品亚洲国产成人综合AV区 | 精品久久久久久亚洲综合网| 亚洲第一成年网站视频|