1、InitializingBean接口說明
InitializingBean接口爲bean提供了屬性初始化後的處理方法,它只包括afterPropertiesSet方法,凡是繼承該接口的類,在bean的屬性初始化後都會執行該方法。java
package org.springframework.beans.factory; /** * Interface to be implemented by beans that need to react once all their * properties have been set by a BeanFactory: for example, to perform custom * initialization, or merely to check that all mandatory properties have been set. * * <p>An alternative to implementing InitializingBean is specifying a custom * init-method, for example in an XML bean definition. * For a list of all bean lifecycle methods, see the BeanFactory javadocs. * * @author Rod Johnson * @see BeanNameAware * @see BeanFactoryAware * @see BeanFactory * @see org.springframework.beans.factory.support.RootBeanDefinition#getInitMethodName * @see org.springframework.context.ApplicationContextAware */ public interface InitializingBean { /** * Invoked by a BeanFactory after it has set all bean properties supplied * (and satisfied BeanFactoryAware and ApplicationContextAware). * <p>This method allows the bean instance to perform initialization only * possible when all bean properties have been set and to throw an * exception in the event of misconfiguration. * @throws Exception in the event of misconfiguration (such * as failure to set an essential property) or if initialization fails. */ void afterPropertiesSet() throws Exception; }
從方法名afterPropertiesSet也能夠清楚的理解該方法是在屬性設置後才調用的。
2、源碼分析接口應用
經過查看spring的加載bean的源碼類(AbstractAutowireCapableBeanFactory)能夠看到react
protected void invokeInitMethods(String beanName, final Object bean, RootBeanDefinition mbd) throws Throwable { //判斷該bean是否實現了實現了InitializingBean接口,若是實現了InitializingBean接口,則調用bean的afterPropertiesSet方法 boolean isInitializingBean = (bean instanceof InitializingBean); if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) { if (logger.isDebugEnabled()) { logger.debug("Invoking afterPropertiesSet() on bean with name '" + beanName + "'"); } if (System.getSecurityManager() != null) { try { AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() { public Object run() throws Exception { //調用afterPropertiesSet ((InitializingBean) bean).afterPropertiesSet(); return null; } }, getAccessControlContext()); } catch (PrivilegedActionException pae) { throw pae.getException(); } } else { //調用afterPropertiesSet ((InitializingBean) bean).afterPropertiesSet(); } } if (mbd != null) { //判斷是否指定了init-method方法,若是指定了init-method方法,則再調用制定的init-method String initMethodName = mbd.getInitMethodName(); if (initMethodName != null && !(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) && !mbd.isExternallyManagedInitMethod(initMethodName)) { //反射調用init-method方法 invokeCustomInitMethod(beanName, bean, mbd); } } }
分析代碼能夠了解:
1:spring爲bean提供了兩種初始化bean的方式,實現InitializingBean接口,實現afterPropertiesSet方法,或者在配置文件中同過init-method指定,兩種方式能夠同時使用
2:實現InitializingBean接口是直接調用afterPropertiesSet方法,比經過反射調用init-method指定的方法效率相對來講要高點。可是init-method方式消除了對spring的依賴
3:若是調用afterPropertiesSet方法時出錯,則不調用init-method指定的方法。spring
3、接口應用
InitializingBean接口在spring框架中自己就不少應用,這就很少說了。咱們在實際應用中如何使用該接口呢?微信
一、使用InitializingBean接口處理一個配置文件:app
import java.io.File; import java.io.FileInputStream; import java.util.Properties; import org.springframework.beans.factory.InitializingBean; public class ConfigBean implements InitializingBean{ //微信公衆號配置文件 private String configFile; private String appid; private String appsecret; public String getConfigFile() { return configFile; } public void setConfigFile(String configFile) { this.configFile = configFile; } public void afterPropertiesSet() throws Exception { if(configFile!=null){ File cf = new File(configFile); if(cf.exists()){ Properties pro = new Properties(); pro.load(new FileInputStream(cf)); appid = pro.getProperty("wechat.appid"); appsecret = pro.getProperty("wechat.appsecret"); } } System.out.println(appid); System.out.println(appsecret); } }
二、配置
spring配置文件:框架
<bean id="configBean" class="com.ConfigBean"> <property name="configFile" value="d:/wechat.properties"></property> </bean>
wechat.properties配置文件源碼分析
wechat.appid=wxappid wechat.appsecret=wxappsecret
三、測試測試
public static void main(String[] args) throws Exception { String config = Test.class.getPackage().getName().replace('.', '/') + "/bean.xml"; ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(config); context.start(); }