SpringBoot扩展功能之InitializingBean接口
InitializingBean接口作用
实现InitializingBean接口,我们可以实现一些个性化的bean操作。
用法
@Slf4j
@Component
public class FirstSunpyBean implements InitializingBean {
public FirstSunpyBean() {
log.info("===================> FirstSunpyBean构造方法");
}
@Override
public void afterPropertiesSet() throws Exception {
log.info("===================> afterPropertiesSet方法");
}
}
结果:
springboot执行流程图
说明:可以看到InitializingBean.afterPropertiesSet()与init-method的执行时机都是在bean后置处理器(BeanPostProcessor)的BeanPostProcessor.postProcessBeforeInitialization方法和BeanPostProcessor.postProcessAfterInitialization方法之间。
InitializingBean接口实现afterPropertiesSet方法什么时候执行
getBean方法 -> createBean方法 -> doCreateBean方法 -> initializeBean方法 -> invokeInitMethods方法
AbstractAutowireCapableBeanFactory.invokeInitMethods方法:
protected void invokeInitMethods(String beanName, Object bean, @Nullable RootBeanDefinition mbd)
throws Throwable {
// 判断bean是否实现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接口实现的方法
((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)) {
// 使用反射的方式来调用init-method指定的方法
invokeCustomInitMethod(beanName, bean, mbd);
}
}
}