Spring5 源码阅读笔记(1.4.2.5)initializeBean(beanName, exposedObject, mbd)

本文深入解析Spring框架中Bean的初始化过程,包括InitializingBean接口、@PostConstruct注解及init-method属性的使用时机与顺序,揭示了initializeBean方法如何协调这些初始化机制。

本节重点
initializeBean 主要做了2件事:

  1. 调用3中初始化方法
  2. 请求AOP,返回代理类

先看一段代码,猜猜 Spring 启动后的打印顺序:

public class InitMethodBean implements InitializingBean{
	//jdk 提供的注解
    @PostConstruct
    public void postConstruct() {
        System.out.println("======构造方法之后=======");
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("======属性设置之后======");
    }
	//基于配置
    public void initMethod() {
        System.out.println("======初始化方法======");
    }
}

在 spring.xml 配置 :

<bean id="initMethodBean" class="com.test.InitMethodBean" init-method="initMethod"/>

结果:
在这里插入图片描述
从方法的名字上合情合理的结果,但其实都是在属性设置之后,因为它们都是在本小节讲的方法 initializeBean 里调用的,而这个方法本身就在 1.4.2.4 小节讲的 populateBean 填充 Bean 实例(依赖注入)之后。

跟源码:
AbstractAutowireCapableBeanFactory

protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
	if (System.getSecurityManager() != null) {
		AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
			invokeAwareMethods(beanName, bean);
			return null;
		}, getAccessControlContext());
	}
	else {
		//调用Aware方法
		invokeAwareMethods(beanName, bean);
	}

	Object wrappedBean = bean;
	if (mbd == null || !mbd.isSynthetic()) {
		//重要程度 :5 对类中某些特殊方法的调用,比如 @PostConstruct,Aware接口
		wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
	}

	try {
		//重要程度:5 InitializingBean接口,afterPropertiesSet,init-method属性调用
		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()) {
		//AOP入口 见3
		wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
	}

	return wrappedBean;
}

跟 invokeInitMethods:

protected void invokeInitMethods(String beanName, final Object bean, @Nullable RootBeanDefinition mbd)
		throws Throwable {
	//实现InitializingBean接口可以在类实例化后,做一些事情
	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);
		}
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值