很多时候,我们在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初始化的神秘面纱。