javascript
Spring bean 初始化顺序
InitializingBean, init-method 和 PostConstruct
1、概述
從接口的名字上不難發(fā)現(xiàn),InitializingBean 的作用就是在 bean 初始化后執(zhí)行定制化的操作。
Spring 容器中的 Bean 是有生命周期的,Spring 允許在 Bean 在初始化完成后以及 Bean 銷毀前執(zhí)行特定的操作,常用的設(shè)定方式有以下三種:
2、InitializingBean vs init-method
接口定義如下:
public interface InitializingBean {void afterPropertiesSet() throws Exception; }接口只有一個方法afterPropertiesSet,
此方法的調(diào)用入口是負(fù)責(zé)加載 spring bean 的AbstractAutowireCapableBeanFactory,源碼如下:
從這段源碼可以得出以下結(jié)論:
3、@PostConstruct
通過 debug 和調(diào)用棧找到類InitDestroyAnnotationBeanPostProcessor, 其中的核心方法,即 @PostConstruct 方法調(diào)用的入口:
@Overridepublic Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {LifecycleMetadata metadata = findLifecycleMetadata(bean.getClass());try {metadata.invokeInitMethods(bean, beanName);}catch (InvocationTargetException ex) {throw new BeanCreationException(beanName, "Invocation of init method failed", ex.getTargetException());}catch (Throwable ex) {throw new BeanCreationException(beanName, "Failed to invoke init method", ex);}return bean;}從命名上,我們就可以得到某些信息——這是一個BeanPostProcessor。BeanPostProcessor的postProcessBeforeInitialization是在Bean生命周期中afterPropertiesSet和init-method之前被調(diào)用的。另外通過跟蹤,@PostConstruct方法的調(diào)用方式也是通過反射機制。
4、總結(jié)
同理,bean銷毀過程的順序為:@PreDestroy > DisposableBean > destroy-method
不再展開,看源碼就好
測試代碼如下:
@Slf4j public class InitSequenceBean implements InitializingBean {public InitSequenceBean() {log.info("InitSequenceBean: construct");}@Overridepublic void afterPropertiesSet() throws Exception {log.info("InitSequenceBean: afterPropertiesSet");}@PostConstructpublic void postConstruct() {log.info("InitSequenceBean: postConstruct");}public void initMethod() {log.info("InitSequenceBean: initMethod");} }@Configuration public class SystemConfig {@Bean(initMethod = "initMethod", name = "initSequenceBean")public InitSequenceBean initSequenceBean() {return new InitSequenceBean();} }@Slf4j public class InitSequenceBeanTest extends ApplicationTests {@Autowiredprivate InitSequenceBean initSequenceBean;@Testpublic void initSequenceBeanTest() {log.info("Finish: {}", initSequenceBean.toString());} }總結(jié)
以上是生活随笔為你收集整理的Spring bean 初始化顺序的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 新手化妆技巧 六个化妆技巧
- 下一篇: gradle idea java ssm