随笔分类
bean 初始化
生命周期中对应 bean的初始化
initializeBean
/**
* bean 配置时 bean有一个 init-method属性
* 这个属性的作用在 bean初始化之前 去调用 init-method指定的方法, 根据用户的业务进行相应的初始化
* 总结:这里主要做了什么事?
* 1.激活 Aware方法
* 2.处理器的应用
* 3.激活自定义的 init方法
*/
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
/** 激活 Aware方法 **/
/** 这里会根据当前 bean实现的具体的 Aware接口来 set某些数据 **/
invokeAwareMethods(beanName, bean);
return null;
}, getAccessControlContext());
}
else {
invokeAwareMethods(beanName, bean);
}
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
/** 方便用户可以根据自己的业务需求进行相应的处理 **/
/** 这里也是后置处理器的调用点 beanPostProcessorsInitialization 初始化之前 **/
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
/** 这里就完成了 用户自定义的初始化方法 的反射调用 **/
/**
* 用户定制的初始化方法除了我们熟知的使用配置 init-method外,
* 还有使 自定义的 bean实现 InitializingBean接口, 并且在 afterPropertiesSet中实现自己的初始化业务逻辑
* init-method 和 afterPropertiesSet都是在初始化 bean时执行,二者的执行顺序: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()) {
/** 这里也是个后置处理器的调用点 beanPostProcessorsAfterInitialization 初始化完之后的后置处理器的调用点 **/
/** 典型应用:Spring AOP的实现... vital **/
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
invokeAwareMethods
private void invokeAwareMethods(String beanName, Object bean) {
/** 这里来判断 bean是否有来实现 Aware接口 **/
if (bean instanceof Aware) {
/** 激活 Aware方法 **/
/** 这里会根据当前 bean实现的具体的 Aware接口来 set某些数据 **/
if (bean instanceof BeanNameAware) {
((BeanNameAware) bean).setBeanName(beanName);
}
if (bean instanceof BeanClassLoaderAware) {
ClassLoader bcl = getBeanClassLoader();
if (bcl != null) {
((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
}
}
if (bean instanceof BeanFactoryAware) {
((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
}
}
}
applyBeanPostProcessorsBeforeInitialization
@Override
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
for (BeanPostProcessor processor : getBeanPostProcessors()) {
/** 执行 postProcessBeforeInitialization 处理器, 默认返回 bean **/
Object current = processor.postProcessBeforeInitialization(result, beanName);
/** 如果 beforeInitialization处理器中返回了 null, 这里会去执行一个短路操作,返回上一个处理器处理完之后的结果 **/
if (current == null) {
return result;
}
result = current;
}
return result;
}
postProcessAfterInitialization
/**
* bean初始化结束后会去 调用
*/
@Nullable
default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
invokeInitMethods
/**
* 用户定制的初始化方法除了我们熟知的使用配置 init-method外,
* 还有使 自定义的 bean实现 InitializingBean接口, 并且在 afterPropertiesSet中实现自己的初始化业务逻辑
* init-method 和 afterPropertiesSet都是在初始化 bean时执行,二者的执行顺序:afterPropertiesSet先, init-method后
*/
protected void invokeInitMethods(String beanName, Object bean, @Nullable RootBeanDefinition mbd)
throws Throwable {
boolean isInitializingBean = (bean instanceof InitializingBean);
/** 首先会去检查是否是 InitializingBean, 如果时的话那就需要去调用 afterPropertiesSet方法 **/
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 {
/** 完成 afterPropertiesSet接口方法的调用 **/
((InitializingBean) bean).afterPropertiesSet();
}
}
if (mbd != null && bean.getClass() != NullBean.class) {
String initMethodName = mbd.getInitMethodName();
if (StringUtils.hasLength(initMethodName) &&
/** 这里会去调用自定义的初始化方法 init-method **/
!(isInitializingBean && "afterPropertiesSet".equals(initMethodName) /** 这里其实是预防重复调用同一个初始化方法 **/) &&
!mbd.isExternallyManagedInitMethod(initMethodName)) {
invokeCustomInitMethod(beanName, bean, mbd);
}
}
}
invokeCustomInitMethod
protected void invokeCustomInitMethod(String beanName, Object bean, RootBeanDefinition mbd)
throws Throwable {
// 获取 init-method方法
String initMethodName = mbd.getInitMethodName();
Assert.state(initMethodName != null, "No init method set");
/** 这里会根据 mbd中配置的权限信息来拿到合适的 init-method所定义的方法对象 **/
Method initMethod = (mbd.isNonPublicAccessAllowed() ?
BeanUtils.findMethod(bean.getClass(), initMethodName) :
ClassUtils.getMethodIfAvailable(bean.getClass(), initMethodName));
/** true -> 说明未找到 init-method方法... 这里就需要来报异常和输出日志了... 这里不用过于分析 **/
if (initMethod == null) {
if (mbd.isEnforceInitMethod()) {
throw new BeanDefinitionValidationException("Could not find an init method named '" +
initMethodName + "' on bean with name '" + beanName + "'");
}
else {
if (logger.isTraceEnabled()) {
logger.trace("No default init method named '" + initMethodName +
"' found on bean with name '" + beanName + "'");
}
// Ignore non-existent default lifecycle methods.
return;
}
}
if (logger.isTraceEnabled()) {
logger.trace("Invoking init method '" + initMethodName + "' on bean with name '" + beanName + "'");
}
// 将initMethod转换成从接口层面获取的 method
Method methodToInvoke = ClassUtils.getInterfaceMethodIfPossible(initMethod);
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
ReflectionUtils.makeAccessible(methodToInvoke);
return null;
});
try {
AccessController.doPrivileged((PrivilegedExceptionAction<Object>)
() -> methodToInvoke.invoke(bean), getAccessControlContext());
}
catch (PrivilegedActionException pae) {
InvocationTargetException ex = (InvocationTargetException) pae.getException();
throw ex.getTargetException();
}
}
/** 这里才是我们主要关心的路线 **/
else {
try {
/** 将方法设置为可以访问的, 通过反射以当前 bean的调度来去调用 Init-method方法,完成 bean的初始化 **/
ReflectionUtils.makeAccessible(methodToInvoke);
methodToInvoke.invoke(bean);
}
catch (InvocationTargetException ex) {
throw ex.getTargetException();
}
}
}
applyBeanPostProcessorsAfterInitialization
@Override
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
/**
* 在此处来执行后置处理器的一系列增强
* Spring获取 bean的规则中又这么一条:
* 需要去保证所有 bean在初始化之后都会去调用 注册的 BeanPostProcessor的 postProcessAfterInitialization方法来进行处理
* 在实际的业务场景中标根据此特性来设计自己的业务逻辑
*/
for (BeanPostProcessor processor : getBeanPostProcessors()) {
/** 调用初始化完之后的后置处理器的 **/
Object current = processor.postProcessAfterInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}
postProcessAfterInitialization
/**
* bean初始化结束后会去 调用
*/
@Nullable
default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
return bean;
}