干货分享 | 如果你不知道spring中的这些初始化方法,你就out了

小豆丁 9月前 ⋅ 310 阅读

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

1.配置init-method参数


@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>

测试类如下:


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方法


@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>

测试类如下:


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注解


@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/>

测试类如下:


public class PostConstructTest {

    @Test

    public void testPostConstruct() {

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

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

        postConstructService.doSameThing();

     }

}

最后执行结果:

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

=====doSameThing====

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


@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/>

测试类如下:


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初始化的神秘面纱。


全部评论: 0

    我有话说: