spring容器初始化过程笔记(四)InitializingBean 接口的 afterPropertiesSet 方法执行

InitializingBean 接口的 afterPropertiesSet 方法执行

前言

这篇讲了spring 源码 InitializingBean 接口的 afterPropertiesSet 方法执行描述 ,主要是对spring源码 做笔记,需要读者下载spring源码 编译执行 辅助。

InitializingBean 接口afterPropertiesSet 执行时间,源码分析

Bean初始化过程中 doCreateBean 中的 initializeBean(beanName, exposedObject, mbd);

initializeBean 方法内的 invokeInitMethods方法
1. 如果bean 对应的Class实现了InitializingBean 接口 ,invoke afterPropertiesSet 方法
2. 如果Bean class不为NullBean 执行Bean initMethodName 初始化化方法

initializeBean方法源码:

/**
 把实例化后的bean初始化,请求工厂回调 初始化方法和 bean 后置处理器
*/	
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
		if (System.getSecurityManager() != null) {
			AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
				invokeAwareMethods(beanName, bean);
				return null;
			}, getAccessControlContext());
		}
		else {
			invokeAwareMethods(beanName, bean);
		}

		Object wrappedBean = bean;
		if (mbd == null || !mbd.isSynthetic()) {
            //  初始化Bean之前 请求应用Bean后置处理器
            //  1. 执行Bean后置处理器postProcessBeforeInitialization
            //  比如 执行Aware 子类中的postProcessBeforeInitialization
			wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
		}

		try {
            // 调用 初始化化方法
            // 如果bean 对应的Class实现了InitializingBean 接口 ,invoke afterPropertiesSet 方法
            // 如果Bean class不为NullBean   执行Bean initMethodName 初始化化方法
			invokeInitMethods(beanName, wrappedBean, mbd);
		}
		catch (Throwable ex) {
			throw new BeanCreationException(
					(mbd != null ? mbd.getResourceDescription() : null),
					beanName, "Invocation of init method failed", ex);
		}
		if (mbd == null || !mbd.isSynthetic()) {
            // 初始化化Bean之后 请求bean后置处理器
            //
			wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
		}

		return wrappedBean;
	}

invokeInitMethods 源码

从下面源码可以看出,如果该bean实例 是InitializingBean 类型的话,执行afterPropertiesSet 方法

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

		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>) () -> {
						((InitializingBean) bean).afterPropertiesSet();
						return null;
					}, getAccessControlContext());
				}
				catch (PrivilegedActionException pae) {
					throw pae.getException();
				}
			}
			else {
				((InitializingBean) bean).afterPropertiesSet();
			}
		}

		if (mbd != null && bean.getClass() != NullBean.class) {
			String initMethodName = mbd.getInitMethodName();
			if (StringUtils.hasLength(initMethodName) &&
					!(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
					!mbd.isExternallyManagedInitMethod(initMethodName)) {
				invokeCustomInitMethod(beanName, bean, mbd);
			}
		}
	}

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
是的,您说得对。下面是一个示例代码,用于演示BeanPostProcessor的postProcessAfterInitialization方法InitializingBean的afterPropertiesSet方法之后执行的情况: ```java import org.springframework.beans.BeansException; import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.config.BeanPostProcessor; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.stereotype.Component; @Component public class DemoBean implements InitializingBean, BeanPostProcessor { @Override public void afterPropertiesSet() throws Exception { System.out.println("InitializingBean's afterPropertiesSet method called"); } @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { System.out.println("BeanPostProcessor's postProcessAfterInitialization method called for bean " + beanName); return bean; } public static void main(String[] args) { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(); context.register(DemoBean.class); context.refresh(); DemoBean demoBean = context.getBean(DemoBean.class); } } ``` 在上面的示例中,DemoBean实现了InitializingBean接口,并且重写了afterPropertiesSet方法。同时,DemoBean还实现了BeanPostProcessor接口,并重写了postProcessAfterInitialization方法。 在程序执行期间,当DemoBean被创建并初始化时,Spring容器会先调用InitializingBean的afterPropertiesSet方法,然后再调用BeanPostProcessor的postProcessAfterInitialization方法。因此,上面的示例代码的输出应该是: ``` InitializingBean's afterPropertiesSet method called BeanPostProcessor's postProcessAfterInitialization method called for bean demoBean ``` 这样,就证明了BeanPostProcessor的postProcessAfterInitialization方法确实是在InitializingBean的afterPropertiesSet方法之后执行的。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值