1. 前面分析了bean的静态工厂查找
  2. bean的构造器查找过程和bean的静态工厂查找类似
  3.  
  4. protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, Object[] args) {
  5. // Make sure bean class is actually resolved at this point.
  6. Class<?> beanClass = resolveBeanClass(mbd, beanName);
  7.  
  8. if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {
  9. throw new BeanCreationException(mbd.getResourceDescription(), beanName,
  10. "Bean class isn't public, and non-public access not allowed: " + beanClass.getName());
  11. }
  12.  
  13. if (mbd.getFactoryMethodName() != null) {
  14. //使用工厂方法获取
  15. return instantiateUsingFactoryMethod(beanName, mbd, args);
  16. }
  17.  
  18. // Shortcut when re-creating the same bean...
  19. boolean resolved = false;
  20. boolean autowireNecessary = false;
  21. if (args == null) {
  22. synchronized (mbd.constructorArgumentLock) {
  23. if (mbd.resolvedConstructorOrFactoryMethod != null) {
  24. resolved = true;
  25. autowireNecessary = mbd.constructorArgumentsResolved;
  26. }
  27. }
  28. }
  29. if (resolved) {
  30. if (autowireNecessary) {
  31. return autowireConstructor(beanName, mbd, null, null);
  32. }
  33. else {
  34. return instantiateBean(beanName, mbd);
  35. }
  36. }
  37.  
  38. // Need to determine the constructor...通过后置处理器返回构造器,然后通过autowireConstructor去筛选构造器,这种可用于配置文件中没有配置构造器参数的方式。
  39. Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
  40. if (ctors != null ||
  41. mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR ||
  42. mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
  43. return autowireConstructor(beanName, mbd, ctors, args);
  44. }
  45.  
  46. // No special handling: simply use no-arg constructor.
  47. //使用无参构造器构造
  48. return instantiateBean(beanName, mbd);
  49. }
  50.  
  51. AbstractAutowireCapableBeanFactory.autowireConstructor
  52.  
  53. protected BeanWrapper autowireConstructor(
  54. String beanName, RootBeanDefinition mbd, Constructor<?>[] ctors, Object[] explicitArgs) {
  55.  
  56. return new ConstructorResolver(this).autowireConstructor(beanName, mbd, ctors, explicitArgs);
  57. }
  58.  
  59. ConstructorResolver.autowireConstructor
  60.  
  61. //beanName表示正在创建bean的名字,mbd表示正在创建bean的BeanDefinition,chosenCtors表示是程序指定的可选构造器列表,可通过后置处理器得到,explicitArgs是用户指定的构造参数
  62. public BeanWrapper autowireConstructor(final String beanName, final RootBeanDefinition mbd,
  63. Constructor<?>[] chosenCtors, final Object[] explicitArgs) {
  64.  
  65. BeanWrapperImpl bw = new BeanWrapperImpl();
  66. //初始化,注册类型转化器和自定义类型转化器
  67. this.beanFactory.initBeanWrapper(bw);
  68.  
  69. Constructor<?> constructorToUse = null;
  70. ArgumentsHolder argsHolderToUse = null;
  71. Object[] argsToUse = null;
  72.  
  73. if (explicitArgs != null) {
  74. argsToUse = explicitArgs;
  75. }
  76. else {
  77. //这里的操作和解析工厂方法时一样的
  78. Object[] argsToResolve = null;
  79. synchronized (mbd.constructorArgumentLock) {
  80. //从缓存中获取
  81. constructorToUse = (Constructor<?>) mbd.resolvedConstructorOrFactoryMethod;
  82. if (constructorToUse != null && mbd.constructorArgumentsResolved) {
  83. // Found a cached constructor...
  84. argsToUse = mbd.resolvedConstructorArguments;
  85. if (argsToUse == null) {
  86. //使用预备的集合参数
  87. argsToResolve = mbd.preparedConstructorArguments;
  88. }
  89. }
  90. }
  91. if (argsToResolve != null) {
  92. //解析预备参数集合
  93. argsToUse = resolvePreparedArguments(beanName, mbd, bw, constructorToUse, argsToResolve);
  94. }
  95. }
  96.  
  97. //如果没有缓存,那么就从头开始查找
  98. if (constructorToUse == null) {
  99. // Need to resolve the constructor.
  100. //如果用户指定了构造器,或者装配为构造器自动装配
  101. boolean autowiring = (chosenCtors != null ||
  102. mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR);
  103. ConstructorArgumentValues resolvedValues = null;
  104.  
  105. int minNrOfArgs;
  106. if (explicitArgs != null) {
  107. minNrOfArgs = explicitArgs.length;
  108. }
  109. else {
  110. ConstructorArgumentValues cargs = mbd.getConstructorArgumentValues();
  111. resolvedValues = new ConstructorArgumentValues();
  112. //解析配置的参数
  113. minNrOfArgs = resolveConstructorArguments(beanName, mbd, bw, cargs, resolvedValues);
  114. }
  115.  
  116. // Take specified constructors, if any.
  117. Constructor<?>[] candidates = chosenCtors;
  118. if (candidates == null) {
  119.  
  120. Class<?> beanClass = mbd.getBeanClass();
  121. try {
  122. //如果没有指定构造器,那么就获取当前bean的构造器
  123. candidates = (mbd.isNonPublicAccessAllowed() ?
  124. beanClass.getDeclaredConstructors() : beanClass.getConstructors());
  125. }
  126. catch (Throwable ex) {
  127. throw new BeanCreationException(mbd.getResourceDescription(), beanName,
  128. "Resolution of declared constructors on bean Class [" + beanClass.getName() +
  129. "] from ClassLoader [" + beanClass.getClassLoader() + "] failed", ex);
  130. }
  131. }
  132. //进行排序,public在前,参数长的在前
  133. AutowireUtils.sortConstructors(candidates);
  134. int minTypeDiffWeight = Integer.MAX_VALUE;
  135. Set<Constructor<?>> ambiguousConstructors = null;
  136. LinkedList<UnsatisfiedDependencyException> causes = null;
  137.  
  138. for (int i = 0; i < candidates.length; i++) {
  139. Constructor<?> candidate = candidates[i];
  140. Class<?>[] paramTypes = candidate.getParameterTypes();
  141.  
  142. if (constructorToUse != null && argsToUse.length > paramTypes.length) {
  143. // Already found greedy constructor that can be satisfied ->
  144. // do not look any further, there are only less greedy constructors left.
  145. break;
  146. }
  147. if (paramTypes.length < minNrOfArgs) {
  148. continue;
  149. }
  150.  
  151. ArgumentsHolder argsHolder;
  152. if (resolvedValues != null) {
  153. try {
  154. String[] paramNames = ConstructorPropertiesChecker.evaluate(candidate, paramTypes.length);
  155. if (paramNames == null) {
  156. ParameterNameDiscoverer pnd = this.beanFactory.getParameterNameDiscoverer();
  157. if (pnd != null) {
  158. paramNames = pnd.getParameterNames(candidate);
  159. }
  160. }
  161. argsHolder = createArgumentArray(
  162. beanName, mbd, resolvedValues, bw, paramTypes, paramNames, candidate, autowiring);
  163. }
  164. catch (UnsatisfiedDependencyException ex) {
  165. if (this.beanFactory.logger.isTraceEnabled()) {
  166. this.beanFactory.logger.trace(
  167. "Ignoring constructor [" + candidate + "] of bean '" + beanName + "': " + ex);
  168. }
  169. // Swallow and try next constructor.
  170. if (causes == null) {
  171. causes = new LinkedList<UnsatisfiedDependencyException>();
  172. }
  173. causes.add(ex);
  174. continue;
  175. }
  176. }
  177. else {
  178. // Explicit arguments given -> arguments length must match exactly.
  179. if (paramTypes.length != explicitArgs.length) {
  180. continue;
  181. }
  182. argsHolder = new ArgumentsHolder(explicitArgs);
  183. }
  184. //根据一些宽松或者严格模式去寻找更适合的构造器
  185. int typeDiffWeight = (mbd.isLenientConstructorResolution() ?
  186. argsHolder.getTypeDifferenceWeight(paramTypes) : argsHolder.getAssignabilityWeight(paramTypes));
  187. // Choose this constructor if it represents the closest match.
  188. if (typeDiffWeight < minTypeDiffWeight) {
  189. constructorToUse = candidate;
  190. argsHolderToUse = argsHolder;
  191. argsToUse = argsHolder.arguments;
  192. minTypeDiffWeight = typeDiffWeight;
  193. ambiguousConstructors = null;
  194. }
  195. else if (constructorToUse != null && typeDiffWeight == minTypeDiffWeight) {
  196. if (ambiguousConstructors == null) {
  197. ambiguousConstructors = new LinkedHashSet<Constructor<?>>();
  198. ambiguousConstructors.add(constructorToUse);
  199. }
  200. //存储存在歧义的构造器
  201. ambiguousConstructors.add(candidate);
  202. }
  203. }
  204.  
  205. if (constructorToUse == null) {
  206. if (causes != null) {
  207. UnsatisfiedDependencyException ex = causes.removeLast();
  208. for (Exception cause : causes) {
  209. this.beanFactory.onSuppressedException(cause);
  210. }
  211. throw ex;
  212. }
  213. throw new BeanCreationException(mbd.getResourceDescription(), beanName,
  214. "Could not resolve matching constructor " +
  215. "(hint: specify index/type/name arguments for simple parameters to avoid type ambiguities)");
  216. }
  217. else if (ambiguousConstructors != null && !mbd.isLenientConstructorResolution()) {
  218. throw new BeanCreationException(mbd.getResourceDescription(), beanName,
  219. "Ambiguous constructor matches found in bean '" + beanName + "' " +
  220. "(hint: specify index/type/name arguments for simple parameters to avoid type ambiguities): " +
  221. ambiguousConstructors);
  222. }
  223.  
  224. if (explicitArgs == null) {
  225. argsHolderToUse.storeCache(mbd, constructorToUse);
  226. }
  227. }
  228.  
  229. try {
  230. Object beanInstance;
  231.  
  232. if (System.getSecurityManager() != null) {
  233. final Constructor<?> ctorToUse = constructorToUse;
  234. final Object[] argumentsToUse = argsToUse;
  235. beanInstance = AccessController.doPrivileged(new PrivilegedAction<Object>() {
  236. @Override
  237. public Object run() {
  238. return beanFactory.getInstantiationStrategy().instantiate(
  239. mbd, beanName, beanFactory, ctorToUse, argumentsToUse);
  240. }
  241. }, beanFactory.getAccessControlContext());
  242. }
  243. else {
  244. //构造对应的bean实例
  245. beanInstance = this.beanFactory.getInstantiationStrategy().instantiate(
  246. mbd, beanName, this.beanFactory, constructorToUse, argsToUse);
  247. }
  248.  
  249. bw.setWrappedInstance(beanInstance);
  250. return bw;
  251. }
  252. catch (Throwable ex) {
  253. throw new BeanCreationException(mbd.getResourceDescription(), beanName,
  254. "Bean instantiation via constructor failed", ex);
  255. }
  256. }

bean的创建(五)第四部分 bean构造器的查找的更多相关文章

  1. Spring 源码(17)Spring Bean的创建过程(8)Bean的初始化

    知识回顾 Bean的创建过程会经历getBean,doGetBean,createBean,doCreateBean,然后Bean的创建又会经历实例化,属性填充,初始化. 在实例化createInst ...

  2. 0003 - 基于xml的Spring Bean 的创建过程

    一.目录 前言 创建 Bean 容器 加载 Bean 定义 创建 Bean Spring Bean 创建过程中的设计模式 总结 二.前言 2.1 Spring 使用配置 ApplicationCont ...

  3. Solon 开发,四、Bean 扫描的三种方式

    Solon 开发 一.注入或手动获取配置 二.注入或手动获取Bean 三.构建一个Bean的三种方式 四.Bean 扫描的三种方式 五.切面与环绕拦截 六.提取Bean的函数进行定制开发 七.自定义注 ...

  4. Spring 源码(11)Spring Bean 的创建过程(2)

    Spring Bean 的创建过程介绍了FactoryBean 的创建方式,那么接下来介绍不是FactoryBean的创建方式,在创建过程中,又会分为单例的Bean的创建,原型类型的Bean的创建等. ...

  5. Spring源码学习-容器BeanFactory(五) Bean的创建-探寻Bean的新生之路

    写在前面 上面四篇文章讲了Spring是如何将配置文件一步一步转化为BeanDefinition的整个流程,下面就到了正式创建Bean对象实例的环节了,我们一起继续学习吧. 2.初始化Bean对象实例 ...

  6. bean的创建(五)第二部分 寻找bean的工厂方法实例化

    instanceWrapper = createBeanInstance(beanName, mbd, args); AbstractAutowireCapableBeanFactory.create ...

  7. bean的创建(五)第一部分

    AbstractBeanFactory.doGetBean protected <T> T doGetBean( final String name, final Class<T&g ...

  8. bean的创建(五)第五部分 属性填充

    AbstractAutowireCapableBeanFactory.populateBean protected void populateBean(String beanName, RootBea ...

  9. Spring学习笔记之 Spring IOC容器(一)之 实例化容器,创建JavaBean对象,控制Bean实例化,setter方式注入,依赖属性的注入,自动装配功能实现自动属性注入

    本节主要内容:       1.实例化Spring容器示例    2.利用Spring容器创建JavaBean对象    3.如何控制Bean实例化    4.利用Spring实现bean属性sett ...

  10. Spring源码分析之Bean的创建过程详解

    前文传送门: Spring源码分析之预启动流程 Spring源码分析之BeanFactory体系结构 Spring源码分析之BeanFactoryPostProcessor调用过程详解 本文内容: 在 ...

随机推荐

  1. 30441数据定义语言DDL

    数据定义:指对数据库对象的定义.删除和修改操作. 数据库对象主要包括数据表.视图.索引等. 数据定义功能通过CREATE.ALTER.DROP语句来完成. 按照操作对象分类来介绍数据定义的SQL语法. ...

  2. abp(net core)+easyui+efcore仓储系统——展现层实现增删改查之控制器(六)

    abp(net core)+easyui+efcore仓储系统目录 abp(net core)+easyui+efcore仓储系统——ABP总体介绍(一) abp(net core)+easyui+e ...

  3. ZooKeeper学习第四期---构建ZooKeeper应用(转)

    转载来源:https://www.cnblogs.com/sunddenly/p/4064992.html 一.配置服务 配置服务是分布式应用所需要的基本服务之一,它使集群中的机器可以共享配置信息中那 ...

  4. 02-MySQL的安装和管理

    # mysql的安装和基本管理 # 01 数据库管理软件分类 ''' 分两大类: 关系型:如sqllite,db2,oracle,access,sql server,MySQL,注意:sql语句通用 ...

  5. Spring Bean的3种装配方式

    Bean常用的装配方式有3种: 基于xml的装配 基于Annotation(注解)的装配 基于Java类的装配 基于xml的装配 在xml文件中配置Bean. 如果依赖很多,xml配置文件会很臃肿,后 ...

  6. HBase 学习之路(二)—— HBase系统架构及数据结构

    一.基本概念 一个典型的Hbase Table 表如下: 1.1 Row Key (行键) Row Key是用来检索记录的主键.想要访问HBase Table中的数据,只有以下三种方式: 通过指定的R ...

  7. java编程思想之面向对象

    面向对象和面向过程 面向对象(Object Oriented),简称OO,是软件开发方法的一种,我们都知道java是基于面向对象开发的,但是说到面向对象,我们不得不提一提面向过程开发,面向过程,又称结 ...

  8. js避坑历险记

    代码改变世界,世界改变码农,码农改变代码! 我就是我,我就是一个码农的武林. 前方JS巨坑出没,请注意集中力! 巨坑1:js精度问题 前段时间去一家物流公司面试,做了一个js题,印象尤为深刻: var ...

  9. .NET Core IdentityServer4实战 第六章-Consent授权页

    在identityServer4中登陆页面只要是成功了,就会注册一个Cookie在服务器资源上,像现在大部分的网站第三方授权,都是经过一个页面,然后选需要的功能,IdentityServer4也给我们 ...

  10. spring boot 2.0 thymeleaf调试时正常,打包后运行报错. 找不到模板文件.

    使用th:fragment  定义模板 使用 th:replace  来添加模板到需要的地方. 使用时发现一个非常奇怪的问题. 本机idea 调试环境一切正常, 但是打成jar包以后报错,提示找不到对 ...