首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >InitializingBean接口

InitializingBean接口

作者头像
IT云清
发布于 2019-01-22 15:32:47
发布于 2019-01-22 15:32:47
1.3K0
举报
文章被收录于专栏:IT云清IT云清

1.作用

InitializingBean接口只包含一个方法afterPropertiesSet(),凡是继承了InitializingBean接口的类,在初始化时都会调用这方法。(原因见后文分析)

2.源码:

代码语言:javascript
复制
package org.springframework.beans.factory;

/**
 *  //由bean实现的接口,一旦bean工厂设置了它们的所有属性,就需要对其进行响应:
 *	例如,执行定制初始化,或检查所有强制属性是否已设置。
 * 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.
 *
 * //实现InitializingBean的另一种方法是指定一个定制的init-方法,例如在XML bean定义中
 * <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
 * {@link BeanFactory 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 {

	/**
	 *//在BeanFactory设置了提供的所有bean属性后调用,
	 *//此方法允许bean实例仅在设置了所有bean属性之后才能执行初始化,并在配置错误时抛出异常。
	 *//在发生错误配置(如设置基本属性失败)或初始化失败的情况下会抛出Exception 
	 * 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;

}

3.分析afterPropertiesSet()方法执行时机

在spring加载bean的类AbstractAutowireCapableBeanFactory源码中,可以找到如下方法:
代码语言:javascript
复制
        /**
         * 让bean有机会对其所有属性进行响应,并有机会了解其所属bean工厂(此对象).
         * 这意味着检查bean是否实现了InitializingBean或定义了自定义init方法,
         * 如果实现了,则调用必要的回调。
         */
	/**
	 * Give a bean a chance to react now all its properties are set,
	 * and a chance to know about its owning bean factory (this object).
	 * This means checking whether the bean implements InitializingBean or defines
	 * a custom init method, and invoking the necessary callback(s) if it does.
	 * @param beanName the bean name in the factory (for debugging purposes)
	 * @param bean the new bean instance we may need to initialize
	 * @param mbd the merged bean definition that the bean was created with
	 * (can also be {@code null}, if given an existing bean instance)
	 * @throws Throwable if thrown by init methods or by the invocation process
	 * @see #invokeCustomInitMethod
	 */
	protected void invokeInitMethods(String beanName, final Object bean, @Nullable 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((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)) {
				//查看该方法的源码,可以发现init-method方法中指定的方法是通过反射实现
				invokeCustomInitMethod(beanName, bean, mbd);
			}
		}
	}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2018年11月07日,如有侵权请联系 cloudcommunity@tencent.com 删除
目录
  • 1.作用
    • InitializingBean接口只包含一个方法afterPropertiesSet(),凡是继承了InitializingBean接口的类,在初始化时都会调用这方法。(原因见后文分析)
  • 2.源码:
  • 3.分析afterPropertiesSet()方法执行时机
    • 在spring加载bean的类AbstractAutowireCapableBeanFactory源码中,可以找到如下方法:
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档