• 字节面试题

InitializingBean和BeanPostProcess都是Spring提供的接口

区别:

1、BeanPostProcess先于InitializingBean执行
2、InitializingBean是在对象已经实例化之后,执行接口的afterPropertiesSet()方法;
BeanPostProcess是在bean构建的过程中,此时对象已经执行了构造方法,随后执行before/after方法,postProcessBeforeInitialization,postProcessAfterInitialization
注意:每个bean在构建的过程中,Spring都会遍历所有的BeanPostProcessor的实现类,调用实现类中的方法,入参为构建好的bean
3、自己实现BeanPostProcess接口时,如果想生效,还需将实现类构建成SpringBean
即需要用@Component注解 等方法

执行顺序

类构造方法 - postProcessBeforeInitialization - @PostConstruct注解的方法 - InitializingBean的afterPropertiesSet()方法- XML中定义的bean init-method方法 - postProcessAfterInitialization

测试代码如下:

  1. @Component
  2. public class TestInitOrder implements InitializingBean {
  3. public TestInitOrder() {
  4. System.out.println("TestInitOrder construct");
  5. }
  6. @PostConstruct
  7. public void testPostConstruct() {
  8. System.out.println("testPostConstruct");
  9. }
  10. @Override
  11. public void afterPropertiesSet() throws Exception {
  12. System.out.println("afterPropertiesSet");
  13. }
  14. }
  15. @Component
  16. public class TestBeanPostProcessor implements BeanPostProcessor {
  17. @Override
  18. public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
  19. if (beanName.contains("testInitOrder")) {
  20. System.out.println("TestInitOrder postProcessBeforeInitialization");
  21. }
  22. return bean;
  23. }
  24. @Override
  25. public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
  26. if (beanName.contains("testInitOrder")) {
  27. System.out.println("TestInitOrder postProcessAfterInitialization");
  28. }
  29. return bean;
  30. }
  31. }

输出结果:
image.png

调用链路

BeanPostProcess接口调用链路如下:
image.png
image.png

自己创建BeanPostProcessor实现类
image.png

InitializingBean接口调用链路如下:
image.png
由调用链路看出,执行的方法先后顺序

附加:Lifecycle实现类调用顺序
image.png