1. 程式人生 > 其它 >spring中InitializingBean的使用

spring中InitializingBean的使用

1、InitializingBean介面

InitializingBean介面中只包含一個afterPropertiesSet()方法,繼承該介面的類,在初始化bean的時候都會執行該方法,且只執行一次
測試如下

package com.rookie.bigdata.Initializingbean;

import org.springframework.beans.factory.InitializingBean;

/**
 * @author
 * @date 2019/5/22
 */
public class AfterInitializingBean implements InitializingBean {
    @Override
    public void afterPropertiesSet() throws Exception {

        System.out.println("執行afterPropertiesSet()方法");
    }

    public void init() {
        System.out.println("執行了init的方法");
    }
}

application-bean.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd
        http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.1.xsd">


    <bean id="AfterInitializingBean" class="com.rookie.bigdata.Initializingbean.AfterInitializingBean" init-method="init"></bean>


</beans>

測試類及測試結果

    @Test
    public void afterPropertiesSet() throws Exception {

        ApplicationContext applicationContext=new ClassPathXmlApplicationContext("com/rookie/bigdata/Initializingbean/application-bean.xml");
    }


在spring初始化bean的時候,如果該bean是實現了InitializingBean介面,並且同時在配置檔案中指定了init-method,系統則是先呼叫afterPropertiesSet方法,然後在呼叫init-method中指定的方法

2、AbstractAutowireCapableBeanFactory

出現上面結果的原因為在載入bean的時候執行了AbstractAutowireCapableBeanFactory類中的invokeInitMethods()方法

protected void invokeInitMethods(String beanName, final Object bean, @Nullable RootBeanDefinition mbd)
			throws Throwable {

			//判斷給bean物件是否實現了InitializingBean,如果實現了該介面,就呼叫afterPropertiesSet方法
		boolean isInitializingBean = (bean instanceof InitializingBean);
		if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
			if (logger.isTraceEnabled()) {
				logger.trace("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
			}
			if (System.getSecurityManager() != null) {
				try {
					AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {
			//呼叫afterPropertiesSet方法					
						((InitializingBean) bean).afterPropertiesSet();
						return null;
					}, getAccessControlContext());
				}
				catch (PrivilegedActionException pae) {
					throw pae.getException();
				}
			}
			else {
			//呼叫afterPropertiesSet方法
				((InitializingBean) bean).afterPropertiesSet();
			}
		}

		if (mbd != null && bean.getClass() != NullBean.class) {
			String initMethodName = mbd.getInitMethodName();
			//判斷是否指定了init-method方法,如果指定了init-method方法,則再呼叫制定的init-method
			if (StringUtils.hasLength(initMethodName) &&
					!(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
					!mbd.isExternallyManagedInitMethod(initMethodName)) {
				invokeCustomInitMethod(beanName, bean, mbd);
			}
		}
	}

3、總結

1、spring執行的時候,首先會呼叫afterPropertiesSet方法,其次當配置檔案中配置了init-method,會呼叫init-method指定的方法
2、spring執行的時候,首先會呼叫afterPropertiesSet方法,當配置檔案中配置了init-method,且方法為afterPropertiesSet時,該方法只調用一次