一级做a免费观看视频网站,如何优化搜索引擎,图案设计网,北京网站建设公司怎么排版序言
前面文章介绍了在Spring中多种创建Bean实例的方式#xff0c;包括采用FactoryBean的方式创建对象、使用反射创建对象、自定义BeanFactoryPostProcessor。 这篇文章继续介绍Spring中创建Bean的形式之一——factoryMethod。方法用的不多#xff0c;感兴趣可以当扩展了解。…序言
前面文章介绍了在Spring中多种创建Bean实例的方式包括采用FactoryBean的方式创建对象、使用反射创建对象、自定义BeanFactoryPostProcessor。 这篇文章继续介绍Spring中创建Bean的形式之一——factoryMethod。方法用的不多感兴趣可以当扩展了解。
doCreateBean
同样是doCreateBean下的createBeanInstance()。
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, Nullable Object[] args)throws BeanCreationException {// Instantiate the bean.//这个beanWrapper是用来持有创建出来的bean对象的BeanWrapper instanceWrapper null;//如果是单例对象从factoryBeanInstanceCache缓存中移除该信息if (mbd.isSingleton()) {// 如果是单例对象从factoryBean实例缓存中移除当前bean定义信息instanceWrapper this.factoryBeanInstanceCache.remove(beanName);}// 没有就创建实例if (instanceWrapper null) {// 根据执行bean使用对应的策略创建新的实例如工厂方法构造函数主动注入、简单初始化instanceWrapper createBeanInstance(beanName, mbd, args);}// 去除无用代码..... }createBeanInstance 我们在上篇中介绍了通过Supplier创建Bean的方式而代码中Supplier判断的下面就是我们本篇文章要介绍的通过factoryMethod方式创建Bean。
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, Nullable Object[] args) {// Make sure bean class is actually resolved at this point.// 锁定class根据设置的class属性或者根据className来解析classClass? beanClass resolveBeanClass(mbd, beanName);// 如果beanClass null// 并且访问修饰符不是public修饰 抛异常if (beanClass ! null !Modifier.isPublic(beanClass.getModifiers()) !mbd.isNonPublicAccessAllowed()) {throw new BeanCreationException(mbd.getResourceDescription(), beanName,Bean class isnt public, and non-public access not allowed: beanClass.getName());}// 获取定义的SupplierSupplier? instanceSupplier mbd.getInstanceSupplier();if (instanceSupplier ! null) {return obtainFromSupplier(instanceSupplier, beanName);}if (mbd.getFactoryMethodName() ! null) {return instantiateUsingFactoryMethod(beanName, mbd, args);}return instantiateBean(beanName, mbd);}测试类 我们这里准备两个测试类一个是静态工厂的方式一个是普通的方式进行Bean实例的创建。
PersonStaticFactory 通过静态方法创建Person对象。
public class PersonStaticFactory {public static Person getPerson(String name){Person person new Person();person.setName(name);person.setAge(22);return person;}
}PersonInstanceFactory 普通方法创建Bean实例。
public class PersonInstanceFactory {public Person getPerson(String name){Person person new Person();person.setAge(18);person.setName(name);return person;}
}Person 平平无奇Person对象。
public class Person {private String name;private int age;// 省略 get set toString和构造函数
}factoryMethod.xml
?xml version1.0 encodingUTF-8?
beans xmlnshttp://www.springframework.org/schema/beansxmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsdbean idpersonInstanceFactory classorg.springframework.factoryMethod.PersonInstanceFactory/beanbean idperson classorg.springframework.factoryMethod.PersonStaticFactory factory-methodgetPersonconstructor-arg namename valuezhangsan//beanbean idperson2 classorg.springframework.factoryMethod.Personfactory-beanpersonInstanceFactory factory-methodgetPersonconstructor-arg namename valuewangwu/constructor-arg/bean
/beansmain 测试main方法让我们看看在getBean()中都做了什么操作。
public static void main(String[] args) {ApplicationContext ac new ClassPathXmlApplicationContext(factoryMethod.xml);Person person1 (Person) ac.getBean(person);Person person2 (Person)ac.getBean(person2);System.out.println(person1);System.out.println(person2);
}instantiateUsingFactoryMethod()
方法入口。我们这里以 person2 的创建为例。
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, Nullable Object[] args) {// Make sure bean class is actually resolved at this point.// 锁定class根据设置的class属性或者根据className来解析classClass? beanClass resolveBeanClass(mbd, beanName);// 如果beanClass null// 并且访问修饰符不是public修饰 抛异常if (beanClass ! null !Modifier.isPublic(beanClass.getModifiers()) !mbd.isNonPublicAccessAllowed()) {throw new BeanCreationException(mbd.getResourceDescription(), beanName,Bean class isnt public, and non-public access not allowed: beanClass.getName());}// 获取定义的SupplierSupplier? instanceSupplier mbd.getInstanceSupplier();if (instanceSupplier ! null) {return obtainFromSupplier(instanceSupplier, beanName);}if (mbd.getFactoryMethodName() ! null) {return instantiateUsingFactoryMethod(beanName, mbd, args);}return instantiateBean(beanName, mbd);}让我们顺着Supplier的判断顺着往下看。 此时来到了person对象的加载根据xml文件的配置此时的beanName所指的person2是Person对象。
创建构造器解析器对象调用instantiateUsingFactoryMethod()方法进行解析。
protected BeanWrapper instantiateUsingFactoryMethod(String beanName, RootBeanDefinition mbd, Nullable Object[] explicitArgs) {return new ConstructorResolver(this).instantiateUsingFactoryMethod(beanName, mbd, explicitArgs);
}instantiateUsingFactoryMethod
源码很长我们这块分段来看。 代码中的第一部分主要是判断当前的BeanDefinition是否包含factoryBeanName并以此来区分是否是static修饰并设置标志位。
public BeanWrapper instantiateUsingFactoryMethod(String beanName, RootBeanDefinition mbd, Nullable Object[] explicitArgs) {// 创建 BeanWrapperImpl 对象BeanWrapperImpl bw new BeanWrapperImpl();//初始化beanWrapper对象这里面获取了所有的customerEditor进行注册this.beanFactory.initBeanWrapper(bw);Object factoryBean;Class? factoryClass;boolean isStatic;//获取factoryBeanNameString factoryBeanName mbd.getFactoryBeanName();//如果factoryBeanName不为nullif (factoryBeanName ! null) {//如果配置的 factoryBeanName与beanName名称相同则抛出异常if (factoryBeanName.equals(beanName)) {throw new BeanDefinitionStoreException(mbd.getResourceDescription(), beanName,factory-bean reference points back to the same bean definition);}//从工厂中获取当前factoryBeanName对应的bean对象factoryBean this.beanFactory.getBean(factoryBeanName);//如果是单例模式并且容器中已经存在该bean对象则抛出异常if (mbd.isSingleton() this.beanFactory.containsSingleton(beanName)) {//意味着此时工厂中已经包含了beanName对应的实例对象再生成则重复了。抛出异常throw new ImplicitlyAppearedSingletonException();}// 获取factoryBean的Class对象factoryClass factoryBean.getClass();// 标志位设置为false 表示不是静态方法。isStatic false;}else {// Its a static factory method on the bean class.// 这是bean类上的静态工厂方法// 如果mbd没有指定bean类if (!mbd.hasBeanClass()) {throw new BeanDefinitionStoreException(mbd.getResourceDescription(), beanName,bean definition declares neither a bean class nor a factory-bean reference);}factoryBean null;factoryClass mbd.getBeanClass();// 标志位设置为 true 表示为静态方法。isStatic true;}} 我们这里的person2是普通工厂并且会在代码this.beanFactory.getBean(factoryBeanName);中通过factoryBeanName来创建我们所配置的PersonInstanceFactory对象。
声明变量并看调用getBean()方法时是否传了显示的参数。我们这里调用getBean时什么都没传。所以expliciArgs为null。 //声明一个要使用的工厂方法默认为nullMethod factoryMethodToUse null;//声明一个用于存储不同形式的参数值的ArgumentsHolder默认为nullArgumentsHolder argsHolderToUse null;// 声明一个要使用的参数值数组,默认为nullObject[] argsToUse null;// 如果调用getBean方法时显示的传了参数则此时explicitArgs ! null// 则argsToUser引用explicitArgsif (explicitArgs ! null) {argsToUse explicitArgs;}else {//如果没有传// 声明一个要解析的args[] 默认为null。Object[] argsToResolve null;synchronized (mbd.constructorArgumentLock) {// factoryMethodToUse引用mbd中已经解析构造器或工厂方法对象factoryMethodToUse (Method) mbd.resolvedConstructorOrFactoryMethod;//如果此时factoryMethodToUse不为null并且mbd已解析构造函数参数默认为falseif (factoryMethodToUse ! null mbd.constructorArgumentsResolved) {// Found a cached factory method...//找到了缓存工厂方法//argsToUse引用完全解析构的造器函数参数argsToUse mbd.resolvedConstructorArguments;//如果依然为nullif (argsToUse null) {//引用mbd准备好的构造函数参数值argsToResolve mbd.preparedConstructorArguments;}}}//如果argsToResolve不为nullif (argsToResolve ! null) {//解析mbd中缓存好的参数值argsToUse resolvePreparedArguments(beanName, mbd, bw, factoryMethodToUse, argsToResolve, true);}}获取所有候选方法并进行过滤。
// 如果没解析过就获取factoryClass的用户定义类型因为此时factoryClass可能是CGLIB动态代理类型// 所以要获取用父类的类型。如果工厂方法是唯一的就是没重载的就获取解析的工厂方法如果不为空就添加到一个不可变列表里// 如果为空的话就要去找出factoryClass的以及父类的所有的方法进一步找出方法修饰符一致且名字跟工厂方法名字相同的且是bean注解的方法并放入列表里。if (factoryMethodToUse null || argsToUse null) {// Need to determine the factory method...// Try all methods with this name to see if they match the given arguments.// 获取工厂类的所有候选工厂方法factoryClass ClassUtils.getUserClass(factoryClass);// 定义一个用于存储候选方法的集合ListMethod candidates null;// 如果mbd所配置工厂方法时唯一if (mbd.isFactoryMethodUnique) {// 如果factoryMethodToUse为nullif (factoryMethodToUse null) {// 获取mbd解析后的工厂方法对象factoryMethodToUse mbd.getResolvedFactoryMethod();}// 如果factoryMethodToUse不为nullif (factoryMethodToUse ! null) {// Collections.singletonList()返回的是不可变的集合但是这个长度的集合只有1可以减少内存空间。但是返回的值依然是Collections的内部实现类// 同样没有add的方法调用addset方法会报错// 新建一个不可变只能存一个对象的集合将factoryMethodToUse添加进行然后让candidateList引用该集合candidates Collections.singletonList(factoryMethodToUse);}}// 如果candidateList为nullif (candidates null) {// 让candidateList引用一个新的ArrayListcandidates new ArrayList();// 根据mbd的是否允许访问非公共构造函数和方法标记【RootBeanDefinition.isNonPublicAccessAllowed】来获取factoryClass的所有候选方法Method[] rawCandidates getCandidateMethods(factoryClass, mbd);// 遍历rawCandidates,元素名为candidatefor (Method candidate : rawCandidates) {// 如果candidate的修饰符与isStatic一致且candidate有资格作为mdb的工厂方法if (Modifier.isStatic(candidate.getModifiers()) isStatic mbd.isFactoryMethod(candidate)) {// 将candidate添加到candidateList中candidates.add(candidate);}}}// 候选方法只有一个且没有构造函数时就直接使用该候选方法生成与beanName对应的Bean对象封装到bw中返回出去// 如果candidateList只有一个元素且没有传入构造函数值且mbd也没有构造函数参数值if (candidates.size() 1 explicitArgs null !mbd.hasConstructorArgumentValues()) {// 获取candidateList中唯一的方法Method uniqueCandidate candidates.get(0);// 如果uniqueCandidate是不需要参数if (uniqueCandidate.getParameterCount() 0) {// 让mbd缓存uniqueCandidate【{link RootBeanDefinition#factoryMethodToIntrospect}】mbd.factoryMethodToIntrospect uniqueCandidate;// 使用mdb的构造函数字段的通用锁【{link RootBeanDefinition#constructorArgumentLock}】进行加锁以保证线程安全synchronized (mbd.constructorArgumentLock) {// 让mbd缓存已解析的构造函数或工厂方法【{link RootBeanDefinition#resolvedConstructorOrFactoryMethod}】mbd.resolvedConstructorOrFactoryMethod uniqueCandidate;// 让mbd标记构造函数参数已解析【{link RootBeanDefinition#constructorArgumentsResolved}】mbd.constructorArgumentsResolved true;// 让mbd缓存完全解析的构造函数参数【{link RootBeanDefinition#resolvedConstructorArguments}】mbd.resolvedConstructorArguments EMPTY_ARGS;}// 使用factoryBean生成的与beanName对应的Bean对象,并将该Bean对象保存到bw中bw.setBeanInstance(instantiate(beanName, mbd, factoryBean, uniqueCandidate, EMPTY_ARGS));// 将bw返回出去return bw;}}// 如果有多个工厂方法的话进行排序操作if (candidates.size() 1) { // explicitly skip immutable singletonListcandidates.sort(AutowireUtils.EXECUTABLE_COMPARATOR);}因为所有的对象的父类都是Object所以会获取很多Object中的方法经过过滤后这里candidates只保留了getPerson() 过滤后只剩getPerson()方法。 根据candidate数量如果只有一个且符合条件则进行对象的创建如果有多个则进行排序。 如果有构造函数则获取构造函数的属性和值。 // 候选方法只有一个且没有构造函数时就直接使用该候选方法生成与beanName对应的Bean对象封装到bw中返回出去// 如果candidateList只有一个元素且没有传入构造函数值且mbd也没有构造函数参数值if (candidates.size() 1 explicitArgs null !mbd.hasConstructorArgumentValues()) {// 获取candidateList中唯一的方法Method uniqueCandidate candidates.get(0);// 如果uniqueCandidate是不需要参数if (uniqueCandidate.getParameterCount() 0) {// 让mbd缓存uniqueCandidate【{link RootBeanDefinition#factoryMethodToIntrospect}】mbd.factoryMethodToIntrospect uniqueCandidate;// 使用mdb的构造函数字段的通用锁【{link RootBeanDefinition#constructorArgumentLock}】进行加锁以保证线程安全synchronized (mbd.constructorArgumentLock) {// 让mbd缓存已解析的构造函数或工厂方法【{link RootBeanDefinition#resolvedConstructorOrFactoryMethod}】mbd.resolvedConstructorOrFactoryMethod uniqueCandidate;// 让mbd标记构造函数参数已解析【{link RootBeanDefinition#constructorArgumentsResolved}】mbd.constructorArgumentsResolved true;// 让mbd缓存完全解析的构造函数参数【{link RootBeanDefinition#resolvedConstructorArguments}】mbd.resolvedConstructorArguments EMPTY_ARGS;}// 使用factoryBean生成的与beanName对应的Bean对象,并将该Bean对象保存到bw中bw.setBeanInstance(instantiate(beanName, mbd, factoryBean, uniqueCandidate, EMPTY_ARGS));// 将bw返回出去return bw;}}// 如果有多个工厂方法的话进行排序操作if (candidates.size() 1) { // explicitly skip immutable singletonListcandidates.sort(AutowireUtils.EXECUTABLE_COMPARATOR);}// ConstructorArgumentValues构造函数参数值的Holder,通常作为BeanDefinition的一部分,支持构造函数参数列表中特定索引的值// 以及按类型的通用参数匹配// 定义一个用于存放解析后的构造函数参数值的ConstructorArgumentValues对象ConstructorArgumentValues resolvedValues null;// 定义一个mbd是否支持使用构造函数进行自动注入的标记boolean autowiring (mbd.getResolvedAutowireMode() AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR);// 定义一个最小类型差异权重默认是Integer最大值int minTypeDiffWeight Integer.MAX_VALUE;// 定义一个存储摸棱两可的工厂方法的Set集合,以用于抛出BeanCreationException时描述异常信息SetMethod ambiguousFactoryMethods null;// 定义一个最少参数数默认为0int minNrOfArgs;// 如果explicitArgs不为nullif (explicitArgs ! null) {// minNrOfArgs引用explicitArgs的数组长度minNrOfArgs explicitArgs.length;}else {// We dont have arguments passed in programmatically, so we need to resolve the// arguments specified in the constructor arguments held in the bean definition.// 我们没有以编程方式传递参数因此我们需要解析BeanDefinition中保存的构造函数参数中指定的参数// 如果mbd有构造函数参数值if (mbd.hasConstructorArgumentValues()) {// 获取mbd的构造函数参数值HolderConstructorArgumentValues cargs mbd.getConstructorArgumentValues();// 对resolvedValues实例化resolvedValues new ConstructorArgumentValues();// 将cargs解析后值保存到resolveValues中并让minNrOfArgs引用解析后的最小(索引参数值数泛型参数值数)minNrOfArgs resolveConstructorArguments(beanName, mbd, bw, cargs, resolvedValues);}else {// 意味着mbd没有构造函数参数值时将minNrOfArgs设为0minNrOfArgs 0;}}获取构造函数的属性和值。 获取参数列表并进行封装。 // 定义一个用于UnsatisfiedDependencyException的列表LinkedListUnsatisfiedDependencyException causes null;// 遍历candidates元素名为candidatefor (Method candidate : candidates) {// 获取参数的个数int parameterCount candidate.getParameterCount();// 如果paramTypes的数组长度大于等于minNrOfArgsif (parameterCount minNrOfArgs) {// ArgumentsHolder:用于保存参数数组// 定义一个封装参数数组的ArgumentsHolder对象ArgumentsHolder argsHolder;// 获取candidate的参数类型数组Class?[] paramTypes candidate.getParameterTypes();// 如果explicitArgs不为nullif (explicitArgs ! null) {// Explicit arguments given - arguments length must match exactly.// 给定的显示参数-参数长度必须完全匹配// 如果paramTypes的长度与explicitArgsd额长度不相等if (paramTypes.length ! explicitArgs.length) {// 跳过当次循环中剩下的步骤执行下一次循环。continue;}// 实例化argsHolder封装explicitArgs到argsHolderargsHolder new ArgumentsHolder(explicitArgs);}else {// Resolved constructor arguments: type conversion and/or autowiring necessary.// 已解析的构造函数参数:类型转换 and/or 自动注入时必须的try {// 定义用于保存参数名的数组String[] paramNames null;// 获取beanFactory的参数名发现器ParameterNameDiscoverer pnd this.beanFactory.getParameterNameDiscoverer();// 如果pnd不为nullif (pnd ! null) {// 通过pnd解析candidate的参数名paramNames pnd.getParameterNames(candidate);}// 将resolvedValues转换成一个封装着参数数组ArgumentsHolder实例当candidate只有一个时支持可在抛// 出没有此类BeanDefinition的异常返回null而不抛出异常argsHolder createArgumentArray(beanName, mbd, resolvedValues, bw,paramTypes, paramNames, candidate, autowiring, candidates.size() 1);}// 捕捉UnsatisfiedDependencyExceptioncatch (UnsatisfiedDependencyException ex) {if (logger.isTraceEnabled()) {logger.trace(Ignoring factory method [ candidate ] of bean beanName : ex);}// Swallow and try next overloaded factory method.// 吞下并尝试下一个重载的工厂方法// 如果cause为nullif (causes null) {// 对cause进行实例化成LinkedList对象causes new LinkedList();}// 将ex添加到causes中causes.add(ex);// 跳过本次循环体中余下尚未执行的语句立即进行下一次的循环continue;}}Spring会计算权重选出符合条件的方法来进行实例对象的创建。 // mbd支持的构造函数解析模式,默认使用宽松模式:// 1. 严格模式如果摸棱两可的构造函数在转换参数时都匹配则抛出异常// 2. 宽松模式将使用最接近类型匹配的构造函数// 如果bd支持的构造函数解析模式时宽松模式,引用获取类型差异权重值否则引用获取Assignabliity权重值int typeDiffWeight (mbd.isLenientConstructorResolution() ?argsHolder.getTypeDifferenceWeight(paramTypes) : argsHolder.getAssignabilityWeight(paramTypes));// Choose this factory method if it represents the closest match.// 如果它表示最接近的匹配项则选择此工厂方法// 如果typeDiffWeight小于minTypeDiffWeightif (typeDiffWeight minTypeDiffWeight) {// 让factoryMethodToUser引用candidatefactoryMethodToUse candidate;// 让argsHolderToUse引用argsHolderargsHolderToUse argsHolder;// 让argToUse引用argsHolder的经过转换后参数值数组argsToUse argsHolder.arguments;// 让minTypeDiffWeight引用typeDiffWeightminTypeDiffWeight typeDiffWeight;// 将ambiguousFactoryMethods置为nullambiguousFactoryMethods null;}// Find out about ambiguity: In case of the same type difference weight// for methods with the same number of parameters, collect such candidates// and eventually raise an ambiguity exception.// However, only perform that check in non-lenient constructor resolution mode,// and explicitly ignore overridden methods (with the same parameter signature).// 找出歧义:如果具有相同数量参数的方法具有相同的类型差异权重则收集此类候选想并最终引发歧义异常。// 但是仅在非宽松构造函数解析模式下执行该检查并显示忽略的方法具有相同的参数签名// 如果factoryMethodToUse不为null且typeDiffWeight与minTypeDiffWeight相等// 且mbd指定了严格模式解析构造函数且paramTypes的数组长度与factoryMethodToUse的参数数组长度相等且// paramTypes的数组元素与factoryMethodToUse的参数数组元素不相等else if (factoryMethodToUse ! null typeDiffWeight minTypeDiffWeight !mbd.isLenientConstructorResolution() paramTypes.length factoryMethodToUse.getParameterCount() !Arrays.equals(paramTypes, factoryMethodToUse.getParameterTypes())) {// 如果ambiguousFactoryMethods为nullif (ambiguousFactoryMethods null) {// 初始化ambiguousFactoryMethods为LinkedHashSet实例ambiguousFactoryMethods new LinkedHashSet();// 将factoryMethodToUse添加到ambiguousFactoryMethods中ambiguousFactoryMethods.add(factoryMethodToUse);}// 将candidate添加到ambiguousFactoryMethods中ambiguousFactoryMethods.add(candidate);}}}// 整合无法筛选出候选方法或者无法解析出要使用的参数值的情况抛出BeanCreationException并加以描述// 如果factoryMethodToUse为null或者argsToUse为nullif (factoryMethodToUse null || argsToUse null) {// 如果causes不为nullif (causes ! null) {// 从cause中移除最新的UnsatisfiedDependencyExceptionUnsatisfiedDependencyException ex causes.removeLast();// 遍历causes,元素为causefor (Exception cause : causes) {// 将cause添加到该Bean工厂的抑制异常列表【{link DefaultSingletonBeanRegistry#suppressedExceptions】中this.beanFactory.onSuppressedException(cause);}// 重新抛出exthrow ex;}// 定义一个用于存放参数类型的简单类名的ArrayList对象长度为minNrOfArgsListString argTypes new ArrayList(minNrOfArgs);// 如果explicitArgs不为nullif (explicitArgs ! null) {// 遍历explicitArgs.元素为argfor (Object arg : explicitArgs) {// 如果arg不为null将arg的简单类名添加到argTypes中否则将null添加到argTypes中argTypes.add(arg ! null ? arg.getClass().getSimpleName() : null);}}// 如果resolvedValues不为nullelse if (resolvedValues ! null) {// 定义一个用于存放resolvedValues的泛型参数值和方法参数值的LinkedHashSet对象SetValueHolder valueHolders new LinkedHashSet(resolvedValues.getArgumentCount());// 将resolvedValues的方法参数值添加到valueHolders中valueHolders.addAll(resolvedValues.getIndexedArgumentValues().values());// 将resolvedValues的泛型参数值添加到valueHolders中valueHolders.addAll(resolvedValues.getGenericArgumentValues());// 遍历valueHolders元素为valuefor (ValueHolder value : valueHolders) {// 如果value的参数类型不为null就获取该参数类型的简单类名否则(如果value的参数值不为null即获取该参数值的简单类名;否则为null)String argType (value.getType() ! null ? ClassUtils.getShortName(value.getType()) :(value.getValue() ! null ? value.getValue().getClass().getSimpleName() : null));// 将argType添加到argTypes中argTypes.add(argType);}}// 将argType转换成字符串以,隔开元素.用于描述Bean创建异常String argDesc StringUtils.collectionToCommaDelimitedString(argTypes);// 抛出BeanCreationException:找不到匹配的工厂方法工厂Beanmbd.getFactoryBeanName();工厂方法// mbd.getFactoryMethodName()(argDesc).检查是否存在具体指定名称和参数的方法并且该方法时静态/非静态的.throw new BeanCreationException(mbd.getResourceDescription(), beanName,No matching factory method found: (mbd.getFactoryBeanName() ! null ?factory bean mbd.getFactoryBeanName() ; : ) factory method mbd.getFactoryMethodName() ( argDesc ). Check that a method with the specified name (minNrOfArgs 0 ? and arguments : ) exists and that it is (isStatic ? static : non-static) .);}// 如果factoryMethodToUse时无返回值方法else if (void.class factoryMethodToUse.getReturnType()) {throw new BeanCreationException(mbd.getResourceDescription(), beanName,Invalid factory method mbd.getFactoryMethodName() : needs to have a non-void return type!);}// 如果ambiguousFactoryMethods不为nullelse if (ambiguousFactoryMethods ! null) {throw new BeanCreationException(mbd.getResourceDescription(), beanName,Ambiguous factory method matches found in bean beanName (hint: specify index/type/name arguments for simple parameters to avoid type ambiguities): ambiguousFactoryMethods);}// 将筛选出来的工厂方法和解析出来的参数值缓存到mdb中// 如果explicitArgs为null且argsHolderToUser不为nullif (explicitArgs null argsHolderToUse ! null) {// 让mbd的唯一方法候选【{link RootBeanDefinition#factoryMethodToIntrospect}】引用factoryMethodToUsembd.factoryMethodToIntrospect factoryMethodToUse;// 将argsHolderToUse所得到的参数值属性缓存到mbd对应的属性中argsHolderToUse.storeCache(mbd, factoryMethodToUse);}}// 使用factoryBean生成与beanName对应的Bean对象,并将该Bean对象保存到bw中bw.setBeanInstance(instantiate(beanName, mbd, factoryBean, factoryMethodToUse, argsToUse));// 将bw返回出去return bw;