设为首页 - 加入收藏 平凉站长网 (http://www.0933zz.com)- 国内知名站长资讯网站,提供最新最全的站长资讯,创业经验,网站建设等!
热搜: 什么 为什么 平台 赚钱
当前位置: 首页 > 综合聚焦 > 移动互联 > 评测 > 正文

Springboot源码分析之Spring循环依赖揭秘(6)

发布时间:2019-09-13 00:29 所属栏目:[评测] 来源:佚名
导读:@Lazy 一般含义是懒加载,它只会作用于 BeanDefinition.setLazyInit() 。而此处给它增加了一个能力:延迟处理(代理处理) //@since4.0出现得挺晚,它支持到了@Lazy是功能最全的AutowireCandidateResolver publiccl

@Lazy?一般含义是懒加载,它只会作用于?BeanDefinition.setLazyInit()?。而此处给它增加了一个能力:延迟处理(代理处理)

  1. //?@since?4.0?出现得挺晚,它支持到了@Lazy??是功能最全的AutowireCandidateResolver?
  2. ????public?class?ContextAnnotationAutowireCandidateResolver?extends?QualifierAnnotationAutowireCandidateResolver?{?
  3. ????????//?这是此类本身唯一做的事,此处精析??
  4. ????????//?返回该?lazy?proxy?表示延迟初始化,实现过程是查看在?@Autowired?注解处是否使用了?@Lazy?=?true?注解??
  5. ????????@Override?
  6. ????????@Nullable?
  7. ????????public?Object?getLazyResolutionProxyIfNecessary(DependencyDescriptor?descriptor,?@Nullable?String?beanName)?{?
  8. ????????????//?如果isLazy=true??那就返回一个代理,否则返回null?
  9. ????????????//?相当于若标注了@Lazy注解,就会返回一个代理(当然@Lazy注解的value值不能是false)?
  10. ????????????return?(isLazy(descriptor)???buildLazyResolutionProxy(descriptor,?beanName)?:?null);?
  11. ????????}?
  12. ?????
  13. ????????//?这个比较简单,@Lazy注解标注了就行(value属性默认值是true)?
  14. ????????//?@Lazy支持标注在属性上和方法入参上~~~??这里都会解析?
  15. ????????protected?boolean?isLazy(DependencyDescriptor?descriptor)?{?
  16. ????????????for?(Annotation?ann?:?descriptor.getAnnotations())?{?
  17. ????????????????Lazy?lazy?=?AnnotationUtils.getAnnotation(ann,?Lazy.class);?
  18. ????????????????if?(lazy?!=?null?&&?lazy.value())?{?
  19. ????????????????????return?true;?
  20. ????????????????}?
  21. ????????????}?
  22. ????????????MethodParameter?methodParam?=?descriptor.getMethodParameter();?
  23. ????????????if?(methodParam?!=?null)?{?
  24. ????????????????Method?method?=?methodParam.getMethod();?
  25. ????????????????if?(method?==?null?||?void.class?==?method.getReturnType())?{?
  26. ????????????????????Lazy?lazy?=?AnnotationUtils.getAnnotation(methodParam.getAnnotatedElement(),?Lazy.class);?
  27. ????????????????????if?(lazy?!=?null?&&?lazy.value())?{?
  28. ????????????????????????return?true;?
  29. ????????????????????}?
  30. ????????????????}?
  31. ????????????}?
  32. ????????????return?false;?
  33. ????????}?
  34. ?????
  35. ????????//?核心内容,是本类的灵魂~~~?
  36. ????????protected?Object?buildLazyResolutionProxy(final?DependencyDescriptor?descriptor,?final?@Nullable?String?beanName)?{?
  37. ????????????Assert.state(getBeanFactory()?instanceof?DefaultListableBeanFactory,?
  38. ????????????????????"BeanFactory?needs?to?be?a?DefaultListableBeanFactory");?
  39. ?????
  40. ????????????//?这里毫不客气的使用了面向实现类编程,使用了DefaultListableBeanFactory.doResolveDependency()方法~~~?
  41. ????????????final?DefaultListableBeanFactory?beanFactory?=?(DefaultListableBeanFactory)?getBeanFactory();?
  42. ?????
  43. ????????????//TargetSource?是它实现懒加载的核心原因,在AOP那一章节了重点提到过这个接口,此处不再叙述?
  44. ????????????//?它有很多的着名实现如HotSwappableTargetSource、SingletonTargetSource、LazyInitTargetSource、?
  45. ????????????//SimpleBeanTargetSource、ThreadLocalTargetSource、PrototypeTargetSource等等非常多?
  46. ????????????//?此处因为只需要自己用,所以采用匿名内部类的方式实现~~~?此处最重要是看getTarget方法,它在被使用的时候(也就是代理对象真正使用的时候执行~~~)?
  47. ????????????TargetSource?ts?=?new?TargetSource()?{?
  48. ????????????????@Override?
  49. ????????????????public?Class?getTargetClass()?{?
  50. ????????????????????return?descriptor.getDependencyType();?
  51. ????????????????}?
  52. ????????????????@Override?
  53. ????????????????public?boolean?isStatic()?{?
  54. ????????????????????return?false;?
  55. ????????????????}?
  56. ?????????
  57. ????????????????//?getTarget是调用代理方法的时候会调用的,所以执行每个代理方法都会执行此方法,这也是为何doResolveDependency?
  58. ????????????????//?我个人认为它在效率上,是存在一定的问题的~~~所以此处建议尽量少用@Lazy~~~????
  59. ????????????????//不过效率上应该还好,对比http、序列化反序列化处理,简直不值一提??所以还是无所谓??用吧?
  60. ????????????????@Override?
  61. ????????????????public?Object?getTarget()?{?
  62. ????????????????????Object?target?=?beanFactory.doResolveDependency(descriptor,?beanName,?null,?null);?
  63. ????????????????????if?(target?==?null)?{?
  64. ????????????????????????Class?type?=?getTargetClass();?
  65. ????????????????????????//?对多值注入的空值的友好处理(不要用null)?
  66. ????????????????????????if?(Map.class?==?type)?{?
  67. ????????????????????????????return?Collections.emptyMap();?
  68. ????????????????????????}?else?if?(List.class?==?type)?{?
  69. ????????????????????????????return?Collections.emptyList();?
  70. ????????????????????????}?else?if?(Set.class?==?type?||?Collection.class?==?type)?{?
  71. ????????????????????????????return?Collections.emptySet();?
  72. ????????????????????????}?
  73. ????????????????????????throw?new?NoSuchBeanDefinitionException(descriptor.getResolvableType(),?
  74. ????????????????????????????????"Optional?dependency?not?present?for?lazy?injection?point");?
  75. ????????????????????}?
  76. ????????????????????return?target;?
  77. ????????????????}?
  78. ????????????????@Override?
  79. ????????????????public?void?releaseTarget(Object?target)?{?
  80. ????????????????}?
  81. ????????????};????
  82. ?????
  83. ????????????//?使用ProxyFactory??给ts生成一个代理?
  84. ????????????//?由此可见最终生成的代理对象的目标对象其实是TargetSource,而TargetSource的目标才是我们业务的对象?
  85. ????????????ProxyFactory?pf?=?new?ProxyFactory();?
  86. ????????????pf.setTargetSource(ts);?
  87. ????????????Class?dependencyType?=?descriptor.getDependencyType();?
  88. ?????????????
  89. ????????????//?如果注入的语句是这么写的private?AInterface?a;??那这类就是借口?值是true?
  90. ????????????//?把这个接口类型也得放进去(不然这个代理都不属于这个类型,反射set的时候岂不直接报错了吗????)?
  91. ????????????if?(dependencyType.isInterface())?{?
  92. ????????????????pf.addInterface(dependencyType);?
  93. ????????????}?
  94. ????????????return?pf.getProxy(beanFactory.getBeanClassLoader());?
  95. ????????}?
  96. ????}?

【免责声明】本站内容转载自互联网,其相关言论仅代表作者个人观点绝非权威,不代表本站立场。如您发现内容存在版权问题,请提交相关链接至邮箱:bqsm@foxmail.com,我们将及时予以处理。

网友评论
推荐文章