Spirng的InitializingBean为bean提供了定义初始化方法的方式。InitializingBean是一个接口,它仅仅包含一个方法:afterPropertiesSet()。
package research.spring.beanfactory.ch4;import org.springframework.beans.factory.InitializingBean; public class LifeCycleBean implements InitializingBean{ public void afterPropertiesSet() throws Exception {System. out .println( " LifeCycleBean initializing... " );}}
xml version="1.0" encoding="UTF-8"?>DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN""http://www.springframework.org/dtd/spring-beans.dtd"><beans><bean name="lifeBean" class="research.spring.beanfactory.ch4.LifeCycleBean">bean>beans>
package research.spring.beanfactory.ch4;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( " research/spring/beanfactory/ch4/context.xml " ));factory.getBean( " lifeBean " );}}
SHAPE \* MERGEFORMAT
装配bean的合作者 |
查看bean是否实现InitializingBean接口 |
调用afterPropertiesSet方法 |
package research.spring.beanfactory.ch4; public class LifeCycleBean{ public void init(){System. out .println( " LifeCycleBean.init... " );}}
xml version="1.0" encoding="UTF-8"?>DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN""http://www.springframework.org/dtd/spring-beans.dtd"><beans><bean name="lifeBean" class="research.spring.beanfactory.ch4.LifeCycleBean" init-method="init">bean>beans>
final protected void init() throws Exception{
System.out.println("init method...");
if(true) throw new Exception("init exception");
// …… // 在一个bean的合作者设备完成后,执行一个bean的初始化方法。 protected void invokeInitMethods(String beanName, Object bean, RootBeanDefinition mergedBeanDefinition) throws Throwable { // 判断bean是否实现了InitializingBean接口 if (bean instanceof InitializingBean) { if (logger.isDebugEnabled()) {logger.debug( " Invoking afterPropertiesSet() on bean with name ‘ " + beanName + " ‘ " );} // 调用afterPropertiesSet方法 ((InitializingBean) bean).afterPropertiesSet();} // 判断bean是否定义了init-method if (mergedBeanDefinition != null && mergedBeanDefinition.getInitMethodName() != null ) { // 调用invokeCustomInitMethod方法来执行init-method定义的方法 invokeCustomInitMethod(beanName, bean, mergedBeanDefinition.getInitMethodName());}} // 执行一个bean定义的init-method方法 protected void invokeCustomInitMethod(String beanName, Object bean, String initMethodName)throws Throwable { if (logger.isDebugEnabled()) {logger.debug( " Invoking custom init method ‘ " + initMethodName + " ‘ on bean with name ‘ " + beanName + " ‘ " );} // 使用方法名,反射Method对象 Method initMethod = BeanUtils.findMethod(bean.getClass(), initMethodName, null ); if (initMethod == null ) { throw new NoSuchMethodException( " Couldn‘t find an init method named ‘ " + initMethodName + " ‘ on bean with name ‘ " + beanName + " ‘ " );} // 判断方法是否是public if ( ! Modifier.isPublic(initMethod.getModifiers())) { // 设置accessible为true,可以访问private方法。 initMethod.setAccessible( true );} try { // 反射执行这个方法 initMethod.invoke(bean, (Object[]) null );} catch (InvocationTargetException ex) { throw ex.getTargetException();}} // ………..
如果一个bean被定义为非单例的,那么afterPropertiesSet和init-method在bean的每一个实例被创建时都会执行。单例 bean的afterPropertiesSet和init-method只在bean第一次被实例时调用一次。大多数情况下 afterPropertiesSet和init-method都应用在单例的bean上。