前面分析了bean的静态工厂查找
bean的构造器查找过程和bean的静态工厂查找类似 protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, Object[] args) {
// Make sure bean class is actually resolved at this point.
Class<?> beanClass = resolveBeanClass(mbd, beanName); if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Bean class isn't public, and non-public access not allowed: " + beanClass.getName());
} if (mbd.getFactoryMethodName() != null) {
//使用工厂方法获取
return instantiateUsingFactoryMethod(beanName, mbd, args);
} // Shortcut when re-creating the same bean...
boolean resolved = false;
boolean autowireNecessary = false;
if (args == null) {
synchronized (mbd.constructorArgumentLock) {
if (mbd.resolvedConstructorOrFactoryMethod != null) {
resolved = true;
autowireNecessary = mbd.constructorArgumentsResolved;
}
}
}
if (resolved) {
if (autowireNecessary) {
return autowireConstructor(beanName, mbd, null, null);
}
else {
return instantiateBean(beanName, mbd);
}
} // Need to determine the constructor...通过后置处理器返回构造器,然后通过autowireConstructor去筛选构造器,这种可用于配置文件中没有配置构造器参数的方式。
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
if (ctors != null ||
mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR ||
mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
return autowireConstructor(beanName, mbd, ctors, args);
} // No special handling: simply use no-arg constructor.
//使用无参构造器构造
return instantiateBean(beanName, mbd);
} AbstractAutowireCapableBeanFactory.autowireConstructor protected BeanWrapper autowireConstructor(
String beanName, RootBeanDefinition mbd, Constructor<?>[] ctors, Object[] explicitArgs) { return new ConstructorResolver(this).autowireConstructor(beanName, mbd, ctors, explicitArgs);
} ConstructorResolver.autowireConstructor //beanName表示正在创建bean的名字,mbd表示正在创建bean的BeanDefinition,chosenCtors表示是程序指定的可选构造器列表,可通过后置处理器得到,explicitArgs是用户指定的构造参数
public BeanWrapper autowireConstructor(final String beanName, final RootBeanDefinition mbd,
Constructor<?>[] chosenCtors, final Object[] explicitArgs) { BeanWrapperImpl bw = new BeanWrapperImpl();
//初始化,注册类型转化器和自定义类型转化器
this.beanFactory.initBeanWrapper(bw); Constructor<?> constructorToUse = null;
ArgumentsHolder argsHolderToUse = null;
Object[] argsToUse = null; if (explicitArgs != null) {
argsToUse = explicitArgs;
}
else {
//这里的操作和解析工厂方法时一样的
Object[] argsToResolve = null;
synchronized (mbd.constructorArgumentLock) {
//从缓存中获取
constructorToUse = (Constructor<?>) mbd.resolvedConstructorOrFactoryMethod;
if (constructorToUse != null && mbd.constructorArgumentsResolved) {
// Found a cached constructor...
argsToUse = mbd.resolvedConstructorArguments;
if (argsToUse == null) {
//使用预备的集合参数
argsToResolve = mbd.preparedConstructorArguments;
}
}
}
if (argsToResolve != null) {
//解析预备参数集合
argsToUse = resolvePreparedArguments(beanName, mbd, bw, constructorToUse, argsToResolve);
}
} //如果没有缓存,那么就从头开始查找
if (constructorToUse == null) {
// Need to resolve the constructor.
//如果用户指定了构造器,或者装配为构造器自动装配
boolean autowiring = (chosenCtors != null ||
mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR);
ConstructorArgumentValues resolvedValues = null; int minNrOfArgs;
if (explicitArgs != null) {
minNrOfArgs = explicitArgs.length;
}
else {
ConstructorArgumentValues cargs = mbd.getConstructorArgumentValues();
resolvedValues = new ConstructorArgumentValues();
//解析配置的参数
minNrOfArgs = resolveConstructorArguments(beanName, mbd, bw, cargs, resolvedValues);
} // Take specified constructors, if any.
Constructor<?>[] candidates = chosenCtors;
if (candidates == null) { Class<?> beanClass = mbd.getBeanClass();
try {
//如果没有指定构造器,那么就获取当前bean的构造器
candidates = (mbd.isNonPublicAccessAllowed() ?
beanClass.getDeclaredConstructors() : beanClass.getConstructors());
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Resolution of declared constructors on bean Class [" + beanClass.getName() +
"] from ClassLoader [" + beanClass.getClassLoader() + "] failed", ex);
}
}
//进行排序,public在前,参数长的在前
AutowireUtils.sortConstructors(candidates);
int minTypeDiffWeight = Integer.MAX_VALUE;
Set<Constructor<?>> ambiguousConstructors = null;
LinkedList<UnsatisfiedDependencyException> causes = null; for (int i = 0; i < candidates.length; i++) {
Constructor<?> candidate = candidates[i];
Class<?>[] paramTypes = candidate.getParameterTypes(); if (constructorToUse != null && argsToUse.length > paramTypes.length) {
// Already found greedy constructor that can be satisfied ->
// do not look any further, there are only less greedy constructors left.
break;
}
if (paramTypes.length < minNrOfArgs) {
continue;
} ArgumentsHolder argsHolder;
if (resolvedValues != null) {
try {
String[] paramNames = ConstructorPropertiesChecker.evaluate(candidate, paramTypes.length);
if (paramNames == null) {
ParameterNameDiscoverer pnd = this.beanFactory.getParameterNameDiscoverer();
if (pnd != null) {
paramNames = pnd.getParameterNames(candidate);
}
}
argsHolder = createArgumentArray(
beanName, mbd, resolvedValues, bw, paramTypes, paramNames, candidate, autowiring);
}
catch (UnsatisfiedDependencyException ex) {
if (this.beanFactory.logger.isTraceEnabled()) {
this.beanFactory.logger.trace(
"Ignoring constructor [" + candidate + "] of bean '" + beanName + "': " + ex);
}
// Swallow and try next constructor.
if (causes == null) {
causes = new LinkedList<UnsatisfiedDependencyException>();
}
causes.add(ex);
continue;
}
}
else {
// Explicit arguments given -> arguments length must match exactly.
if (paramTypes.length != explicitArgs.length) {
continue;
}
argsHolder = new ArgumentsHolder(explicitArgs);
}
//根据一些宽松或者严格模式去寻找更适合的构造器
int typeDiffWeight = (mbd.isLenientConstructorResolution() ?
argsHolder.getTypeDifferenceWeight(paramTypes) : argsHolder.getAssignabilityWeight(paramTypes));
// Choose this constructor if it represents the closest match.
if (typeDiffWeight < minTypeDiffWeight) {
constructorToUse = candidate;
argsHolderToUse = argsHolder;
argsToUse = argsHolder.arguments;
minTypeDiffWeight = typeDiffWeight;
ambiguousConstructors = null;
}
else if (constructorToUse != null && typeDiffWeight == minTypeDiffWeight) {
if (ambiguousConstructors == null) {
ambiguousConstructors = new LinkedHashSet<Constructor<?>>();
ambiguousConstructors.add(constructorToUse);
}
//存储存在歧义的构造器
ambiguousConstructors.add(candidate);
}
} if (constructorToUse == null) {
if (causes != null) {
UnsatisfiedDependencyException ex = causes.removeLast();
for (Exception cause : causes) {
this.beanFactory.onSuppressedException(cause);
}
throw ex;
}
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Could not resolve matching constructor " +
"(hint: specify index/type/name arguments for simple parameters to avoid type ambiguities)");
}
else if (ambiguousConstructors != null && !mbd.isLenientConstructorResolution()) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Ambiguous constructor matches found in bean '" + beanName + "' " +
"(hint: specify index/type/name arguments for simple parameters to avoid type ambiguities): " +
ambiguousConstructors);
} if (explicitArgs == null) {
argsHolderToUse.storeCache(mbd, constructorToUse);
}
} try {
Object beanInstance; if (System.getSecurityManager() != null) {
final Constructor<?> ctorToUse = constructorToUse;
final Object[] argumentsToUse = argsToUse;
beanInstance = AccessController.doPrivileged(new PrivilegedAction<Object>() {
@Override
public Object run() {
return beanFactory.getInstantiationStrategy().instantiate(
mbd, beanName, beanFactory, ctorToUse, argumentsToUse);
}
}, beanFactory.getAccessControlContext());
}
else {
//构造对应的bean实例
beanInstance = this.beanFactory.getInstantiationStrategy().instantiate(
mbd, beanName, this.beanFactory, constructorToUse, argsToUse);
} bw.setWrappedInstance(beanInstance);
return bw;
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Bean instantiation via constructor failed", ex);
}
}

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. ZooKeeper学习之路(五)—— ACL权限控制

    一.前言 为了避免存储在Zookeeper上的数据被其他程序或者人为误修改,Zookeeper提供了ACL(Access Control Lists)进行权限控制.只有拥有对应权限的用户才可以对节点进 ...

  2. mysql批量update操作时出现锁表

    https://www.cnblogs.com/wodebudong/articles/7976474.html 最近遇到一件锁表的情况,发现更新的语句where检索的字段,没有建索引,且是批量操作的 ...

  3. QDomDocument 读取和编辑xml文件

    Qt中几种操作xml的方式 流方式 sax方式 dom方式 初学时,我常常采用流方式读取xml,该方式简单直观,容易理解.之后遇到了需要修改xml并重新写回的情况,流方式就显得捉襟见肘了. sax方式 ...

  4. 关于Lombok和自动生成get set方法

    在Java开发的项目里面免不了要用很多的get set 以及toString之类的方法,有时候确实是很繁琐而且做着重复共同工作,我们有没有办法来简化这个过程呢,当然有. Lombok就可以很好的解决这 ...

  5. Java并发包中线程池ThreadPoolExecutor原理探究

    一.线程池简介 线程池的使用主要是解决两个问题:①当执行大量异步任务的时候线程池能够提供更好的性能,在不使用线程池时候,每当需要执行异步任务的时候直接new一个线程来运行的话,线程的创建和销毁都是需要 ...

  6. POJ 2455:Secret Milking Machine(二分+最大流)

    http://poj.org/problem?id=2455 题意:给出n个点和m条无向路,每条路都有一个长度.从1点到n点要走t次两两互不重合的路.求出每条1->n的路中相邻两点最大值的最小值 ...

  7. 自定义docker镜像

    1.拉去centos当作基础镜像 2.重要!!!必须使用超级权限启动: docker run --privileged -ti --name latestCenos  centos /usr/sbin ...

  8. django基础知识之URLconf:

    URLconf 在settings.py文件中通过ROOT_URLCONF指定根级url的配置 urlpatterns是一个url()实例的列表 一个url()对象包括: 正则表达式 视图函数 名称n ...

  9. 页面的隐藏或显示:hidden与visibilityState

    我们在很多地方都需要判断用户是不是在当前页面,如果离开了当前页面我们需要捕捉到并进行一些操作. 例如:当视频处于播放状态时,我们需要判断用户是不是在当前页面以继续播放,如果离开了我们需要暂停播放. 有 ...

  10. .NetCore应用多个target framework

    <Project Sdk="Microsoft.NET.Sdk.Web"> <PropertyGroup> <TargetFrameworks> ...