《Spring in Action》第七章筆記,涵蓋 JNDI 資源查找、JavaMail 郵件發送(含 SMTP 認證)、JDK Timer/Quartz 定時任務、JMS 訊息發送等企業級服務整合實戰配置與避坑指南。
JndiObjectFactoryBean 在應用伺服器內自動使用預設 JNDI 環境;獨立運行(單元測試、Main 程式)需顯式設定 jndiEnvironment:
<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="jdbc/MyDS"/>
<property name="jndiEnvironment">
<props>
<prop key="java.naming.factory.initial">org.apache.naming.java.javaURLContextFactory</prop>
<prop key="java.naming.factory.url.pkgs">org.apache.naming</prop>
</props>
</property>
</bean>
Tomcat 需 catalina.jar、tomcat-juli.jar 在 classpath;其他容器請參考對應文檔。
書中遺漏 SMTP 認證配置,實際生產必須加上 mail.smtp.auth=true 及帳密:
<bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
<property name="host" value="mail.example.com"/>
<property name="username" value="noreply@example.com"/>
<property name="password" value="secret"/>
<property name="javaMailProperties">
<props>
<prop key="mail.smtp.auth">true</prop>
<prop key="mail.smtp.starttls.enable">true</prop> <!-- TLS 加密 -->
<prop key="mail.smtp.timeout">5000</prop>
</props>
</property>
</bean>
使用:
SimpleMailMessage msg = new SimpleMailMessage();
msg.setTo("user@example.com"); msg.setSubject("歡迎"); msg.setText("內容...");
mailSender.send(msg);
進階:搭配 Velocity/FreeMarker 模板生成 HTML 郵件,使用 MimeMessagePreparator 或 MimeMessageHelper。
<bean id="timerTask" class="org.springframework.scheduling.timer.ScheduledTimerTask">
<property name="timerTask">
<bean class="com.example.MyTimerTask" /> <!-- 實作 TimerTask -->
</property>
<property name="delay" value="10000"/> <!-- 10秒後首次執行 -->
<property name="period" value="60000"/> <!-- 之後每60秒 -->
</bean>
<bean class="org.springframework.scheduling.timer.TimerFactoryBean">
<property name="scheduledTimerTasks"><ref bean="timerTask"/></property>
</bean>
缺點:僅支援固定延遲/週期,無法表達「每天凌晨 2 點」、「每月最後一天」等複雜排程。
<!-- 1. JobDetail 定義任務 -->
<bean id="jobDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
<property name="targetObject" ref="myService"/> <!-- Spring Bean -->
<property name="targetMethod" value="execute"/> <!-- 無參方法 -->
</bean>
<!-- 2. CronTrigger 定義排程 -->
<bean id="cronTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">
<property name="jobDetail" ref="jobDetail"/>
<property name="cronExpression" value="0 0 2 * * ?"/> <!-- 每天 02:00 -->
</bean>
<!-- 3. SchedulerFactoryBean 啟動調度器 -->
<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="triggers"><list><ref bean="cronTrigger"/></list></property>
</bean>
秒 分 時 日 月 周 [年]
0 0 2 * * ? 每天 02:00
0 0/10 * * * ? 每 10 分鐘
0 0 12 ? * MON-FRI 工作日中午 12:00
0 0 0 1 * ? 每月 1 號 00:00
0 0 0 L * ? 每月最後一天 00:00
注意:Spring 1.2.x 配置文件中 <value ref="..."/> 應改為 <ref bean="..."/>;書中 P94,96,97,104 有誤。
Spring 提供 JmsTemplate 簡化 JMS 發送/接收,支援 ActiveMQ、IBM MQ、WebLogic JMS 等。配置 ConnectionFactory、Destination、JmsTemplate 即可。因篇幅限制此處略過,實際專案中 SOA/微服務架構下極常用,建議深入學習。
jndiEnvironment。mail.smtp.auth=true + 帳密。CronTriggerBean 才是彈性調度核心,SimpleTriggerBean 僅等同 JDK Timer。<value ref="..."/> → <ref bean="..."/>。MethodInvokingJobDetailFactoryBean 靜態方法或使用 JobDetailFactoryBean 實作 Job 介面。