@Value 注入主要有三种场景:
- 注入原始值,比如说注入
Value("hello")
- 注入变量,比如
@Value("${JAVA_HOME}")
- 注入spel表达式,比如
@Value("#{1 + 2}")
package com.example.value; import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.config.BeanExpressionContext; import org.springframework.beans.factory.config.DependencyDescriptor; import org.springframework.beans.factory.support.DefaultListableBeanFactory; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.ContextAnnotationAutowireCandidateResolver; import org.springframework.stereotype.Component; import java.lang.reflect.Field; @Configuration // 自动扫描bean3 public class ValueApplication { public static void main(String[] args) throws Exception { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ValueApplication.class); DefaultListableBeanFactory beanFactory = context.getDefaultListableBeanFactory(); ContextAnnotationAutowireCandidateResolver resolver = new ContextAnnotationAutowireCandidateResolver(); resolver.setBeanFactory(beanFactory); test1(context, resolver); test2(context, resolver); test3(context, resolver, Bean2.class.getDeclaredField("bean3")); System.out.println(">>>>>>>>>>>>>>>>>>>"); test3(context, resolver, Bean4.class.getDeclaredField("value")); } private static void test1(AnnotationConfigApplicationContext context, ContextAnnotationAutowireCandidateResolver resolver) throws Exception { DependencyDescriptor dd1 = new DependencyDescriptor(Bean1.class.getDeclaredField("home"), false); // 获取 @Value 的内容 String value = resolver.getSuggestedValue(dd1).toString(); System.out.println(value); // 解析 ${} value = context.getEnvironment().resolvePlaceholders(value); System.out.println(value); } // ${} -> 类型 private static void test2(AnnotationConfigApplicationContext context, ContextAnnotationAutowireCandidateResolver resolver) throws Exception{ DependencyDescriptor dd1 = new DependencyDescriptor(Bean1.class.getDeclaredField("age"), false); // 获取 @Value 的内容 String value = resolver.getSuggestedValue(dd1).toString(); System.out.println("@Value 的 value 属性值: " + value); // 解析 ${} value = context.getEnvironment().resolvePlaceholders(value); System.out.println("解析得到的值: " + value); System.out.println("解析得到的值的类型: " + value.getClass()); // 转成字段的类型 Object age = context.getBeanFactory() .getTypeConverter() .convertIfNecessary(value, dd1.getDependencyType()); System.out.println("转换后的类型: " + age.getClass()); } // spel private static void test3(AnnotationConfigApplicationContext context, ContextAnnotationAutowireCandidateResolver resolver, Field field) throws Exception { DependencyDescriptor dd1 = new DependencyDescriptor(field, false); // 获取 @Value 的内容 String value = resolver.getSuggestedValue(dd1).toString(); System.out.println("@Value 的 value 属性值: " + value); // 解析 ${} value = context.getEnvironment().resolvePlaceholders(value); System.out.println("解析得到的值: " + value); System.out.println("解析得到的值的类型: " + value.getClass()); // 解析 #{} Object bean3 = context.getBeanFactory() .getBeanExpressionResolver() .evaluate(value, new BeanExpressionContext(context.getBeanFactory(), null)); // 类型转换 Object result = context.getBeanFactory() .getTypeConverter() .convertIfNecessary(bean3, dd1.getDependencyType()); System.out.println("转换后的类型: " + result.getClass()); } static class Bean1 { @Value("${JAVA_HOME}") private String home; @Value("18") private int age; } static class Bean2 { @Value("#{@bean3}") private Bean3 bean3; } @Component("bean3") static class Bean3 { } static class Bean4 { @Value("#{'hello, ' + '${JAVA_HOME}'}") private String value; } }
输出结果
${JAVA_HOME} /Users/xx/Library/Java/JavaVirtualMachines/corretto-17.0.8.1/Contents/Home @Value 的 value 属性值: 18 解析得到的值: 18 解析得到的值的类型: class java.lang.String 转换后的类型: class java.lang.Integer @Value 的 value 属性值: #{@bean3} 解析得到的值: #{@bean3} 解析得到的值的类型: class java.lang.String 转换后的类型: class com.example.value.ValueApplication$Bean3 >>>>>>>>>>>>>>>>>>> @Value 的 value 属性值: #{'hello, ' + '${JAVA_HOME}'} 解析得到的值: #{'hello, ' + '/Users/xx/Library/Java/JavaVirtualMachines/corretto-17.0.8.1/Contents/Home'} 解析得到的值的类型: class java.lang.String 转换后的类型: class java.lang.String
用到的几个工具类
获取 @Value
内容
Bean2.class.getDeclaredField("bean3") DependencyDescriptor dd1 = new DependencyDescriptor(field, false); // 获取 @Value 的内容 String value = resolver.getSuggestedValue(dd1).toString();
解析 ${}
内容
value = context.getEnvironment().resolvePlaceholders(value);
解析 SPEL
Object bean3 = context.getBeanFactory() .getBeanExpressionResolver() .evaluate(value, new BeanExpressionContext(context.getBeanFactory(), null));
类型转换
Object result = context.getBeanFactory() .getTypeConverter() .convertIfNecessary(bean3, dd1.getDependencyType());