You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java Spring Boot:无@Service普通类如何访问application.properties配置值

普通类读取Spring Boot配置值的实现方案

空值问题的核心原因

@Value 注解的注入逻辑完全由Spring容器托管执行,只要类的实例不是Spring创建、也没有经过Spring的上下文处理流程,所有类内写的@Value、@Autowired这类Spring注解都不会生效,字段自然会返回null。
你之前在普通类里加@Value读不到值,本质是因为这个AppUtils实例根本没走Spring的处理链路,和配置文件写的对不对没有关系。

具体可行方案

方案1:手动触发Spring对普通类实例的注入(侵入性最低)

不需要改写原有AppUtils的类定义,只需要在Spring容器启动后,把你创建的普通类实例交给Spring完成字段注入即可。
首先保留你原来写的AppUtils类逻辑:

public class AppUtils {
    @Value("${cloud.aws.endpointUrl}")
    private String endpointUrl;

    public String getEndpointUrl() {
        return endpointUrl;
    }
}

然后新增一个受Spring管理的初始化组件,在容器启动时完成对普通类的注入处理:

@Component
public class AppUtilsContextInjector implements ApplicationContextAware {
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) {
        // 1. 如果你已经在业务代码里手动创建过AppUtils实例,直接传入该实例即可,不需要重复new
        AppUtils appUtils = new AppUtils();
        // 2. 调用Spring的能力,对传入的实例执行@Value、@Autowired等字段的注入逻辑
        applicationContext.getAutowireCapableBeanFactory().autowireBean(appUtils);
        // 3. 将处理完成的实例存到全局静态持有类,业务代码随时可以取用
        AppUtilsHolder.setInstance(appUtils);
    }
}

配套的简单全局持有类代码:

public class AppUtilsHolder {
    private static AppUtils INSTANCE;
    public static void setInstance(AppUtils instance) {
        INSTANCE = instance;
    }
    public static AppUtils getInstance() {
        return INSTANCE;
    }
}

这种方案兼容你已经写好的普通类代码,不管是手动new的实例,还是第三方框架创建的实例,只要传入Spring的autowire方法走一遍流程,@Value字段就会被正常赋值,不会出现null的问题。

方案2:自定义静态配置读取工具(适配脱离Spring注解的场景)

如果你不想在普通类里写任何Spring注解,可以写一个受Spring管理的组件,把配置值暴露为静态方法供全局调用。

@Component
public class StaticConfigProvider implements EnvironmentAware {
    // 静态持有Spring的Environment对象
    private static Environment environment;

    @Override
    public void setEnvironment(Environment environment) {
        StaticConfigProvider.environment = environment;
    }

    // 对外提供通用的配置读取能力,传入配置key即可获取对应值
    public static String getProperty(String key) {
        return environment.getProperty(key);
    }

    // 可以针对常用配置封装固定方法,避免硬编码key
    public static String getAwsEndpointUrl() {
        return environment.getProperty("cloud.aws.endpointUrl");
    }
}

之后在任何普通类里,不需要加任何注解,直接调用静态方法就能拿到配置值:

public class AppUtils {
    private String endpointUrl = StaticConfigProvider.getAwsEndpointUrl();
}

这种方式灵活性最高,哪怕在main方法、第三方框架的回调逻辑里,只要Spring容器已经启动完成,就能正常读取到配置值。

方案3:将普通类注册为Spring托管Bean(最符合开发规范)

如果这个工具类没有必须手动new的强需求,最简洁的做法就是把类交给Spring容器管理:

  • 对无状态的工具类,直接加上@Component注解,将其注册为Spring Bean,类内原有的@Value逻辑就会正常生效
  • 如果需要自定义实例的创建逻辑,可以在Spring配置类里写@Bean方法,手动将AppUtils实例注册到容器,同样能触发@Value的注入流程

注意:哪怕给类加了Spring注解,如果你后续手动new了一个新的AppUtils实例,这个手动创建的实例里的@Value字段依然会是null——注入逻辑只对Spring容器创建的那个Bean实例生效,和类上加了什么注解没有关系。

常见踩坑提醒

  • 不要尝试在普通类的static静态字段上使用@Value,哪怕类已经被Spring托管,静态字段的注入时机和实例字段绑定的流程不兼容,大概率还是会拿到null
  • 所有依赖Spring注入能力的代码,必须等Spring容器完全启动完成后再执行,否则拿到的配置值依然是null

内容的提问来源于stack exchange,提问作者Kishan Solanki

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.26 02:45:02