在spring中PostConstruct、InitializingBean和init-method执行顺序是什么样的?

很多时候,我们在spring实例化bean之前,需要做一些准备工作,比如读取资源文件,创建其他的对象等。这些准备工作,往往写在初始化方法中,那么spring目前支持哪些初始化方法呢?

1.配置init-method参数

/**

* 配置 init-method

*

* @author sue

* @date 2020/5/17 11:46

*/

@Slf4j

@Service

public class InitMethodService {

public void initMethod() {

log.info("======= init-method======");

}

public void doSameThing() {

log.info("=====doSameThing==== ");

}

}

在applicationContext.xml文件中配置bean

<bean id="initMethodService" class="com.sue.jump.init.InitMethodService"

init-method="initMethod">

</bean>

测试类如下:

/**

* 测试初始化方法

*

* @author sue

* @date 2020/5/17 11:59

*/

public class InitMethodTest {

@Test

public void testInitMethod() {

ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");

InitMethodService initMethodService = (InitMethodService) (applicationContext.getBean("initMethodService"));

initMethodService.doSameThing();

}

}

最后执行结果:

======= init-method======

=====doSameThing====

2.实现InitializingBean接口,重写afterPropertiesSet方法

/**

* 实现InitializingBean接口

*

* @author sue

* @date 2020/5/17 11:46

*/

@Slf4j

@Service

public class InitializingBeanService implements InitializingBean {

@Override

public void afterPropertiesSet() throws Exception {

log.info("======InitializingBean init ====== ");

}

public void doSameThing() {

log.info("=====doSameThing==== ");

}

}

在applicationContext.xml文件中配置bean

<bean id="initializingBeanService" class="com.sue.jump.init.InitializingBeanService">

</bean>

测试类如下:

/**

* 测试初始化方法

*

* @author sue

* @date 2020/5/17 11:59

*/

public class InitMethodTest {

@Test

public void testInitMethod() {

ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");

InitMethodService initMethodService = (InitMethodService) (applicationContext.getBean("initMethodService"));

initMethodService.doSameThing();

}

}

最后执行结果:

======InitializingBean init ======

=====doSameThing====

3.在方法上加@PostConstruct注解

/**

* 在方法上打 PostConstruct 注解

*

* @author sue

* @date 2020/5/17 11:46

*/

@Slf4j

@Service

public class PostConstructService {

@PostConstruct

public void init() {

log.info("==== PostConstruct init ======");

}

public void doSameThing() {

log.info("=====doSameThing==== ");

}

}

在applicationContext.xml文件中配置bean

<bean id="postConstructService" class="com.sue.jump.init.PostConstructService">

</bean>

并且配置

<context:annotation-config/>

测试类如下:

/**

* 测试初始化方法

*

* @author sue

* @date 2020/5/17 11:59

*/

public class PostConstructTest {

@Test

public void testPostConstruct() {

ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");

PostConstructService postConstructService = (PostConstructService) (applicationContext.getBean("postConstructService"));

postConstructService.doSameThing();

}

}

最后执行结果:

==== PostConstruct init ======

=====doSameThing====

接下来,你有可能会问,既然有三种初始化方法,那么它们的执行先后顺序是怎么样的?

/**

* 实现InitializingBean接口

*

* @author sue

* @date 2020/5/17 11:46

*/

@Slf4j

@Service

public class InitService implements InitializingBean {

public void initMethod() {

log.info("======= init-method======");

}

@PostConstruct

public void init() {

log.info("==== PostConstruct init ======");

}

@Override

public void afterPropertiesSet() throws Exception {

log.info("======InitializingBean init ====== ");

}

public void doSameThing() {

log.info("=====doSameThing==== ");

}

}

在applicationContext.xml文件中配置bean

<bean id="initService" class="com.sue.jump.init.InitService" init-method="initMethod">

</bean>

并且配置:<context:annotation-config/>

测试类如下:

/**

* 测试初始化方法

*

* @author sue

* @date 2020/5/17 11:59

*/

public class InitTest {

@Test

public void testInit() {

ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");

InitService initService = (InitService) (applicationContext.getBean("initService"));

initService.doSameThing();

}

}

最后执行结果:

==== PostConstruct init ======

======InitializingBean init ======

======= init-method======

=====doSameThing====

顺便提一句,如果在方法上使用PostConstruct时,没有在applicationContext.xml中配置<context:annotation-config/>,则该注解不会生效。

接下来,总结一下 spring中初始化方法的执行顺序如下:

PostConstruct > InitializingBean > init-method

此外,你会不会有这样的疑问:spring为啥要提供三种初始化的方式呢?

在我看来,spring最初的时候只支持xml配置bean,所以刚开始只有init-method方法。

随着spring的发展,允许使用注解的方式创建bean,这时候可以通过实现InitializingBean接口的方式来初始化。

然后spring处于多方面考虑,也支持java的原始注解PostConstruct,该注解其实是在javax.annotation包下面,以后如果用户不使用spring框架,换成其他的框架比如:jfinal,也不需要该代码。

最后,如果大家想了解spring是如何实现调用初始化方法,以及三种初始化方法为啥是PostConstruct > InitializingBean > init-method的顺序,

敬请关注下一篇文章,将从spring源码的角度,一层层揭开spring初始化的神秘面纱。

 

猜你喜欢

转载自blog.csdn.net/lisu061714112/article/details/106749735