持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第5天,点击查看活动详情
1. 工具类封装
SpringBoot 内置了 RestTemplate 对象用来进行 HTTP 请求,当项目中需要进行 HTTP 请求的位置较多时,就需要考虑封装专门的工具类来进行调用,而不需要每次使用时都注入 RestTemplate。
值得一提的是,RestTemplate 作为内置对象已经加入 Spring 容器,注入时需要使用对象属性接收,不能赋值给静态变量,这样就导致工具类中的静态方法无法直接使用,今天就来学习一下如何将容器中对象赋值到静态变量中进行使用。
2. 静态变量接收 JavaBean
2.1 定义静态变量并初始化
该方法不从容器中获取 bean 对象,而是手动初始化,因此不会使用到 RestTemplate 的相关配置,初始化时使用默认配置。
public class RestTemplateUtil{
private static RestTemplate restTemplate = new RestTemplate();
}
此种方法简单创建并使用 RestTemplate 是可以的,但是正式使用中需要对 RestTemplate 进行自定义配置,而使用 new 创建无法应用配置信息。
2.2 构造器或 setter 方法注入静态属性
属性注入无法直接注入到静态变量,SpringBoot 中还提供了另外两种注入方法,可以利用构造器注入和 setter 方法注入来实现 JavaBean 赋值到静态变量中。
注入的时候可以选择使用 @Autowired 或 @Resource 注解,分别是以类型或名称注入
// 构造器注入
@Component
public class RestTemplateUtil{
private static RestTemplate restTemplate;
@Autowired
public RestTemplateUtil(RestTemplate restTemplate){
RestTemplateUtil.restTemplate = restTemplate;
}
}
// setter 方法注入
@Component
public class RestTemplateUtil{
private static RestTemplate restTemplate;
@Resource
public setRestTemplate(RestTemplate restTemplate){
RestTemplateUtil.restTemplate = restTemplate;
}
}
构造器注入或 setter 方法将变量注入到静态属性中的方式比较推荐使用,但是使用时一定要保证当前工具类交由容器管理,即使用 @Component 注解。
2.3 使用 @PostContract 注解实现
除此之外,还可以使用 @PostContract 注解来在容器管理的对象创建后,立即执行对应的方法来实现静态变量赋值的逻辑。
静态方法和静态变量初始化在前,因此静态方法中不能调用非静态属性和方法,而 Spring 中静态方法的调用却是在容器加载完成之后才会进行,只需要在此之前将非静态属性内容赋值到静态属性中即可,避免静态方法调用时空指针异常。
@Component
public class RestTemplateUtil {
@Autowired
private RestTemplate restTemplate;
private static HttpUtils httpUtils;
@PostConstruct
public void init(){
// 在容器初始化对象后,将对象值赋值到静态类变量,如果手动创建则属性无法注入
httpUtils = this;
// 手动创建,不会注入属性,而属性是非静态的,无法在此手动赋值,
// 此时 httpUtils.restTemplate 为 null,报错空指针异常
// HttpUtils httpUtils = new HttpUtils();
}
// 其他静态方法中可以直接使用 httpUtils.restTemplate 进行操作
}
在spring项目中,在一个bean的初始化过程中,方法执行先后顺序为:Constructor > @Autowired > @PostConstruct
因此在 @PostConstruct 注解的方法调用时, bean 已经准备好了,可以完成赋值。
2.4 使用静态工具类获取容器管理对象
还可以使用常用的静态工具类 SpringContextHolder 来获取容器中的对象并赋值给静态变量,SpringContextHolder 需要自定义实现为以静态变量保存 Spring ApplicationContext 并操作的工具类。
public class RestTemplateUtil{
// 直接获取指定的类对象赋值到静态变量中
private static RestTemplate restTemplate = SpringContextHolder.getBean(RestTemplate.class);
}
需要注意的是,SpringBoot 并没有默认实现 SpringContextHolder 工具类,而是要自定义实现并加入到容器中。
3.最后
本文对于封装工具类,定义静态方法时需要使用 Spring 容器的 Bean 对象问题提供了几种方法和思路,供大家参考使用,希望能够带来一点点帮助,也希望大家多多批评和指正。多交流共进步!