前幾天看到網友分享的自學心得,其中一句話讓我印象深刻:「光看別人騎自行車很輕易,那麼是不是看了幾百遍別人怎麼騎自行車你也就馬上能騎著走了呢?不摔跤是不可能學會的。」還有就是要經常總結:遇到問題時記錄下來,下次再碰到就不會浪費時間回憶。好記性不如爛筆頭,假如今天不寫,以後只會越來越忙,再也沒時間寫筆記了。If you doesn't have time to do it today, then when do you have time to do it tomorrow?
基於這個心態,今天我們來實作 Spring 的消息(MessageSource)與事件(ApplicationEvent)機制,透過一個完整的範例展示如何實現國際化訊息與自定義事件發布監聽。
簡單的 JavaBean,包含 name 與 age 兩個屬性及其 getter/setter 方法:
package cn.xy.hw;
public class User {
private String name;
private int age;
public int getAge() { return age; }
public void setAge(int age) { this.age = age; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
}
建立兩個 properties 檔案支援中英文切換:
xiyou_en_US.properties
userlogin user {0} login at {1}
xiyou_zh_CN.properties
userlogin 使用者 {0} 於 {1}登入
繼承 ApplicationEvent,建構子中輸出下雨場景描述:
package cn.xy.hw;
import org.springframework.context.ApplicationEvent;
public class RainEvent extends ApplicationEvent {
public RainEvent(Object source) {
super(source);
System.out.println("烏雲密布、閃電、打雷,緊接著,下起了瓢潑大雨。");
}
}
實作 ApplicationListener 介面,攔截 RainEvent 並輸出唐僧喊收衣服的訊息:
package cn.xy.hw;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;
public class RainListener implements ApplicationListener {
@Override
public void onApplicationEvent(ApplicationEvent event) {
if (event instanceof RainEvent) {
System.out.println("唐僧大喊:" + event.getSource() + "趕緊收衣服喽!");
}
}
}
定義 User Bean、MessageSource、RainListener 三個核心組件:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="https://www.springframework.org/schema/beans"
xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
<bean id="user" class="cn.xy.hw.User">
<property name="name" value="hanwei"/>
<property name="age" value="20"/>
</bean>
<bean id="messageSource"
class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basename" value="xiyou"/>
</bean>
<bean id="listener" class="cn.xy.hw.RainListener"/>
</beans>
載入 Spring 容器,測試國際化訊息獲取與事件發布:
package cn.xy.hw;
import java.util.Calendar;
import java.util.Locale;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MainTest {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
User user = (User) context.getBean("user");
Object[] args = {user.getName(), Calendar.getInstance().getTime()};
// 中文環境
System.out.println(context.getMessage("userlogin", args, "找不到指定模組!", Locale.CHINA));
// 英文環境
System.out.println(context.getMessage("userlogin", args, "找不到指定模組!", Locale.US));
// 發布自定義事件
context.publishEvent(new RainEvent("下雨了!"));
}
}
使用者 hanwei 於 07-8-26 下午6:14登入
user hanwei login at 8/26/07 6:14 PM
烏雲密布、閃電、打雷,緊接著,下起了瓢潑大雨。
唐僧大喊:下雨了!趕緊收衣服喽!
log4j:WARN No appenders could be found for logger (org.springframework.context.support.ClassPathXmlApplicationContext).
log4j:WARN Please initialize the log4j system properly.
透過這個完整範例,我們展示了 Spring 核心功能的兩大支柱:MessageSource 實現國際化(i18n)與ApplicationEvent 實現事件驅動架構。實際專案中,這兩項機制廣泛應用於多語系支援、業務解耦、非同步通知等場景。