bean的创建第二部分 寻找bean的工厂方法实例化
Posted honger
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了bean的创建第二部分 寻找bean的工厂方法实例化相关的知识,希望对你有一定的参考价值。
instanceWrapper = createBeanInstance(beanName, mbd, args); AbstractAutowireCapableBeanFactory.createBeanInstance protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, Object[] args) { // Make sure bean class is actually resolved at this point.确保实际已经解析了beanClass,如果是表达式,会进行表达式的运算得到className 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()); } //如果存在工厂方法,那么说明需要通过静态工厂的方式获取bean 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... 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.instantiateUsingFactoryMethod protected BeanWrapper instantiateUsingFactoryMethod( String beanName, RootBeanDefinition mbd, Object[] explicitArgs) { return new ConstructorResolver(this).instantiateUsingFactoryMethod(beanName, mbd, explicitArgs); } ConstructorResolver.instantiateUsingFactoryMethod public BeanWrapper instantiateUsingFactoryMethod( final String beanName, final RootBeanDefinition mbd, final Object[] explicitArgs) { BeanWrapperImpl bw = new BeanWrapperImpl(); //初始化这个bean包装器,内部给这个包装器设置了类型转化器和自定的转化器 this.beanFactory.initBeanWrapper(bw); Object factoryBean; Class<?> factoryClass; boolean isStatic; String factoryBeanName = mbd.getFactoryBeanName(); //如果存在factoryBeanName 比如<bean id="helloWorld" factory-bean="helloWorld" factory-method="getSayHi"></bean> if (factoryBeanName != null) { //如果工厂bean的名字和自己相同,那么直接抛错 if (factoryBeanName.equals(beanName)) { throw new BeanDefinitionStoreException(mbd.getResourceDescription(), beanName, "factory-bean reference points back to the same bean definition"); } //使用getBean获取到依赖的那个工厂bean factoryBean = this.beanFactory.getBean(factoryBeanName); if (factoryBean == null) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "factory-bean ‘" + factoryBeanName + "‘ (or a BeanPostProcessor involved) returned null"); } if (mbd.isSingleton() && this.beanFactory.containsSingleton(beanName)) { throw new IllegalStateException("About-to-be-created singleton instance implicitly appeared " + "through the creation of the factory bean that its bean definition points to"); } factoryClass = factoryBean.getClass(); isStatic = false; } else { // It‘s a static factory method on the bean class. 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(); isStatic = true; } Method factoryMethodToUse = null; ArgumentsHolder argsHolderToUse = null; Object[] argsToUse = null; //如果用户已经指定了构造参数,那么直接使用用户指定的构造参数 if (explicitArgs != null) { argsToUse = explicitArgs; } else { Object[] argsToResolve = null; synchronized (mbd.constructorArgumentLock) { //获取已经解析后的构造器或者工厂方法 factoryMethodToUse = (Method) mbd.resolvedConstructorOrFactoryMethod; //如果已经解析好了,那么尝试从缓存中获取参数 if (factoryMethodToUse != null && mbd.constructorArgumentsResolved) { // Found a cached factory method... argsToUse = mbd.resolvedConstructorArguments; //如果缓存中没有,那么就从准备的(也就是解析配置文件时,BeanDefinition存储的参数)构造参数中获取,这个时候的参数还是原始(配置文件中)的,没有进行类型转换的参数 if (argsToUse == null) { argsToResolve = mbd.preparedConstructorArguments; } } } if (argsToResolve != null) { //解析准备的配置参数 argsToUse = resolvePreparedArguments(beanName, mbd, bw, factoryMethodToUse, argsToResolve); } } //如果没有缓存,那么说明这是第一次访问,需要从头开始解析 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. //判断是否被cglib代理过的,如果代理过,那么就返回其父类 factoryClass = ClassUtils.getUserClass(factoryClass); //获取这个类定义的所有方法 Method[] rawCandidates = getCandidateMethods(factoryClass, mbd); List<Method> candidateSet = new ArrayList<Method>(); for (Method candidate : rawCandidates) { //获取工厂方法 if (Modifier.isStatic(candidate.getModifiers()) == isStatic && mbd.isFactoryMethod(candidate)) { candidateSet.add(candidate); } } Method[] candidates = candidateSet.toArray(new Method[candidateSet.size()]); //给重载的方法排序,public修饰和参数长的排在前面 AutowireUtils.sortFactoryMethods(candidates); ConstructorArgumentValues resolvedValues = null; boolean autowiring = (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR); int minTypeDiffWeight = Integer.MAX_VALUE; Set<Method> ambiguousFactoryMethods = null; int minNrOfArgs; if (explicitArgs != null) { minNrOfArgs = explicitArgs.length; } else { // We don‘t have arguments passed in programmatically, so we need to resolve the // arguments specified in the constructor arguments held in the bean definition. //如果用户没有传递参数进来,那么我们需要获取配置的参数 ConstructorArgumentValues cargs = mbd.getConstructorArgumentValues(); resolvedValues = new ConstructorArgumentValues(); //解析构造参数,通过BeanDefinitionValueResolver进行解析,解析好后放置到resolvedValues中,这里主要是将beanref的解析好和以下表达式什么的,没有进行参数类型的转换。 minNrOfArgs = resolveConstructorArguments(beanName, mbd, bw, cargs, resolvedValues); } List<Exception> causes = null; for (int i = 0; i < candidates.length; i++) { Method candidate = candidates[i]; //获取当前方法的参数类型 Class<?>[] paramTypes = candidate.getParameterTypes(); if (paramTypes.length >= minNrOfArgs) { ArgumentsHolder argsHolder; if (resolvedValues != null) { // Resolved constructor arguments: type conversion and/or autowiring necessary. try { //获取这些方法的参数名 String[] 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 factory method [" + candidate + "] of bean ‘" + beanName + "‘: " + ex); } if (i == candidates.length - 1 && argsHolderToUse == null) { if (causes != null) { for (Exception cause : causes) { this.beanFactory.onSuppressedException(cause); } } throw ex; } else { // Swallow and try next overloaded factory method. if (causes == null) { causes = new LinkedList<Exception>(); } 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 factory method if it represents the closest match. if (typeDiffWeight < minTypeDiffWeight) { factoryMethodToUse = candidate; argsHolderToUse = argsHolder; argsToUse = argsHolder.arguments; minTypeDiffWeight = typeDiffWeight; ambiguousFactoryMethods = 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). else if (factoryMethodToUse != null && typeDiffWeight == minTypeDiffWeight && !mbd.isLenientConstructorResolution() && paramTypes.length == factoryMethodToUse.getParameterTypes().length && !Arrays.equals(paramTypes, factoryMethodToUse.getParameterTypes())) { if (ambiguousFactoryMethods == null) { ambiguousFactoryMethods = new LinkedHashSet<Method>(); ambiguousFactoryMethods.add(factoryMethodToUse); } ambiguousFactoryMethods.add(candidate); } } } if (factoryMethodToUse == null) { List<String> argTypes = new ArrayList<String>(minNrOfArgs); if (explicitArgs != null) { for (Object arg : explicitArgs) { argTypes.add(arg != null ? arg.getClass().getSimpleName() : "null"); } } else { Set<ValueHolder> valueHolders = new LinkedHashSet<ValueHolder>(resolvedValues.getArgumentCount()); valueHolders.addAll(resolvedValues.getIndexedArgumentValues().values()); valueHolders.addAll(resolvedValues.getGenericArgumentValues()); for (ValueHolder value : valueHolders) { String argType = (value.getType() != null ? ClassUtils.getShortName(value.getType()) : (value.getValue() != null ? value.getValue().getClass().getSimpleName() : "null")); argTypes.add(argType); } } String argDesc = StringUtils.collectionToCommaDelimitedString(argTypes); 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") + "."); } 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!"); } else 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); } if (explicitArgs == null && argsHolderToUse != null) { argsHolderToUse.storeCache(mbd, factoryMethodToUse); } } try { Object beanInstance; if (System.getSecurityManager() != null) { final Object fb = factoryBean; final Method factoryMethod = factoryMethodToUse; final Object[] args = argsToUse; beanInstance = AccessController.doPrivileged(new PrivilegedAction<Object>() { @Override public Object run() { return beanFactory.getInstantiationStrategy().instantiate( mbd, beanName, beanFactory, fb, factoryMethod, args); } }, beanFactory.getAccessControlContext()); } else { beanInstance = this.beanFactory.getInstantiationStrategy().instantiate( mbd, beanName, this.beanFactory, factoryBean, factoryMethodToUse, argsToUse); } if (beanInstance == null) { return null; } bw.setWrappedInstance(beanInstance); return bw; } catch (Throwable ex) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Bean instantiation via factory method failed", ex); } } ConstructorResolver.resolvePreparedArguments private Object[] resolvePreparedArguments( String beanName, RootBeanDefinition mbd, BeanWrapper bw, Member methodOrCtor, Object[] argsToResolve) { //获取构造方法或者工厂方法的参数类型 Class<?>[] paramTypes = (methodOrCtor instanceof Method ? ((Method) methodOrCtor).getParameterTypes() : ((Constructor<?>) methodOrCtor).getParameterTypes()); //获取自定义的类型转化器,如果没有就是用bean包装器·,这个包装器在上面已经注册了默认的转化器和自定的转化器。 TypeConverter converter = (this.beanFactory.getCustomTypeConverter() != null ? this.beanFactory.getCustomTypeConverter() : bw);、 //构建BeanDefinition值的解析器,用于转化value BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this.beanFactory, beanName, mbd, converter); Object[] resolvedArgs = new Object[argsToResolve.length]; for (int argIndex = 0; argIndex < argsToResolve.length; argIndex++) { //获取当前下标参数值 Object argValue = argsToResolve[argIndex]; //包装成方法参数对象,持有对应的方法,参数的位置 MethodParameter methodParam = MethodParameter.forMethodOrConstructor(methodOrCtor, argIndex); //解析这个方法所在的类,参数的类型 GenericTypeResolver.resolveParameterType(methodParam, methodOrCtor.getDeclaringClass()); //参数是AutowiredArgumentMarker只只是个标记类,标记为自动装配的参数,这里会解析@Value注解的参数,还有会根据字段的类型去包装成某些延迟获取数据的对象,比如DependencyObjectFactory(依赖工厂bean,这种类型字段可以通过getObject获取数据),这里是方法参数的获取所以不用去管field的。最后内部会通过DefaultListableBeanFactory.doResolveDependency方法根据参数类型去获取bean if (argValue instanceof AutowiredArgumentMarker) { argValue = resolveAutowiredArgument(methodParam, beanName, null, converter); } //这种类型数据一般是在解析xml配置的时候生成的,比如xml中的ref指定的bean会包装成RuntimeBeanReference,当spring看到这种类型的时候就知道,我要去BeanFactory中寻找叫这个名字的bean else if (argValue instanceof BeanMetadataElement) { //使用上面new出来的BeanDefinitionValueResolver进行解析 argValue = valueResolver.resolveValueIfNecessary("constructor argument", argValue); } //如果只是普通的字符串,那么经过表达式解析器之后直接返回 else if (argValue instanceof String) { argValue = this.beanFactory.evaluateBeanDefinitionString((String) argValue, mbd); } Class<?> paramType = paramTypes[argIndex]; try { //将得到的数据进行类型转换 resolvedArgs[argIndex] = converter.convertIfNecessary(argValue, paramType, methodParam); } catch (TypeMismatchException ex) { String methodType = (methodOrCtor instanceof Constructor ? "constructor" : "factory method"); throw new UnsatisfiedDependencyException( mbd.getResourceDescription(), beanName, argIndex, paramType, "Could not convert " + methodType + " argument value of type [" + ObjectUtils.nullSafeClassName(argValue) + "] to required type [" + paramType.getName() + "]: " + ex.getMessage()); } } //返回解析好的参数 return resolvedArgs; } DefaultListableBeanFactory.resolveDependency public Object resolveDependency(DependencyDescriptor descriptor, String beanName, Set<String> autowiredBeanNames, TypeConverter typeConverter) throws BeansException { //获取参数名 descriptor.initParameterNameDiscovery(getParameterNameDiscoverer()); //如果对应的字段或参数类型是Option类型的,那么创建Option,对应的值用get获取,其实内部的值依然是调用 doResolveDependency获取的 if (descriptor.getDependencyType().equals(javaUtilOptionalClass)) { return new OptionalDependencyFactory().createOptionalDependency(descriptor, beanName); } //如果这个字段或参数是对象工厂,那么返回依赖工厂,对应的值用个getObject获取 else if (ObjectFactory.class == descriptor.getDependencyType()) { return new DependencyObjectFactory(descriptor, beanName); } //如果这个字段或参数类型为javax.inject.Provider,那么返回DependencyProvider,通过get获取值 else if (javaxInjectProviderClass == descriptor.getDependencyType()) { return new DependencyProviderFactory().createDependencyProvider(descriptor, beanName); } else { Object result = getAutowireCandidateResolver().getLazyResolutionProxyIfNecessary(descriptor, beanName); if (result == null) { //解析依赖 result = doResolveDependency(descriptor, beanName, autowiredBeanNames, typeConverter); } return result; } } DefaultListableBeanFactory.doResolveDependency public Object doResolveDependency(DependencyDescriptor descriptor, String beanName, Set<String> autowiredBeanNames, TypeConverter typeConverter) throws BeansException { //获取字段或方法参数的类型 Class<?> type = descriptor.getDependencyType(); //获取@Value注解的值 Object value = getAutowireCandidateResolver().getSuggestedValue(descriptor); if (value != null) { if (value instanceof String) { //如果从@Value中获取到了数据,那么就解析${}占位符。 String strVal = resolveEmbeddedValue((String) value); BeanDefinition bd = (beanName != null && containsBean(beanName) ? getMergedBeanDefinition(beanName) : null); //动态语言解析 value = evaluateBeanDefinitionString(strVal, bd); } TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter()); //转换类型后返回 return (descriptor.getField() != null ? converter.convertIfNecessary(value, type, descriptor.getField()) : converter.convertIfNecessary(value, type, descriptor.getMethodParameter())); } //如果是数组,那么获取到对应数组类型,然后到BeanFactory中获取到对应的类型 if (type.isArray()) { Class<?> componentType = type.getComponentType(); DependencyDescriptor targetDesc = new DependencyDescriptor(descriptor); targetDesc.increaseNestingLevel(); //获取符合类型的候选的对象 Map<String, Object> matchingBeans = findAutowireCandidates(beanName, componentType, targetDesc); if (matchingBeans.isEmpty()) { //如果这个字段或参数是必须的,又没有值,那么只好报错了 if (descriptor.isRequired()) { raiseNoSuchBeanDefinitionException(componentType, "array of " + componentType.getName(), descriptor); } return null; } if (autowiredBeanNames != null) { autowiredBeanNames.addAll(matchingBeans.keySet()); } TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter()); //转换类型 Object result = converter.convertIfNecessary(matchingBeans.values(), type); if (getDependencyComparator() != null && result instanceof Object[]) { Arrays.sort((Object[]) result, adaptDependencyComparator(matchingBeans)); } return result; } //处理集合类型 else if (Collection.class.isAssignableFrom(type) && type.isInterface()) { Class<?> elementType = descriptor.getCollectionType(); if (elementType == null) { if (descriptor.isRequired()) { throw new FatalBeanException("No element type declared for collection [" + type.getName() + "]"); } return null; } DependencyDescriptor targetDesc = new DependencyDescriptor(descriptor); targetDesc.increaseNestingLevel(); Map<String, Object> matchingBeans = findAutowireCandidates(beanName, elementType, targetDesc); if (matchingBeans.isEmpty()) { if (descriptor.isRequired()) { raiseNoSuchBeanDefinitionException(elementType, "collection of " + elementType.getName(), descriptor); } return null; } if (autowiredBeanNames != null) { autowiredBeanNames.addAll(matchingBeans.keySet()); } TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter()); Object result = converter.convertIfNecessary(matchingBeans.values(), type); if (getDependencyComparator() != null && result instanceof List) { Collections.sort((List<?>) result, adaptDependencyComparator(matchingBeans)); } return result; } 、 //处理Map类型 else if (Map.class.isAssignableFrom(type) && type.isInterface()) { Class<?> keyType = descriptor.getMapKeyType(); if (String.class != keyType) { if (descriptor.isRequired()) { throw new FatalBeanException("Key type [" + keyType + "] of map [" + type.getName() + "] must be [java.lang.String]"); } return null; } Class<?> valueType = descriptor.getMapValueType(); if (valueType == null) { if (descriptor.isRequired()) { throw new FatalBeanException("No value type declared for map [" + type.getName() + "]"); } return null; } DependencyDescriptor targetDesc = new DependencyDescriptor(descriptor); targetDesc.increaseNestingLevel(); Map<String, Object> matchingBeans = findAutowireCandidates(beanName, valueType, targetDesc); if (matchingBeans.isEmpty()) { if (descriptor.isRequired()) { raiseNoSuchBeanDefinitionException(valueType, "map with value type " + valueType.getName(), descriptor); } return null; } if (autowiredBeanNames != null) { autowiredBeanNames.addAll(matchingBeans.keySet()); } return matchingBeans; } else { Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor); if (matchingBeans.isEmpty()) { if (descriptor.isRequired()) { raiseNoSuchBeanDefinitionException(type, "", descriptor); } return null; } //如果匹配的bean大于一个,那么就查看是否配置了primary属性,如果有就使用primary的那个,没有就报错。 if (matchingBeans.size() > 1) { String primaryBeanName = determineAutowireCandidate(matchingBeans, descriptor); if (primaryBeanName == null) { throw new NoUniqueBeanDefinitionException(type, matchingBeans.keySet()); } if (autowiredBeanNames != null) { autowiredBeanNames.add(primaryBeanName); } return matchingBeans.get(primaryBeanName); } // We have exactly one match. Map.Entry<String, Object> entry = matchingBeans.entrySet().iterator().next(); if (autowiredBeanNames != null) { autowiredBeanNames.add(entry.getKey()); } return entry.getValue(); } }
以上是关于bean的创建第二部分 寻找bean的工厂方法实例化的主要内容,如果未能解决你的问题,请参考以下文章