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方法");
    }
}

结果:

image

springboot执行流程图

image

说明:可以看到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);
		}
	}
}
posted @ 2023-06-05 22:24  sunpeiyu  阅读(317)  评论(0编辑  收藏  举报