afterPropertiesSet方法和init-method區別和應用


InitializingBean

       spring的InitializingBean為bean提供了定義初始化方法的方式。InitializingBean是一個接口,只包含一個方法:afterPropertiesSet():

public interface InitializingBean
{
  public abstract void afterPropertiesSet()

  throws Exception;

}

 

用法示例:
Bean實現:

 

import org.springframework.beans.factory.InitializingBean;

 

publicclass LifeCycleBean implements InitializingBean{

 

 

  void afterPropertiesSet() throws Exception {

 

 

    System.out.println("LifeCycleBean initializing...");

 

 

  }

 

 

}

 

在xml配置文件中並不需要對bean進行特殊的配置:

<beans>

  <bean name = "lifeBean" class ="com.spring.LifeCycleBean"></beans >
</beans>

 

編寫測試程序進行測試:

 

 

 

import org.springframework.beans.factory.xml.XmlBeanFactory;

 

 

import org.springframework.core.io.ClassPathResource;

 

 

public class LifeCycleTest {

 

 

  public static void main(String[] args) {

 

 

    XmlBeanFactory factory= new XmlBeanFactory( new ClassPathResource("com/spring/applicationcontext.xml"));

 

 

    factory.getBean("lifeBean");

 

 

  }

 

 

}

 

 

    運行之后,我們可以看到下面的結果:LifeCycleBean initializing...。說明bean的afterPropertiesSet方法被spring調用了。
    spring在裝配完一個bean的所有合作者之后,會檢查這個bean是否實現了InitializingBean接口,如果實現就調用該bean的afterPropertiesSet方法。
 
 
 
init-method
    Spring雖然可以通過InitializingBean完成bean初始化后對這個bean的回調,但是這種方式要求bean實現InitializingBean接口。一但bean實現了InitializingBean接口,那么這個bean的代碼就和Spring耦合到一起了。通常情況下我不鼓勵bean直接實現InitializingBean,可以使用Spring提供的init-method的功能來執行一個bean子定義的初始化方法。

bean實現:

 

 

package com.spring;

 

 

public class LifeCycleBean{

 

 

  publicvoid init(){

 

 

    System. out .println("LifeCycleBean.init...");

 

 

  }

 

 

}

 

在Spring配置文件中配置這個bean:

 

<beans>

 

 

  <bean name ="lifeBean" class ="research.spring.beanfactory.ch4.LifeCycleBean" init-method ="init"></bean>

 

 

</beans>

 

 

      當spring實例化lifeBean時,你會看到控制台上打印出LifeCycleBean.init...
     Spring要求init-method是一個無參的方法,如果init-method指定的方法中有參數,那么Spring將會拋出java.lang.NoSuchMethodException。init-method指定的方法可以是public、protected以及private的,並且方法也可以是final的。另外,init-method指定的方法可以是聲明為拋出異常的,就像這樣:

 

 

final protected void init() throws Exception{

 

 

  System.out.println( "init method...");

 

 

  if(true)

 

 

  throw new Exception("init exception");

 

 

}

 

   

 

    通過分析上面的源代碼我們可以看到,init-method是通過反射執行的,而afterPropertiesSet是直接執行的。所以afterPropertiesSet的執行效率要比init-method高,不過init-method消除了bean對Spring依賴。在實際使用時我推薦使用init-method。另外,需要注意的是Spring總是先處理bean定義的InitializingBean,然后才處理init-method。如果在Spirng處理InitializingBean時出錯,那么Spring將直接拋出異常,不會再繼續處理init-method。
    如果一個bean被定義為非單例的,那么afterPropertiesSet和init-method在bean的每一個實例被創建時都會執行。單例 bean的afterPropertiesSet和init-method只在bean第一次被實例時調用一次。大多數情況下 afterPropertiesSet和init-method都應用在單例的bean上。
 
可以借助這個InitializingBean方法來完成一些需要在bean初始化時完成的工作。
示例場景:
一個bean在初始化時需要讀取項目目錄中某個文件夾下的配置文件。
bean配置:

 

 
<bean id= "testServiceConfig" class="com.lmb.client.TestlServiceConfigImpl">

 

 

  <property name= "folderName" value="test_config" />

 

 

</bean>

 

調用代碼:

 

 

//bean初始化之后調用afterPropertiesSet方法根據配置目錄,讀取相應目錄下的配置文件

 

 

public class TestServiceConfigImpl implements InitializingBean {

 

 

private String folderName;

 

 

@Override

 

 

public void afterPropertiesSet()throws Exception{

 

 

  folderName = folderName != null ? folderName : "test_config";

 

 

  reload(folderName);

 

 

}

 

 

//根據文件目錄加載配置文件

 

 

public void reload(String fileName) throws Exception {

 

 

  fileName = fileName.startsWith("/") ? fileName.substring(1) : fileName;

 

 

  //根據文件名稱獲取相應的文件

 

 

  File file = ResourceUtils.getFile("classpath:" + fileName);

  if (file.isDirectory()) {

 

    File[] files = file.listFiles();

 

 

    for (File configFile : files) {

 

 

      //加載文件……

 

 

    }

 

 

  }

 

}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM