spring使用BeanFactory來實例化、配置和管理對象,可是它只是一個接口,裏面有一個getBean()方法。咱們通常都不直接用BeanFactory,而是用它的實現類ApplicationContext,這個類會自動解析咱們配置的applicationContext.xml,而後根據咱們配置的bean來new對象,將new好的對象放進一個Map中,鍵就是咱們bean的id,值就是new的對象。java
經常使用的設定方式有如下三種:spring
public class InitSequenceBean implements InitializingBean { public InitSequenceBean() { System.out.println("InitSequenceBean: constructor"); } @PostConstruct public void postConstruct() { System.out.println("InitSequenceBean: postConstruct"); } public void initMethod() { System.out.println("InitSequenceBean: init-method"); } @Override public void afterPropertiesSet() throws Exception { System.out.println("InitSequenceBean: afterPropertiesSet"); } }
而且在配置文件中添加以下Bean定義:app
<bean class="InitSequenceBean" init-method="initMethod"></bean>
輸出結果:ide
InitSequenceBean: constructor InitSequenceBean: postConstruct InitSequenceBean: afterPropertiesSet InitSequenceBean: init-method
經過上述輸出結果,說明三種初始化的順序是:
Constructor > @PostConstruct > InitializingBean > init-methodpost
緣由:
@PostConstruct註解後的方法在BeanPostProcessor前置處理器中就被執行了。咱們知道BeanPostProcessor接口是一個回調的做用,spring容器的每一個受管Bean在調用初始化方法以前,都會得到BeanPostProcessor接口實現類的一個回調。在BeanPostProcessor的方法中有一段邏輯就是會判斷當前被回調的bean的方法中有沒有被initAnnotationType/destroyAnnotationType註釋,若是有,則添加到init/destroy隊列中,後續一一執行。initAnnotationType/destroyAnnotationType註解就是@PostConstruct/@PreDestroy。因此@PostConstruct固然要先於InitializingBean和init-method執行了。prototype
從圖中,咱們能夠看到實例化Bean的過程當中有如下幾個節點:code