- package com.xx;
- import javax.annotation.PostConstruct;
- import javax.annotation.Resource;
- import org.springframework.beans.factory.InitializingBean;
- import org.springframework.context.ApplicationListener;
- import org.springframework.context.event.ContextRefreshedEvent;
- import org.springframework.stereotype.Component;
- import com.xx.service.DemoService;
- @Component
- public class InitBeanTest implements InitializingBean,ApplicationListener<ContextRefreshedEvent> {
- @Resource
- DemoService demoService;
- public InitBeanTest() {
- System.err.println("----> InitSequenceBean: constructor: "+demoService);
- }
- @PostConstruct
- public void postConstruct() {
- System.err.println("----> InitSequenceBean: postConstruct: "+demoService);
- }
- @Override
- public void afterPropertiesSet() throws Exception {
- System.err.println("----> InitSequenceBean: afterPropertiesSet: "+demoService);
- }
- @Override
- public void onApplicationEvent(ContextRefreshedEvent arg0) {
- System.err.println("----> InitSequenceBean: onApplicationEvent");
- }
- }
執行結果:
----> InitSequenceBean: constructor: null
----> InitSequenceBean: postConstruct: com.yiniu.kdp.service.impl.DemoServiceImpl@40fe544
----> InitSequenceBean: afterPropertiesSet: com.yiniu.kdp.service.impl.DemoServiceImpl@40fe544
----> InitSequenceBean: onApplicationEvent
----> InitSequenceBean: onApplicationEvent
分析:
構造函數是每個類最先執行的,這個時候,bean屬性還沒有被注入
postConstruct優先於afterPropertiesSet執行,這時屬性竟然也被注入了,有點意外
spring很多組建的初始化都放在afterPropertiesSet做。我們在做一些中間件想和spring一起啟動,可以放在這里啟動。
onApplicationEvent屬於應用層的時間,最后被執行,很容易理解。注意,它出現了兩次,為什么?因為bean注入了DemoService,spring容器會被刷新。
換言之onApplicationEvent會被頻繁執行,需要使用它監聽,需要考慮性能問題。
很顯然,這是觀察者模式的經典應用。