工具类封装之静态方法使用 JavaBean

2,075 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 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 对象问题提供了几种方法和思路,供大家参考使用,希望能够带来一点点帮助,也希望大家多多批评和指正。多交流共进步!