解决启动SpringBoot项目加载 @Value注解报异常问题

2023-02-24 08:57:54

在开发的过程中很多时候我们需要用到公共配置组件,@Value注解就是开发中常用到的工具,但是该注解使用不当很容易出现错误,查阅资料后总结了以下几种解决方案。


1、使用场景及异常错误

最近在做项目中需要用到文件上传,我采用的是七牛云对象存储管理平台,就是将本地文件上传到云端存储及管理,这个时候就需要一些从远程配置管理中心获取公共配置参数的场景。

在编写文件上传下载服务业务逻辑实现类的时候,启动项目报出了如下异常:
在这里插入图片描述
看下业务逻辑实现类:

import com.cloudflashpay.common.domain.BusinessException;
import com.cloudflashpay.common.domain.CommonErrorCode;
import com.cloudflashpay.common.util.QiniuUtils;
import com.cloudflashpay.merchant.service.FileService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

/**
 * @author: 一宿君
 * @date: 2022-03-23 16:47:25
 * @description: 文件上传下载服务
 */
@Service
@Slf4j
public class FileServiceImpl implements FileService {

    @Value("${oss.qiniu.url}")
    private String qiniuUrl;

    @Value("${oss.qiniu.accessKey}")
    private String accessKey;

    @Value("${oss.qiniu.secretKey}")
    private String secretKey;

    @Value("${oss.qiniu.bucket}")
    private String bucket;

    /**
     * 上传文件
     * @param bytes 文件字节
     * @param fileName 文件名称
     * @return 文件下载访问路径地址
     * @throws BusinessException
     */
    @Override
    public String upload(byte[] bytes, String fileName) throws BusinessException {

        try {
            //调用上传文件到七牛云工具类方法
            QiniuUtils.uploadFileQiniu(accessKey,secretKey,bucket,bytes,fileName);
        }catch (RuntimeException e){
            e.printStackTrace();
            log.error("上传文件到七牛云异常:{}",e.getMessage());
            throw new BusinessException(CommonErrorCode.E_100106);
        }
        //上传成功后,将文件的下载访问地址返回给前端(绝对路径)
        return qiniuUrl+fileName;
    }
}

出现上述异常错误是因为在启动SpringBoot项目的时候会预先检索@Value注解对应的配置参数值,如果该注解对应的配置参数key没有取到值,就会报错无效异常!

2、解决方法

2.1、@Value注解后面加上默认值

	@Value("${oss.qiniu.url: default_value}")
    private String qiniuUrl;

    @Value("${oss.qiniu.accessKey: default_value}")
    private String accessKey;

    @Value("${oss.qiniu.secretKey: default_value}")
    private String secretKey;

    @Value("${oss.qiniu.bucket: default_value}")
    private String bucket;

注解后面加上默认值,如果@Value注解在加载的过程中没有取到值,或者说${key}不存在,则会默认采用这个default_value,这样就可以避免在启动项目的时候报错中断,便于后续排查。

2.2、在 Application启动类中设置PropertySourcesPlaceholderConfigurer类的默认属性

	// 设置开启忽略@Value注解取不到值时不报错
    @Bean
    public static PropertySourcesPlaceholderConfigurer placeholderConfigurer(){
        PropertySourcesPlaceholderConfigurer configurer = new PropertySourcesPlaceholderConfigurer();
        configurer.setIgnoreUnresolvablePlaceholders(true);
        return configurer;
    }

这种方法虽然可以解决启动项目时避免报错,但是不推荐使用。

2.3、将配置文件名称由application.yml修改为bootstap.yml

这个也是最容易忽略的,SprintBoot项目在启动的过程中,会采用优先加载的机制加载配置文件。若application.ymlbootStrap.yml在同一目录下,则bootStrap.yml的加载顺序要高于application.yml,如果当前配置文件名称为application.yml,即使配置文件中存在所使用的属性key,使用@Value注解也会报错,因为在启动项目时@Value只能检索到优先及最高的配置文件,也就是bootStrap.yml

原理:

  • bootstrap.yml用于应用程序上下文的引导阶段,由父Spring ApplicationContext加载。bootstrap.yml 可以理解成系统级别的一些参数配置,这些参数一般是不会变动的。
  • application.yml可以用来定义应用级别的,如果搭配 spring-cloud-config 使用 application.yml 里面定义的文件可以实现动态替换。

一起学编程,让生活更随和!如果你觉得是个同道中人,欢迎关注博主公众号:【随和的皮蛋桑】。专注于Java基础、进阶、面试以及计算机基础知识分享🐳。偶尔认知思考、日常水文🐌。


  • 作者:一宿君
  • 原文链接:https://blog.csdn.net/qq_52596258/article/details/123694592
    更新时间:2023-02-24 08:57:54