目录
- 前言
- 1. 基本知识
- 2. 高级用法
- 3. 彩蛋
前言
对于Java的基本知识推荐阅读:
- java框架 零基础从入门到精通的学习路线 附开源项目面经等(超全)
- 【Java项目】实战CRUD的功能整理(持续更新)
1. 基本知识
@Value 是 Spring 中一个非常常用的注解,主要用于将外部化配置(如 .properties
文件或 .yaml
文件中的配置)注入到 Spring 管理的 Bean 中
支持基本的类型转换和 Spring Expression Language (SpEL),使得开发者可以更加灵活地配置应用程序的参数
基本的用法如下:
确保存在 application.properties 或 application.yml 文件且其中有正确的配置
例如:
application.properties:
app.name=MyApplication
app.version=1.0.0
app.timeout=5000
或者 application.yml:
app:
name: MyApplication
version: 1.0.0
timeout: 5000
主题的输出类如下:
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
@Configuration
@ComponentScan(basePackages = "com.example.test")
@PropertySource("classpath:application.properties") // 确保加载配置文件
public class MainApp {
public static void main(String[] args) {
ApplicationContext context = new AnnotationConfigApplicationContext(MainApp.class);
ValueTest valueTest = context.getBean(ValueTest.class);
valueTest.printValues();
}
}
对应的配置文件如下:
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component
public class ValueTest {
@Value("${app.name}")
private String appName;
@Value("${app.version}")
private String appVersion;
@Value("${app.timeout}")
private int timeout;
public void printValues() {
System.out.println("App Name: " + appName);
System.out.println("App Version: " + appVersion);
System.out.println("App Timeout: " + timeout + "ms");
}
}
截图如下:
2. 高级用法
设定默认值,如果配置文件在外部文件不存在,提供默认值
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component
public class ValueTest {
@Value("${app.name:Unknown App}")
private String appName;
@Value("${app.connection.timeout:10000}")
private int connectionTimeout;
public void printValues() {
System.out.println("App Name: " + appName);
System.out.println("Connection Timeout: " + connectionTimeout + "ms");
}
}
输出如下:
枚举类:
public enum LogLevel {
DEBUG, INFO, WARN, ERROR
}
配置文件:
app.log.level=INFO
配置文件类:
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component
public class AppConfigWithEnum {
@Value("${app.log.level}")
private LogLevel logLevel;
public void printConfig() {
System.out.println("Log Level: " + logLevel);
}
}
除了直接注入到字段中,@Value 还可以用于构造函数参数和方法参数的注入
在构造函数中使用 @Value
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component
public class AppConfigConstructorInjection {
private final String appName;
private final int timeout;
public AppConfigConstructorInjection(@Value("${app.name}") String appName,
@Value("${app.timeout}") int timeout) {
this.appName = appName;
this.timeout = timeout;
}
public void printConfig() {
System.out.println("App Name: " + appName);
System.out.println("Timeout: " + timeout + "ms");
}
}
在方法参数中使用 @Value
import org.springframework.stereotype.Component;
@Component
public class AppConfigMethodInjection {
public void printConfig(@Value("${app.name}") String appName,
@Value("${app.timeout}") int timeout) {
System.out.println("App Name: " + appName);
System.out.println("Timeout: " + timeout + "ms");
}
}
3. 彩蛋
此种方式是错误的!
import org.springframework.beans.factory.annotation.Value;
public class valueTest {
@Value("${app.name}")
private static String appName;
@Value("${app.version}")
private static String appVersion;
@Value("${app.timeout}")
private static int timeout;
public static void main(String[] args) {
System.out.println("App Name: " + appName);
System.out.println("App Version: " + appVersion);
System.out.println("App Timeout: " + timeout + "ms");
}
}
@Value
注解不能直接用于 static 变量,这是因为 Spring 的依赖注入机制在对象实例化后才会注入值,而 static 变量在类加载时就已经分配了内存,不属于对象的实例属性
要解决这个问题,可以将 @Value 注入到非静态变量或方法中,或者通过静态方法获取注入的值