本文主要介绍三个初始化的方式,分别是@PostConstruct,InitializingBean,以及SmartInitializingSingleton这三个,咱们直接三个一块儿用,来看看代码哈。app
@Component
public class TestP implements InitializingBean, SmartInitializingSingleton {
@PostConstruct
public void test() {
System.out.println("@PostConstruct");
}
@Override
public void afterPropertiesSet() throws Exception {
// InitializingBean 的方法
System.out.println("afterPropertiesSet");
}
@Override
public void afterSingletonsInstantiated() {
// SmartInitializingSingleton 的方法
System.out.println("afterSingletonsInstantiated");
}
}
复制代码
代码很简单,咱们来看看容器启动后的结果:ide
调用初始化的代码位于AbstractAutowireCapableBeanFactory中的initializeBean方法中post
protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {
// 调用几个Aware接口
if (System.getSecurityManager() != null) {
AccessController.doPrivileged(new PrivilegedAction<Object>() {
@Override
public Object run() {
invokeAwareMethods(beanName, bean);
return null;
}
}, getAccessControlContext());
}
else {
invokeAwareMethods(beanName, bean);
}
// 调用全部的BeanPostProcessor的postProcessBeforeInitialization
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
// 调用InitializingBean的方法和自定义初始化方法
invokeInitMethods(beanName, wrappedBean, mbd);
}catch (Throwable ex) {
throw new BeanCreationException(
(mbd != null ? mbd.getResourceDescription() : null),
beanName, "Invocation of init method failed", ex);
}
// 执行全部BeanPostProcessor的postProcessAfterInitialization方法
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
复制代码
在这个方法中,咱们很明显的能够看到,InitializingBean的执行位置,那么@PostConstruct是在哪里执行的呢?通过debug,咱们能够发现它是在调用全部的BeanPostProcessor的postProcessBeforeInitialization的时候被执行的(CommonAnnotationBeanPostProcessor中)。而后SmartInitializingSingleton这个东西须要先说一下,Spring4.0的时候是没有这个东西的,这个是4.1以后加入进来的,这个也能够用来作初始化以后的一些操做,那么它又是何时被执行的呢?咱们能够在DefaultListableBeanFactory中的preInstantiateSingletons中最后几行中发现:ui
而这个时候,全部的Bean都已经被初始化了。因此咱们在这里作一个小小的总结:这三个初始化的方法,执行前后顺序是@PostConstruct,而后是InitializingBean,最后是SmartInitializingSingleton。举个使用上的小例子,若是A bean要依赖B bean初始化产生的数据的话,那么就可让A来实现SmartInitializingSingleton,B来实现InitializingBean或者使用@PostConstruct,InitializingBean和@PostConstruct这两个初始化的方式在绝大多数状况下都没什么差异。另外须要注意的是这三个初始化的方法,都不要和以前的BeanFactoryPostProcessor以及BeanPostProcessor一块儿用,由于是在容器不一样阶段来作的事情,好比我举一个例子:spa
@Component
public class AProcessor implements BeanPostProcessor, PriorityOrdered {
@PostConstruct
public void test() {
System.out.println("AProcessor @PostConstruct");
}
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("aa");
return null;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("bb");
return null;
}
@Override
public int getOrder() {
return 0;
}
}
复制代码
这个类实现了BeanPostProcessor 和PriorityOrdered 这两个接口,而后咱们启动以后发现@PostConstruct里面的东西并无被执行,这个缘由是由于这个类初始化的时候用做执行@PostConstruct的BeanPostProcessor 尚未被初始化,因此固然没法执行喽,这只不过是我随随便便就想到的一个,还有可能又其余坑的,因此说尽量分开用。debug
写文章不易,尤为完了要对一个庞大的东西作总结更为不易,因此你的赞对我很重要,求点个赞🥺~code