Spring5 source parsing (bean instantiation)

It has been introduced in the previous blog: For example, if you need another definitionMap for beans, do not specify another definition for beans. If you need another definition for beans, do not specify another definition for beans. If you need another definition for beans, do not specify another definition for beans. Source code analysis of bean scanning process: blog.csdn.net/qq_24101357…

  • finishBeanFactoryInitialization(beanFactory);
  • Merge the parent class, RootBeanDefinition bd = getMergedLocalBeanDefinition (beanName); Here’s an example, not so important:
<bean id="parentBd" class="com.llsydn.merge.PcBd">
	<property name="name" value="parent"></property>
</bean>

<bean id="childBd" parent="parentBd">
	<property name="name" value="children"></property>
</bean>

public class PcBd {
	private String name;
	public void setName(String name) {
		this.name = name;
	}
	public void test(a) {
		System.out.println(this.name); }}public class test{
	public static void main(String[] args) {
		AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext();
		ac.register(Appconfig.class);
		ac.refresh();

		PcBd parentBd = (PcBd) ac.getBean("parentBd");
		parentBd.test();

		PcBd childBd = (PcBd) ac.getBean("childBd"); childBd.test(); }}/ / output:
parent
children
Copy the code

The above code, the main implementation bean is instantiated preparation process, all to be scanned from the beanDefinitionNames beanName. Optionally, call getBean() one by one while iterating over beanDefinitionNames, instantiating the bean objects.

  • getBean(beanName)
  • IsSingletonCurrentlyInCreation thought also no need to create the object.

The model of Spring autowiring is not equal to the technology of autowiring.

  1. No will use the ByType technology
  2. The default auassemble model for beans == no
public class OrderService{ IndexService indexService; } public class OrderService{@autowired indexService indexService; } The indexService will be autoassembled using the ByType technology first, and then using the ByName auto-assembly if it is not foundCopy the code
  • Next, go to doGetBean() for analysis
protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
			@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
	/** * obtain beanName by name. There are two reasons not to use name directly as beanName here * 1. The name might start with the &character, indicating that the caller wants to get The FactoryBean itself, not the bean created by the FactoryBean * implementation class. In BeanFactory, FactoryBean's implementation class stores * in the same way as other beans, that is, 
      
       . There is no & in beanName. So we need * to remove the first character & from the name in order to get the FactoryBean instance from the cache. * * * * * * * * * * * * * * * * * *
      ,>
	final String beanName = transformedBeanName(name);
	Object bean;

	/** * This method is called during initialization, and is also called when getBean is initialized. If spring initializes a bean, it will be instantiated. If spring initializes a bean, it will be instantiated. If spring initializes a bean, it will be instantiated. Since spring's bean container is a map (singletonObjects) *, you can understand that getSingleton(beanName) equals beanmap.get (beanName) * Since the method is called once when the spring environment is initialized (that is, when the object is created) * and once when the getBean is created *, you need to be careful when debugging. * need to enter the annotationConfigApplicationContext. GetBean (IndexDao. Class) * after the breakpoint, Thus ensure that the us is in acquiring the bean called when the * * to be sure of is called when the initialization is usually returns null * * the first call: isSingletonCurrentlyInCreation thought not to start to create the object * /
	Object sharedInstance = getSingleton(beanName);
	if(sharedInstance ! =null && args == null) {
		// This code is for logging, so it should be commented for future reading, and does not affect spring functionality
		 if (logger.isDebugEnabled()) {
		 	if (isSingletonCurrentlyInCreation(beanName)) {
		 		logger.debug("Returning eagerly cached instance of singleton bean '" + beanName +
		 				"' that is not fully initialized yet - a consequence of a circular reference");
		 	}
		 	else {
		 		logger.debug("Returning cached instance of singleton bean '" + beanName + "'"); }}/** * If sharedInstance is an ordinary singleton bean, the following method will return directly. But if * sharedInstance is of type FactoryBean, then you need to call the getObject factory method to get the real * Bean instance. If the user wants to get FactoryBean itself, there's nothing special to do here, just return *. After all, the FactoryBean implementation class is itself a bean, just with a little special functionality. * /
		bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
	}

	else {
		// Fail if we're already creating this bean instance:
		// We're assumably within a circular reference.
		/** * prototype to determine whether the bean being created is a prototype. If it is a prototype, it should not be created during initialization
		if (isPrototypeCurrentlyInCreation(beanName)) {
			throw new BeanCurrentlyInCreationException(beanName);
		}

		// Check if bean definition exists in this factory. The parent plant
		BeanFactory parentBeanFactory = getParentBeanFactory();
		if(parentBeanFactory ! =null && !containsBeanDefinition(beanName)) {
			// Not found -> check parent.
			String nameToLookup = originalBeanName(name);
			if (parentBeanFactory instanceof AbstractBeanFactory) {
				return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
						nameToLookup, requiredType, args, typeCheckOnly);
			}
			else if(args ! =null) {
				// Delegation to parent with explicit args.
				return (T) parentBeanFactory.getBean(nameToLookup, args);
			}
			else {
				// No args -> delegate to standard getBean method.
				returnparentBeanFactory.getBean(nameToLookup, requiredType); }}if(! typeCheckOnly) {// add it to the alreadyCreated set to indicate that it has alreadyCreated one
			markBeanAsCreated(beanName);
		}

		try {
			final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
			checkMergedBeanDefinition(mbd, beanName, args);

			// Guarantee initialization of beans that the current bean depends on.
			String[] dependsOn = mbd.getDependsOn();
			if(dependsOn ! =null) {
				for (String dep : dependsOn) {
					if (isDependent(beanName, dep)) {
						throw new BeanCreationException(mbd.getResourceDescription(), beanName,
								"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
					}
					registerDependentBean(dep, beanName);
					try {
						getBean(dep);
					}
					catch (NoSuchBeanDefinitionException ex) {
						throw new BeanCreationException(mbd.getResourceDescription(), beanName,
								"'" + beanName + "' depends on missing bean '" + dep + "'", ex); }}}// Create a singleton bean
			if (mbd.isSingleton()) {
				sharedInstance = getSingleton(beanName, () -> {
					try {
						return createBean(beanName, mbd, args);
					}
					catch (BeansException ex) {
						// Explicitly remove instance from singleton cache: It might have been put there
						// eagerly by the creation process, to allow for circular reference resolution.
						// Also remove any beans that received a temporary reference to the bean.
						destroySingleton(beanName);
						throwex; }}); bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd); }else if (mbd.isPrototype()) {
				// It's a prototype -> create a new instance.
				Object prototypeInstance = null;
				try {
					beforePrototypeCreation(beanName);
					prototypeInstance = createBean(beanName, mbd, args);
				}
				finally {
					afterPrototypeCreation(beanName);
				}
				bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
			}

			else {
				String scopeName = mbd.getScope();
				final Scope scope = this.scopes.get(scopeName);
				if (scope == null) {
					throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
				}
				try {
					Object scopedInstance = scope.get(beanName, () -> {
						beforePrototypeCreation(beanName);
						try {
							return createBean(beanName, mbd, args);
						}
						finally{ afterPrototypeCreation(beanName); }}); bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd); }catch (IllegalStateException ex) {
					throw new BeanCreationException(beanName,
							"Scope '" + scopeName + "' is not active for the current thread; consider " +
							"defining a scoped proxy for this bean if you intend to refer to it from a singleton", ex); }}}catch (BeansException ex) {
			cleanupAfterBeanCreationFailure(beanName);
			throwex; }}// Check if required type matches the type of the actual bean instance.
	if(requiredType ! =null && !requiredType.isInstance(bean)) {
		try {
			T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);
			if (convertedBean == null) {
				throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
			}
			return convertedBean;
		}
		catch (TypeMismatchException ex) {
			if (logger.isDebugEnabled()) {
				logger.debug("Failed to convert bean '" + name + "' to required type '" +
						ClassUtils.getQualifiedName(requiredType) + "'", ex);
			}
			throw newBeanNotOfRequiredTypeException(name, requiredType, bean.getClass()); }}return (T) bean;
}
Copy the code
  • createBean(beanName, mbd, args); Analysis of the
@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
		throws BeanCreationException {

	if (logger.isDebugEnabled()) {
		logger.debug("Creating instance of bean '" + beanName + "'");
	}
	RootBeanDefinition mbdToUse = mbd;

	// Make sure bean class is actually resolved at this point, and
	// clone the bean definition in case of a dynamically resolved Class
	// which cannot be stored in the shared merged bean definition.Class<? > resolvedClass = resolveBeanClass(mbd, beanName);if(resolvedClass ! =null&&! mbd.hasBeanClass() && mbd.getBeanClassName() ! =null) {
		mbdToUse = new RootBeanDefinition(mbd);
		mbdToUse.setBeanClass(resolvedClass);
	}

	// Prepare method overrides.
	// Handles the lookup-method and replace-method configurations, which Spring calls the Override method
	try {
		mbdToUse.prepareMethodOverrides();
	}
	catch (BeanDefinitionValidationException ex) {
		throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
				beanName, "Validation of method overrides failed", ex);
	}

	try {
		// Apply postprocessing before the bean is initialized. If the returned bean is not empty, return it directly
		// This class needs to be demonstrated in code
		// The main function of this function is to return all of the bean's dependencies to a single object. Implement InstantiationAwareBeanPostProcessor interface.
		// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
		Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
		if(bean ! =null) {
			returnbean; }}catch (Throwable ex) {
		throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
				"BeanPostProcessor before instantiation of bean failed", ex);
	}
	try {
		// Call doCreateBean to create the bean
		Object beanInstance = doCreateBean(beanName, mbdToUse, args);
		if (logger.isDebugEnabled()) {
			logger.debug("Finished creating instance of bean '" + beanName + "'");
		}
		return beanInstance;
	}
	catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
		// A previously detected exception with proper bean creation context already,
		// or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry.
		throw ex;
	}
	catch (Throwable ex) {
		throw new BeanCreationException(
				mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex); }}Copy the code
  • Object beanInstance = doCreateBean(beanName, mbdToUse, args); Analysis of the
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
			throws BeanCreationException {
	// Instantiate the bean
	BeanWrapper instanceWrapper = null;
	if (mbd.isSingleton()) {
		instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
	}
	if (instanceWrapper == null) {
		/** * Create a bean instance and return it wrapped in a BeanWrapper implementation object. * createBeanInstance contains three ways to create bean instances: * 1. Create bean instances using factory methods * 2. Create bean instances using autowire by constructor * 3. Create bean instances with no-parameter constructor methods * * CGLIB * is used to enhance bean instances if the bean configuration information contains lookup-method and replace-method. More on lookup-method and replace-method later. * /
		instanceWrapper = createBeanInstance(beanName, mbd, args);
	}
	// Get the native object that wraps the class
	finalObject bean = instanceWrapper.getWrappedInstance(); Class<? > beanType = instanceWrapper.getWrappedClass();if(beanType ! = NullBean.class) { mbd.resolvedTargetType = beanType; }// Allow post-processors to modify the merged bean definition.
	synchronized (mbd.postProcessingLock) {
		if(! mbd.postProcessed) {try {
				// Very important
				applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
			}
			catch (Throwable ex) {
				throw new BeanCreationException(mbd.getResourceDescription(), beanName,
						"Post-processing of merged bean definition failed", ex);
			}
			mbd.postProcessed = true; }}// Eagerly cache singletons to be able to resolve circular references
	// even when triggered by lifecycle interfaces like BeanFactoryAware.
	boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
			isSingletonCurrentlyInCreation(beanName));
	if (earlySingletonExposure) {
		if (logger.isDebugEnabled()) {
			logger.debug("Eagerly caching bean '" + beanName +
					"' to allow for resolving potential circular references");
		}
		addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
	}

	// Initialize the bean instance.
	Object exposedObject = bean;
	try {
		// Setting properties is very important
		populateBean(beanName, mbd, instanceWrapper);
		// The post-execution handler is where AOP does its processing
		exposedObject = initializeBean(beanName, exposedObject, mbd);
	}
	catch (Throwable ex) {
		if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
			throw (BeanCreationException) ex;
		}
		else {
			throw new BeanCreationException(
					mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex); }}if (earlySingletonExposure) {
		Object earlySingletonReference = getSingleton(beanName, false);
		if(earlySingletonReference ! =null) {
			if (exposedObject == bean) {
				exposedObject = earlySingletonReference;
			}
			else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
				String[] dependentBeans = getDependentBeans(beanName);
				Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
				for (String dependentBean : dependentBeans) {
					if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
						actualDependentBeans.add(dependentBean);
					}
				}
				if(! actualDependentBeans.isEmpty()) {throw new BeanCurrentlyInCreationException(beanName,
							"Bean with name '" + beanName + "' has been injected into other beans [" +
							StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
							"] in its raw version as part of a circular reference, but has eventually been " +
							"wrapped. This means that said other beans do not use the final version of the " +
							"bean. This is often the result of over-eager type matching - consider using " +
							"'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example."); }}}}// Register bean as disposable.
	try {
		registerDisposableBeanIfNecessary(beanName, bean, mbd);
	}
	catch (BeanDefinitionValidationException ex) {
		throw new BeanCreationException(
				mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
	}
	return exposedObject;
}
Copy the code

The doCreateBean() method is used to generate an instance of the bean. createBeanInstance(beanName, mbd, args) 2. The properties of the instance object are automatically assembled. populateBean(beanName, mbd, instanceWrapper); 3. Execute the post-processor for bean enhancement. initializeBean(beanName, exposedObject, mbd);

  • CreateBeanInstance (beanName, MBD, args) instantiates the object using reflection technology
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
	// Make sure bean class is actually resolved at this point.Class<? > beanClass = resolveBeanClass(mbd, beanName);Spring allows access to non-public classes by default. * /
	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()); } Supplier<? > instanceSupplier = mbd.getInstanceSupplier();if(instanceSupplier ! =null) {
		return obtainFromSupplier(instanceSupplier, beanName);
	}

	/** ** if the factoryMethod is not empty, you can build the bean object using the factoryMethod. * you can write a demo of how to build the bean. We instantiate the object using the FactoryMethod method. (Example implementation) */
	if(mbd.getFactoryMethodName() ! =null)  {
		return instantiateUsingFactoryMethod(beanName, mbd, args);
	}

	// Shortcut when re-creating the same bean...
	/** * this is my Shortcut. This Shortcut can be used if you want to build the same bean multiple times. * This means you don't need to infer which way to construct the bean * if you want to build the same Prototype bean multiple times. Can go the shortcut here * resolved here and MBD constructorArgumentsResolved will be the first time in the bean instantiation is set in the process of * /
	boolean resolved = false;
	boolean autowireNecessary = false;  // Whether automatic assembly is required
	if (args == null) {
		synchronized (mbd.constructorArgumentLock) {
			if(mbd.resolvedConstructorOrFactoryMethod ! =null) {
				resolved = true;
				// If the constructor parameters have been resolved, the constructor must be instantiated with a parameter constructorautowireNecessary = mbd.constructorArgumentsResolved; }}}if (resolved) {
		if (autowireNecessary) {
			// Construct the bean object using the constructor autowire
			return autowireConstructor(beanName, mbd, null.null);
		}
		else {
			// Through the default no-parameter constructor
			returninstantiateBean(beanName, mbd); }}//1. When there is no constructor, the object is instantiated using the constructor by default.
		// Since Spring doesn't know whether you want to instantiate an object with a parameter constructor or a no-parameter constructor, it's easier to instantiate an object with a no-parameter constructor.
	//2. If and only if there is only one parameter constructor, instantiate the object using that parameter constructor.
		// When you have multiple parameter-based constructors, Spring does not know which constructor to use to instantiate the object, so it is simpler to use the parameterless constructor to instantiate the object.
	// It is up to the postprocessor to decide which constructors to return
	// Get the bean constructor and use that constructor to instantiate the object. (Which constructor to use to instantiate the object is left to BeanPostProcessors.)Constructor<? >[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);if(ctors ! =null|| mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR || mbd.hasConstructorArgumentValues() || ! ObjectUtils.isEmpty(args)) {return autowireConstructor(beanName, mbd, ctors, args);
	}
	// Initialize using the default constructor with no parameters
	return instantiateBean(beanName, mbd);
}
Copy the code

The main steps of createBeanInstance are as follows: 1. Determine whether the bean can be accessed. 2. Determine whether the bean has a factory-method method, and if so, call the factory-method method to instantiate object 3. Determine if the bean is being instantiated for the second time and if there is a shortcut instantiating object. 4. Determine the constructor of the bean:

1. When the bean has no constructor, it defaults to the constructor and instantiates object 2. When the bean has only one parameter constructor, that parameter constructor is used to instantiate object 3. When a bean has multiple parameterized constructors, instantiate the object using the parameterless constructor. (Spring cannot determine which constructor to use)

Note: Spring instantiates objects using constructors

  • DetermineConstructorsFromBeanPostProcessors (), with which constructor instantiation objects to BeanPostProcessors processing
protectedConstructor<? >[] determineConstructorsFromBeanPostProcessors(@NullableClass<? > beanClass, String beanName)throws BeansException {
	if(beanClass ! =null && hasInstantiationAwareBeanPostProcessors()) {
		for (BeanPostProcessor bp : getBeanPostProcessors()) {
			if (bp instanceofSmartInstantiationAwareBeanPostProcessor) { SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp; Constructor<? >[] ctors = ibp.determineCandidateConstructors(beanClass, beanName);if(ctors ! =null) {
					returnctors; }}}}return null;
}

#AutowiredAnnotationBeanPostProcessor
// Decide which candidate constructor to use
@Override
@Nullable
publicConstructor<? >[] determineCandidateConstructors(Class<? > beanClass,final String beanName)
		throws BeanCreationException {

	// Let's check for lookup methods here..
	if (!this.lookupMethodsChecked.contains(beanName)) {
		try {
			ReflectionUtils.doWithMethods(beanClass, method -> {
				Lookup lookup = method.getAnnotation(Lookup.class);
				if(lookup ! =null) {
					Assert.state(this.beanFactory ! =null."No BeanFactory available");
					LookupOverride override = new LookupOverride(method, lookup.value());
					try {
						RootBeanDefinition mbd = (RootBeanDefinition) this.beanFactory.getMergedBeanDefinition(beanName);
						mbd.getMethodOverrides().addOverride(override);
					}
					catch (NoSuchBeanDefinitionException ex) {
						throw new BeanCreationException(beanName,
								"Cannot apply @Lookup to beans without corresponding bean definition"); }}}); }catch (IllegalStateException ex) {
			throw new BeanCreationException(beanName, "Lookup method resolution failed", ex);
		}
		this.lookupMethodsChecked.add(beanName);
	}

	// Candidate constructor
	// Quick check on the concurrent map first, with minimal locking.Constructor<? >[] candidateConstructors =this.candidateConstructorsCache.get(beanClass);
	if (candidateConstructors == null) {
		// Fully synchronized resolution now...
		synchronized (this.candidateConstructorsCache) {
			candidateConstructors = this.candidateConstructorsCache.get(beanClass);
			if (candidateConstructors == null) {
				// Get all the constructors of the beanConstructor<? >[] rawCandidates;try {
					rawCandidates = beanClass.getDeclaredConstructors();
				}
				catch (Throwable ex) {
					throw new BeanCreationException(beanName,
							"Resolution of declared constructors on bean Class [" + beanClass.getName() +
							"] from ClassLoader [" + beanClass.getClassLoader() + "] failed", ex); } List<Constructor<? >> candidates =newArrayList<>(rawCandidates.length); Constructor<? > requiredConstructor =null; Constructor<? > defaultConstructor =null; Constructor<? > primaryConstructor = BeanUtils.findPrimaryConstructor(beanClass);int nonSyntheticConstructors = 0;
				for(Constructor<? > candidate : rawCandidates) {if(! candidate.isSynthetic()) {// Record how many constructors the bean has
						nonSyntheticConstructors++;
					}
					else if(primaryConstructor ! =null) {
						continue;
					}
					AnnotationAttributes ann = findAutowiredAnnotation(candidate);
					if (ann == null) { Class<? > userClass = ClassUtils.getUserClass(beanClass);if(userClass ! = beanClass) {try{ Constructor<? > superCtor = userClass.getDeclaredConstructor(candidate.getParameterTypes()); ann = findAutowiredAnnotation(superCtor); }catch (NoSuchMethodException ex) {
								// Simply proceed, no equivalent superclass constructor found...}}}if(ann ! =null) {
						if(requiredConstructor ! =null) {
							throw new BeanCreationException(beanName,
									"Invalid autowire-marked constructor: " + candidate +
									". Found constructor with 'required' Autowired annotation already: " +
									requiredConstructor);
						}
						boolean required = determineRequiredStatus(ann);
						if (required) {
							if(! candidates.isEmpty()) {throw new BeanCreationException(beanName,
										"Invalid autowire-marked constructors: " + candidates +
										". Found constructor with 'required' Autowired annotation: " +
										candidate);
							}
							requiredConstructor = candidate;
						}
						candidates.add(candidate);
					}
					// If the constructor has no arguments, it is the default constructor. Instantiate the object using the default constructor.
					else if (candidate.getParameterCount() == 0) { defaultConstructor = candidate; }}if(! candidates.isEmpty()) {// Add default constructor to list of optional constructors, as fallback.
					if (requiredConstructor == null) {
						if(defaultConstructor ! =null) {
							candidates.add(defaultConstructor);
						}
						else if (candidates.size() == 1 && logger.isWarnEnabled()) {
							logger.warn("Inconsistent constructor declaration on bean with name '" + beanName +
									"': single autowire-marked constructor flagged as optional - " +
									"this constructor is effectively required since there is no " +
									"default constructor to fall back to: " + candidates.get(0));
						}
					}
					candidateConstructors = candidates.toArray(newConstructor<? > [0]);
				}
				else if (rawCandidates.length == 1 && rawCandidates[0].getParameterCount() > 0) {
					// There is only one constructor with a parameter. Return that constructor
					candidateConstructors = newConstructor<? >[] {rawCandidates[0]};
				}
				else if (nonSyntheticConstructors == 2&& primaryConstructor ! =null&& defaultConstructor ! =null && !primaryConstructor.equals(defaultConstructor)) {

					candidateConstructors = newConstructor<? >[] {primaryConstructor, defaultConstructor}; }else if (nonSyntheticConstructors == 1&& primaryConstructor ! =null) {
					candidateConstructors = newConstructor<? >[] {primaryConstructor}; }else {
					// Return null, that is, instantiate the object using the default no-parameter constructor.
					candidateConstructors = newConstructor<? > [0];
				}
				this.candidateConstructorsCache.put(beanClass, candidateConstructors); }}}return (candidateConstructors.length > 0 ? candidateConstructors : null);
}
Copy the code