当前位置:   article > 正文

SpringBoot优雅的调用工具类并在工具类中获取自动注入的bean或属性

SpringBoot优雅的调用工具类并在工具类中获取自动注入的bean或属性

通常,我们在写工具类时,会将其所属方法,属性规定为 static 类型的,方便调用,

如下:

  1. // 调用
  2. FileUtil.getFiles();
  3. public class FileUtil {
  4. private static String FILE_PATH = "D:\\files";
  5. public static String getFiles() {
  6. return FILE_PATH;
  7. }
  8. }

通过 FileUtil.getFiles(); 可以直接调用静态方法,不必获取 FileUtil 对象实例,或使用@Autowired自动注入。

但是,当工具类本身需要使用spring注入对象实例或者需要从配置文件获取属性值时,这时候

在使用静态方法往往就会存在一些限制。

如下:

使用spring注入对象实例

  1. // 调用会报空指针错误
  2. FileUtil.getFiles();
  3. @Component
  4. public class FileUtil {
  5. private static String FILE_PATH = "D:\\files";
  6. @Autowired
  7. private static SysFileService service;
  8. public static String getFiles() {
  9. return service.download(FILE_PATH);
  10. }
  11. }

从配置文件获取属性值

  1. // 调用结果为null
  2. FileUtil.getFiles();
  3. // 以下两种写法均无法正常从配置文件获取值
  4. @Component
  5. public class FileUtil {
  6. @Value("${files.filePath}")
  7. private static String FILE_PATH;
  8. public static String getFiles() {
  9. return FILE_PATH;
  10. }
  11. }
  12. // 或
  13. @Component
  14. @ConfigurationProperties(prefix = "files")
  15. public class FileUtil {
  16. private static String FILE_PATH;
  17. public static String getFiles() {
  18. return FILE_PATH;
  19. }
  20. }

上述代码,无法正常获取值,这是因为 FILE_PATH 变量不能是静态变量(因为@Value和@ConfigurationProperties注解不能赋值到静态变量上,虽然也可以通过一些方法成功赋值静态变量,但这里不做详述), 如果把 static 修饰词去掉,则可以正常获取,但这样一来,由于 FILE_PATH 不是静态变量,也就无法在静态方法中使用了!

以上,是存在的问题,接下来,讲讲如何优雅的来解决问题。

使用spring注入对象实例

  1. // 调用正常
  2. FileUtil.getFiles();
  3. @Component
  4. public class FileUtil {
  5. private static String FILE_PATH = "D:\\files";
  6. private static FileUtil instance;
  7. @Autowired
  8. private SysFileService service;
  9. @PostConstruct
  10. public void init() {
  11. instance = this;
  12. }
  13. public static String getFiles() {
  14. return instance.service.download(FILE_PATH);
  15. }
  16. }

使用了@PostConstruct来完成对应bean的获取。

原理:@PostConstruct注解被用来修饰一个非静态void方法。该注解方法在整个Bean初始化中的执行顺序:

Constructor(构造方法) -> @Autowired(依赖注入) -> @PostConstruct(注释的方法)

由此,在自动注入后,instance 对象被赋值为 this,即成功获得一个自动注入后的一个 FileUtil 类对象(手动赋值 instance),所以,getFiles方法中使用 instance 对象时就不会是一个 null 值。

从配置文件获取属性值

  1. // 调用正常
  2. FileUtil.getFiles();
  3. public class FileUtils {
  4. private static final String FILE_PATH;
  5. static {
  6. File file = File.getInstance();
  7. FILE_PATH = file.FILE_PATH;
  8. }
  9. public static String getFiles() {
  10. return FILE_PATH;
  11. }
  12. @Component
  13. @ConfigurationProperties("files")
  14. public static class File {
  15. private String FILE_PATH;
  16. public static File getInstance() {
  17. return ApplicationContextUtil.getBean(File.class);
  18. }
  19. }
  20. }

这里使用了上下文和静态代码块来完成对应bean的获取。

简单讲下原理:上下文可以让我们自己获取需要的bean实例,静态代码块会在类初始化的时候执行且仅执行一次(静态代码块是最优先被执行的,在类构造器执行之前)。

先使用 File 静态内部类(可以简单看作一个普通类)来正常获取配置文件的值! 其中 getInstance方法的 ApplicationContextUtil.getBean 方法实现了 ApplicationContextAware 接口,用来获取 File bean 本身,然后在 FileUtil 类的静态代码块中调用 File.getInstance() 获取实例。就可以成功赋值 FILE_PATH 了。

后记:

推荐使用该方法!

构造器注入

  1. // 调用正常
  2. FileUtil.getFiles();
  3. @Component
  4. public class FileUtil {
  5. private static String FILE_PATH = "D:\\files";
  6. private static SysFileService service;
  7. public FileUtilss(SysFileService service) {
  8. FileUtil.service = service;
  9. }
  10. public static String getFiles() {
  11. return service.download(FILE_PATH);
  12. }
  13. }

以上,我们解决了如何在工具类中优雅的使用Spring(依赖注入)获取bean或属性,并且可以使用静态方法来实现具体的功能!

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/盐析白兔/article/detail/151896
推荐阅读
相关标签
  

闽ICP备14008679号