2016年1月6日 星期三

事件 (Spring3.x 十七)

參考文件

※內鍵event

@Component
public class ObjectListener implements ApplicationListener {
    @Override
    public void onApplicationEvent(ApplicationEvent event) {
        System.out.println(event.getClass().getName());
    }
}


ConfigurableApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");// ContextRefreshedEvent
// ctx.publishEvent(new TestEvent(ctx));// impl.TestEvent(自定的event)
ctx.start();// ContextStartedEvent
ctx.refresh();// ContextRefreshedEvent
ctx.stop();// ContextStoppedEvent
ctx.close();// ContextClosedEvent

※事件都在org.springframework.context.event包裡,其中啟動和refresh方法都會呼叫ContextRefreshedEvent事件

※不加泛型全部的事件都會攔到,如果只想攔其中一個就加泛型,如「implements ApplicationListener<ContextStoppedEvent>」,而實作的參數就會變ContextStoppedEvent,這時就只會攔到ContextStoppedEvent事件了



※自定event

1.寫一隻class繼承ApplicationEvent
2.寫一隻class實作ApplicationListener<1的class>
3.如果有人呼叫1的class,就會自動觸發2的onApplicationEvent方法



TestEvent.java

public class TestEvent extends ApplicationEvent {
    public TestEvent(Object source) {
        super(source);
        Date date = new Date(super.getTimestamp());
        DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        System.out.println("在" + df.format(date) + " 呼叫 TestEvent 建構子");
    }
}



TestListener

@Component
public class TestListener implements ApplicationListener<TestEvent> {
    @Override
    public void onApplicationEvent(TestEvent event) {
        System.out.println("TestEvent 的事件被觸發了");
    }
}



測試類

ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
    
for (String s : ctx.getBeanDefinitionNames()) {
    System.out.println(s);
}
    
TestEvent event = new TestEvent("xxx");
ctx.publishEvent(event);
    
((ClassPathXmlApplicationContext) ctx).close();

※結果:
在2016-01-07 15:02:46 呼叫 TestEvent 建構子
TestEvent 的事件被觸發了

※我有將1的event換成其他event,但不管是哪一個event,一定會呼叫到

※我將close註解,內鍵的要呼叫close才會成功,但我用自定的publishEvent裡面是自己的event,繼承ContextClosedEvent,但還是會成功,詭異!

沒有留言:

張貼留言