Spring Bean 的初始化和销毁的几种方式,你一般用的是哪种?

开发 前端
今天了不起给大家介绍了一下 Spring 的三种初始化和三种销毁对象的方式,并且通过示例案例给大家介绍了一下优先级,希望对大家有帮助。

作为一个 Java​ 程序员 Spring​ 框架在我们日常工作和面试中可谓必不可少,学习和掌握好 Spring 对我们来说是很有必要的。

今天了不起就给大家介绍一下 Spring​ 的 Bean 的初始化和销毁的几种方式,看看你平时用的都是哪种。

初始化

由于 Spring Bean​ 的初始化都是 Spring 容器帮我们处理的,我们这里说的初始化是指在容器帮我们初始化的过程,我们有哪些方式可以进行手动干预,或者说初始化的时候如何运行我们自己的逻辑。

废话不多说,我们依次来看下面的几种方式

实现 InitializingBean 接口

我们可以写一个类,然后实现 InitializingBean​ 接口,通过覆盖其中的 afterPropertiesSet()​ 方法来实现我们自己的逻辑,我们写一个 case 来实现一下,如下所示

package com.example.demo.service;

import org.springframework.beans.factory.InitializingBean;

public class InitServiceImpl implements InitializingBean {
private String name;
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("afterPropertiesSet...");
this.name = "Java极客技术 afterPropertiesSet";
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}
}

实现的方式很简单,直接实现 org.springframework.beans.factory.InitializingBean​ 这个接口然后覆盖 afterPropertiesSet 这个方法即可,在这个方法里面,我们就可以执行我们需要在初始化时候就执行的代码。

比如这里我们在初始化方法里面直接给一个属性进行赋值,后续就可以直接使用了,如下所示

package com.example.demo.controller;

@RestController
public class HelloController {

@Autowired
InitServiceImpl initService;

@GetMapping(value = "/hello")
public String hello(@RequestParam String name) {
return initService.getName();
}
}

图片

可以看到是可以直接获取到属性值的,这个比较简单我们就不赘述了,继续看下面两个方式。

增加 @PostConstruct 注解

我们继续在 InitServiceImpl​ 类中增加一个方法,并且在方法上面增加 @PostConstruct 注解,如下所示

@PostConstruct
public void postConstruct() {
System.out.println("postConstruct...");
this.name = "Java极客技术 postConstruct";
}

这种写法比实现一个接口要简单一点,毕竟只要增加一个注解就行了,而不需要覆盖接口的方法,不过本质上没什么区别。

自定义 init 方法

这种方式也很简单,只不过我们做两个动作,第一个是在 InitServiceImpl 

public void initMethod() {
System.out.println("initMethod...");
this.name = "Java极客技术 initMethod";
}

然后再写一个配置类,在配置类中定义一个方法,在方法上面增加一个 @Bean​ 注解,并且赋值一个 init-method 方法,同时这个方法需要创建对象并返回,如下所示

package com.example.demo.service;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class Config {

@Bean(initMethod = "initMethod")
public InitServiceImpl initServiceImpl() {
return new InitServiceImpl();
}
}

怎么样是不是也很简单。

小结

在这里问大家一个问题,如果我们在同一个类中同时存在这三种初始化方法,那会是什么情况呢?

我们来试一下就知道了,通过完整的代码,我们将三种方式都写进来,然后启动服务。

package com.example.demo.service;

import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;

import javax.annotation.PostConstruct;

public class InitServiceImpl implements InitializingBean {
private String name;

@Override
public void afterPropertiesSet() throws Exception {
System.out.println("afterPropertiesSet...");
this.name = "Java极客技术 afterPropertiesSet";
}

@PostConstruct
public void postConstruct() {
System.out.println("postConstruct...");
this.name = "Java极客技术 postConstruct";
}

public void initMethod() {
System.out.println("initMethod...");
this.name = "Java极客技术 initMethod";
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}
}

可以看到,我们的服务是正常的启动和运行,并且三个方法都正常的执行了,执行的顺序依次是 postConstruct,afterPropertiesSet,initMethod​,那么这里问一下小伙伴们,此时我们的 name 值是什么呢?

图片

销毁

既然我们初始化有三种形式,可以很自然的想到销毁是不是也有三种形式呢?没错,销毁的三种方法,也是跟上面类似,分别是

  1. 实现 org.springframework.beans.factory.DisposableBean​ 接口,覆盖 destroy() 方法;
  2. 自定义一个方法,在方法上面增加 @PreDestroy 注解;
  3. 在 InitServiceImpl​  中增加一个自定义销毁方法,然后在配置类中增加 Bean​ 的 destoryMethod;

相关的内容也比较简单,在上面的 InitServiceImpl​ 和 Config 基础上只要增加一点点内容就好了

public class InitServiceImpl implements InitializingBean, DisposableBean {

public void destroyMethod() throws Exception {
System.out.println("destroyMethod...");
}

@Override
public void destroy() throws Exception {
System.out.println("destroy...");
}

@PreDestroy
public void preDestroy() throws Exception {
System.out.println("preDestroy...");
}
}

@Bean(initMethod = "initMethod", destroyMethod = "destroyMethod")
public InitServiceImpl initServiceImpl() {
return new InitServiceImpl();

}

销毁的三个方法在执行的时候也是有优先级的,依次是 preDestroy,destroy,destroyMethod。

至此完整的一个包含三个初始化和三个销毁方法的代码就完成了,我们来运行一下看看整体的流程。

图片

总结

虽然说 Spring 给我们提供了三种初始化和三种销毁的方法,不过我们在日常的写代码中很少会把三种都写上,但是对于这几种的优先级还是有必要了解的,万一别人给你挖坑了怎么办呢?

好了,今天了不起给大家介绍了一下 Spring 的三种初始化和三种销毁对象的方式,并且通过示例案例给大家介绍了一下优先级,希望对大家有帮助。

责任编辑:武晓燕 来源: Java极客技术
相关推荐

2022-11-14 07:33:57

Java场景value

2023-12-01 10:20:00

SpringBean参数机制

2024-10-29 11:27:27

2021-06-26 16:14:11

虚拟机注册钩子

2024-07-31 11:26:05

反射BeanXML

2022-03-16 11:11:37

SpringBean项目

2023-11-12 23:08:17

C++初始化

2013-01-20 21:55:24

移动策略

2009-07-20 15:08:41

Spring实例化Be

2013-03-04 11:10:03

JavaJVM

2012-02-28 10:04:09

Java

2015-11-11 16:36:23

CA Technolo

2021-01-26 09:14:19

Linux内核模块

2021-05-07 16:19:36

异步编程Java线程

2023-09-08 07:23:52

2020-06-09 08:09:07

机器学习统计学习无监督学习

2009-08-26 18:28:44

C#数组

2011-03-16 10:52:20

2022-10-27 07:33:36

序列化协议Protobuf

2020-04-08 15:59:23

显卡Linux命令
点赞
收藏

51CTO技术栈公众号