spring的bean初始化

spring为bean提供了两种初始化bean的方式,实现InitializingBean接口,实现afterPropertiesSet方法,或者在配置文件中同过init-method指定,两种方式可以同时使用。如下:

 

 

import org.springframework.beans.factory.InitializingBean;
public class TestInitializingBean implements InitializingBean{

    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("ceshi InitializingBean");        
    }
    public void testInit(){
        System.out.println("ceshi init-method");        
    }
}
 

 

 

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:jdbc="http://www.springframework.org/schema/jdbc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="
    http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
    <bean id="testInitializingBean" class="com.TestInitializingBean" init-method="testInit"></bean>
</beans>
 

疑问:如果bean实现了InitializingBean接口同时在配置文件中又制定了init-method方法,那么会先调用那个方法呢?查源码

AbstractAutowireCapableBeanFactory.java 的invokeInitMethods方法源码如下:

 

protected void invokeInitMethods(String beanName, Object bean, RootBeanDefinition mbd)
			throws Throwable {
                //判断bean是否实现了InitializingBean
		boolean isInitializingBean = (bean instanceof InitializingBean);
               //如果实现了InitializingBean并且....
		if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
			if (logger.isDebugEnabled()) {
				logger.debug("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
			}
                         //调用afterPropertiesSet()方法
			((InitializingBean) bean).afterPropertiesSet();
		}
                      //判断是否指定了init-method方法,如果制定了再调用init-method方法
		String initMethodName = (mbd != null ? mbd.getInitMethodName() : null);
		if (initMethodName != null && !(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
				!mbd.isExternallyManagedInitMethod(initMethodName)) {
                      //init-method方法是用反射实现的
			invokeCustomInitMethod(beanName, bean, initMethodName, mbd.isEnforceInitMethod());
		}
	}
实现InitializingBean接口是直接调用afterPropertiesSet方法,比通过反射调用init-method指定的方法效率相对来说要高点。但是init-method方式消除了对spring的依赖
如果调用afterPropertiesSet方法时出错,则不调用init-method指定的方法。
 

你可能感兴趣的:(spring bean 初始化)