第四十六讲-@Value注入底层(第四讲延续)
第四十六讲-@Value注入底层(第四讲延续)
如下面的代码:
// 本章节作为第四讲的延续
@Configuration
@SuppressWarnings("all")
public class A46 {
public static void main(String[] args) throws Exception {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(A46.class);
DefaultListableBeanFactory beanFactory = context.getDefaultListableBeanFactory();
ContextAnnotationAutowireCandidateResolver resolver = new ContextAnnotationAutowireCandidateResolver();
resolver.setBeanFactory(beanFactory);
// test1(context, resolver, Bean1.class.getDeclaredField("home"));
// test2(context, resolver, Bean1.class.getDeclaredField("age"));
// test3(context, resolver, Bean2.class.getDeclaredField("bean3"));
test3(context, resolver, Bean4.class.getDeclaredField("value"));
}
private static void test3(AnnotationConfigApplicationContext context, ContextAnnotationAutowireCandidateResolver resolver, Field field) {
DependencyDescriptor dd1 = new DependencyDescriptor(field, false);
// 获取 @Value 的内容
String value = resolver.getSuggestedValue(dd1).toString();
System.out.println(value);
// 解析 ${}
value = context.getEnvironment().resolvePlaceholders(value);
System.out.println(value);
System.out.println(value.getClass());
// 解析 #{} @bean3
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);
}
private static void test2(AnnotationConfigApplicationContext context, ContextAnnotationAutowireCandidateResolver resolver, Field field) {
DependencyDescriptor dd1 = new DependencyDescriptor(field, false);
// 获取 @Value 的内容
String value = resolver.getSuggestedValue(dd1).toString();
System.out.println(value);
// 解析 ${}
value = context.getEnvironment().resolvePlaceholders(value);
System.out.println(value);
System.out.println(value.getClass());
// 类型转换,String转为Integer
Object age = context.getBeanFactory().getTypeConverter().convertIfNecessary(value, dd1.getDependencyType());
System.out.println(age.getClass());
}
private static void test1(AnnotationConfigApplicationContext context, ContextAnnotationAutowireCandidateResolver resolver, Field field) {
DependencyDescriptor dd1 = new DependencyDescriptor(field, false);
// 获取 @Value 的内容
String value = resolver.getSuggestedValue(dd1).toString();
System.out.println(value);
// 解析 ${}
value = context.getEnvironment().resolvePlaceholders(value);
System.out.println(value);
}
public class Bean1 {
@Value("${JAVA_HOME}")
private String home;
@Value("18")
private int age;
}
public class Bean2 {
@Value("#{@bean3}") // SpringEL #{SpEL}: @Value也可以作为依赖注入,类似于@Autowired,只是要配合Spring EL表达式一起使用,
//形式为#{@beanName},也就是根据beanName寻找对应的bean对象进行注入
private Bean3 bean3;
}
@Component("bean3")
public class Bean3 {
}
static class Bean4 {
@Value("#{'hello, ' + '${JAVA_HOME}'}")
private String value;
}
}
分类:
Spring 高级49讲
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构