@Value 注入主要有三种场景:
- 注入原始值,比如说注入
Value("hello")
- 注入变量,比如
@Value("${JAVA_HOME}")
- 注入spel表达式,比如
@Value("#{1 + 2}")
文章目录
- 获取 `@Value`内容
- 解析 `${}`内容
- 解析 `SPEL`
- 类型转换
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());}// spelprivate 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());