Spring in Action 學習筆記—第七章訪問企業服務

來源:互聯網
上載者:User
Spring in Action 學習筆記 第七章 訪問企業服務   本章向讀者展示了在Spring中如何整合其他企業服務,讀者將瞭解到使用Spring整合郵件服務、JMS甚至EJB都是那麼的容易。 Spring並沒有對一些企業服務提供直接的支援。它依賴其他API來提供有關服務,但對這些服務通過相應的抽象層進行了封裝,因此使用起來更為方便。 一、從 JNDI 中擷取對象 JNDI為Java應用程式提供了一個用於儲存應用對象的中心倉庫。 Spring的JNDI抽象使你可以在應用的設定檔中聲明JNDI對象。然後你就可以將這些對象裝配到其他Bean的屬性中,就如同JNDI對象與其他的POJO一樣。 1 .使用傳統的 JNDI 使用傳統的JNDI API,你編寫的代碼也許和下面的看上去差不多: InitialContext ctx = null;                 try {            ctx = new InitialContext();            DataSource ds = (DataSource) ctx.lookup("java:comp/env/jdbc/myDatasource");         } catch (NamingException ne) {                //exception         } finally {            if (ctx != null) {              try {                 ctx.close();              } catch (NamingException ne) {}            }         } 這段代碼有點笨拙,總的說來,這種從JNDI中擷取對象的傳統方式的問題都來源於違背了依賴注入的原則。不是賦給你的代碼一個對象,而是你的代碼必須親自去擷取這個對象。這意味著你的代碼所做的不是真正的工作。這也意味著你的代碼不必要地與JNDI耦合了。 2 .代理 JNDI 對象 Spring的JndiObjectFactoryBean允許你同時得到這兩個不同領域中的好處。它是一個工廠Bean,這意味著當把它裝配到一個屬性上時,實際上它會建立一個其他類型的對象供裝配時使用。對於JndiObjectFactoryBean,它實際裝配的是一個從JNDI擷取的對象。 當Spring裝配sessionFactory Bean時,它會把從JNDI中擷取的DataSource對象注入到會話工廠Bean的dataSource屬性中。使用JndiObjectFactoryBean從JNDI中尋找對象的最大優勢在於惟一知道DataSource是從JNDI中擷取的代碼就是那段dataSource Bean的XML聲明。sessionFactory Bean不知道(也不關心)DataSource來自哪裡。這意味著如果以後你決定改從一個JDBC驅動管理器擷取DataSource,只需要重新定義dataSource Bean為一個DriverManagerDataSource即可。   二、寄送電子郵件 Spring中的郵件發送器由Spring的MailSender介面定義。郵件發送器抽象了某個特定的郵件實現。這樣就使應用代碼和實際使用的郵件實現之間沒有耦合。Spring提供了這個介面的兩個實現:    CosMailSenderImpl——以Jason Hunter的Java Servlet Programming一書(O’Reilly,1998)中的COS(com.oreilly.servlet)實現為基礎的SMTP郵件發送器的簡單實現。    JavaMailSenderImpl——一個基於JavaMail API的郵件發送器實現。允許發送MIME郵件以及非SMTP郵件(比如Lotus Notes)。 採用哪個都將完成發送的工作,但是我們將選擇JavaMailSenderImpl,因為在兩者間它的功能更全面。你可以在Spring設定檔中按以下方式聲明它: <bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">     <property name="host">       <value>mail.springtraining.com</value>     </property> </bean> 屬性host指定了郵件伺服器的主機名稱,在這裡是Spring培訓應用的SMTP伺服器。在預設情況下,郵件發送器假設SMTP伺服器監聽25連接埠(標準的SMTP連接埠),但如果你的SMTP伺服器監聽在不同的連接埠上,可以使用JavaMailSenderImpl的port屬性來指定連接埠。 上面的mailSender聲明中顯式地命名了用於發送郵件的郵件伺服器。然而,如果你有一個位於JNDI中的javax.mail.MailSession對象(可能位於你的應用伺服器中),則也可以選擇從JNDI中擷取它。只需簡單地使用JndiObjectFactoryBean(如第7.1節中描述的)來擷取郵件會話對象,並按照下面的方式將它裝配到mailSender的mailSession屬性中即可: <bean id="mailSession" class="org.springframework.jndi.JndiObjectFactoryBean">     <property name="jndiName">       <value>java:comp/env/mail/Session</value>     </property>  </bean>  <bean id="mailSender" class="org.springrframework.mail.javamail.JavaMailSenderImpl">     <property name="session"><ref bean="mailSession"/></property> </bean>   三、調度任務 Java的Timer類和OpenSymphony的Quartz調度器 [2] 是兩個流行的調度API。Spring為這兩個調度器提供了一個抽象層,使你可以更容易地使用它們。 1 .使用 Java Timer 調度任務 從Java 1.3開始,Java SDK就通過java.util.Timer類提供了基本的調度功能。這個類允許你調度一個任務(通過java.util.TimerTask子類定義)按任意周期運行。 建立一個定時器任務 使用Java Timer來調度發送註冊報表郵件的第一步是從java.util.TimerTask中派生出郵件任務:        public class EmailReportTask extends TimerTask {              public EmailReportTask() {}              public void run() {              courseService.sendCourseEnrollmentReport();            }              private CourseService courseService;              public void setCourseService(CourseService courseService) {                this.courseService = courseService;              }           } run()方法定義了當任務運行時該做什麼。在上面的例子中,它調用CourseService的sendCourseEnrollmentReport()方法來發送註冊報表郵件。CourseService是通過依賴注入方式提供給EmailReportTask的。 按以下方式在Spring設定檔中聲明EmailReportTask: <bean id="reportTimerTask" class="com.springinaction.training.schedule.EmailReportTask">       <property name="courseService">         <ref bean="courseService"/>       </property>    </bean> 這個聲明本身只是將EmailReportTask放到應用上下文中,並在courseService屬性中裝配courseService Bean。在你調度它之前,它不會做任何有用的事。 調度定時器任務 Spring的ScheduledTimerTask定義了一個定時器任務的運行周期。既然課程主任要求每天向她發送註冊報表,你應該以如下方式裝配一個ScheduledTimerTask: <bean id="scheduledReportTask" class="org.springframework.scheduling.timer.ScheduledTimerTask">       <property name="timerTask">         <ref bean="reportTimerTask"/>       </property>       <property name="period">         <value>86400000</value>       </property>    </bean> 屬性timerTask告訴ScheduledTimerTask運行哪個TimerTask。在這裡,該屬性裝配了指向reportTimerTask的一個引用,它就是EmailReportTask。屬性period告訴ScheduledTimerTask以怎樣的頻度調用TimerTask的run()方法。這個屬性以毫秒作為單位,它被設定為86400000,指定這個任務應該每24小時運行一次。 啟動定時器 最後一步是啟動定時器。Spring的TimerFactoryBean負責啟動定時任務。按以下方式在Spring設定檔中聲明它: <bean class="org.springframework.scheduling.timer.TimerFactoryBean">       <property name="scheduledTimerTasks">         <list>           <ref bean="scheduledReportTask"/>         </list>       </property>    </bean> 屬性scheduledTimerTasks要求一個需要啟動的定時器任務的列表。既然你現在只有一個定時器任務,這個列表中只包含一個指向scheduledReportTask Bean的引用。 遺憾的是,即使這個任務已經能夠每隔24小時運行一次了,在這裡你無法指定它應該在一天中的哪個時間點執行。ScheduledTimerTask有一個delay屬性,允許你指定當任務第一次運行之前應該等待多久。例如,要將EmailReportTask的第一次運行延遲1小時,可以按照以下方式進行配置: <bean id="scheduledReportTask" class="org.springframework.scheduling.timer.ScheduledTimerTask">       <property name="timerTask">         <ref bean="reportTimerTask"/>       </property>       <property name="period">         <value>86400000</value>       </property>       <property name="delay">         <value>3600000</value>       </property>   </bean> 2 .使用 Quartz

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.