微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

spring 43 @Value 装配底层

按类型装配的步骤

  1. 查看需要的类型是否为 Optional,是,则进行封装(非延迟),否则向下走
  2. 查看需要的类型是否为 ObjectFactory 或 ObjectProvider,是,则进行封装(延迟),否则向下走
  3. 查看需要的类型(成员或参数)上是否用 @Lazy 修饰,是,则返回代理,否则向下走
  4. 解析 @Value 的值
    1. 如果需要的值是字符串,先解析 ${ },再解析 #{ }
    2. 不是字符串,需要用 TypeConverter 转换
  5. 看需要的类型是否为 Stream、Array、Collection、Map,是,则按集合处理,否则向下走
  6. beanfactory 的 resolvableDependencies 中找有没有类型合适的对象注入,没有向下走
  7. beanfactory 及父工厂中找类型匹配的 bean 进行筛选,筛选时会考虑 @Qualifier 及泛型
  8. 结果个数为 0 抛出 NoSuchBeanDeFinitionException 异常
  9. 如果结果 > 1,再根据 @Primary 进行筛选
  10. 如果结果仍 > 1,再根据成员名或变量名进行筛选
  11. 结果仍 > 1,抛出 NoUniqueBeanDeFinitionException 异常
点击查看代码 @H_404_35@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()); 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} private Bean3 bean3; } @Component("bean3") public class Bean3 { } static class Bean4 { @Value("#{'hello, ' + '${JAVA_HOME}'}") private String value; } }

小结:

  1. ContextAnnotationAutowireCandidateResolver 作用之一,获取 @Value 的值
  2. 了解 ${ } 对应的解析器
  3. 了解 #{ } 对应的解析器
  4. TypeConvert 的一项体现

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐