简介
这是一个Java接口,名为InitializingBean,它是Spring框架中的一个关键接口。当Spring容器完成一个bean的所有属性设置并满足其他Aware接口(如BeanFactoryAware、ApplicationContextAware等)之后,会调用该接口中的afterPropertiesSet方法。这个方法允许bean实例在所有的bean属性都被设置之后进行整体的配置验证和最终的初始化。
源码
public interface InitializingBean {
/**
* 当Spring容器完成了bean的所有属性设置后,此方法会被调用。
* 该方法允许bean执行配置验证和最终的初始化操作。
* 如果在配置过程中发现任何问题(例如,未能设置某个必需属性),或者在初始化过程中因其他原因失败,此方法可以抛出异常。
*/
void afterPropertiesSet() throws Exception;
}
Spring在设置完bean的属性之后调用此接口的方法
//org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#initializeBean
/**
* Initialize the given bean instance, applying factory callbacks
* as well as init methods and bean post processors.
* <p>Called from {@link #createBean} for traditionally defined beans,
* and from {@link #initializeBean} for existing bean instances.
* @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 bean definition that the bean was created with
* (can also be {@code null}, if given an existing bean instance)
* @return the initialized bean instance (potentially wrapped)
* @see BeanNameAware
* @see BeanClassLoaderAware
* @see BeanFactoryAware
* @see #applyBeanPostProcessorsBeforeInitialization
* @see #invokeInitMethods
* @see #applyBeanPostProcessorsAfterInitialization
* 调用顺序是先
* 1.调用spring内部的aware方法
* 2.bean的初始化前的后置处理器
* 3.bean的初始化方法调用
* 4.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 {
//调用默认的aware方法
invokeAwareMethods(beanName, bean);
}
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
//初始化前 BeanPostProcessor 后置处理器 before方法
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
// TODO 调用初始化方法,InitializingBean中的初始化方法或者BeanDefinition中设置的初始化方法
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()) {
//初始化后 BeanPostProcessor 后置处理器 after方法
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
/**
* 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
* 这个是spring的初始化方法,其实就是调用bean的初始化方法,这个方法的初始化方法有两个地方,
* 第一个是实现了InitializingBean的初始化方法
* 第二个是在BeanDefinition中设置了initMethod方法,而已可以在这里调用
*/
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类中的初始化的方法
((InitializingBean) bean).afterPropertiesSet();
}
}
/**
* 下面是调用BeanDefinition中设置的initMethod方法,也是初始化方法
*/
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);
}
}
}
示例
import org.springframework.beans.factory.InitializingBean;
public class MyBean implements InitializingBean {
private String someProperty;
public void setSomeProperty(String someProperty) {
this.someProperty = someProperty;
}
@Override
public void afterPropertiesSet() throws Exception {
// 在这里执行初始化或验证操作
if (someProperty == null || someProperty.isEmpty()) {
throw new IllegalArgumentException("someProperty cannot be null or empty");
}
// 其他初始化代码...
}
}
在这个例子中,MyBean实现了InitializingBean接口,并在afterPropertiesSet方法中进行了属性someProperty的非空验证。如果someProperty为空,则抛出一个异常。