The processing are in front of the preparation, the following finishBeanFactoryInitialization method into official bean creation process.

protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) { // Initialize conversion Service for this context. // Initializes the type converter if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) && beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) { beanFactory.setConversionService( beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)); } // Register a default embedded value resolver if no bean post-processor // (such as a PropertyPlaceholderConfigurer bean) registered any before: // At this point, primarily for resolution in annotation attribute values. // If beanFactory has not previously registered an embed value parser, register the default embed value parser, If (! beanFactory.hasEmbeddedValueResolver()) { beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal)); } // Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early. // Initialize loadTimeWeaverAware beans as early as possible to register their converters String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false); for (String weaverAwareName : weaverAwareNames) { getBean(weaverAwareName); } / / Stop using the temporary this for type matching. / / it is prohibited to use temporary class loader type matching the beanFactory. SetTempClassLoader (null); // Allow for caching all bean definition metadata, not expecting further changes. Registered bean definition will not be modified or any further processing. The beanFactory freezeConfiguration (); / / Instantiate all remaining (non - lazy - init) singletons. / / Instantiate the rest of the singleton object. The beanFactory preInstantiateSingletons (); }Copy the code
  • Set converterConversionService

Converters of various types are set in ConversionService

public static void addDefaultConverters(ConverterRegistry converterRegistry) {
   addScalarConverters(converterRegistry);
   addCollectionConverters(converterRegistry);

   converterRegistry.addConverter(new ByteBufferConverter((ConversionService) converterRegistry));
   converterRegistry.addConverter(new StringToTimeZoneConverter());
   converterRegistry.addConverter(new ZoneIdToTimeZoneConverter());
   converterRegistry.addConverter(new ZonedDateTimeToCalendarConverter());

   converterRegistry.addConverter(new ObjectToObjectConverter());
   converterRegistry.addConverter(new IdToEntityConverter((ConversionService) converterRegistry));
   converterRegistry.addConverter(new FallbackObjectToStringConverter());
   converterRegistry.addConverter(new ObjectToOptionalConverter((ConversionService) converterRegistry));
}
Copy the code
  • Converter type
  1. ConverterConvert type S to type T
@FunctionalInterface public interface Converter<S, T> {/** * Convert the source object of type {@code S} to target type {@code T}. * @param source the source object to convert, which must be an instance of {@code S} (never {@code null}) * @return the converted object, which must be an instance of {@code T} (potentially {@code null}) * @throws IllegalArgumentException if the source cannot be converted to the desired target type */ @Nullable T convert(S source); }Copy the code
  1. GenericConverterA generic converter interface for converting between two or more types
** Convert the source object to the targetType described by the {@code TypeDescriptor}. * @param source the source object to convert (may be {@code null}) * @param sourceType the type descriptor of the field we are converting from * @param targetType the type descriptor of the field we are converting to * @return the converted object  */ @Nullable Object convert(@Nullable Object source, TypeDescriptor sourceType, TypeDescriptor targetType);Copy the code
  1. ConverterFactoryFactory class for Converter to get the corresponding converter
Public interface ConverterFactory<S, R> {/** * Get the converter to convert from S to target type T, where T is also an instance of R. * @param <T> the target type * @param targetType the target type to convert to * @return a converter from S to T */ <T extends R> Converter<S, T> getConverter(Class<T> targetType); }Copy the code

To add your own converter, refer to the official documentation:

  • Merge the parent BeanDefinition operation

GetMergedBeanDefinition role: Before instantiation, all the basic beanDefinition objects should be converted into RootBeanDefinition objects for caching. Later, when it needs to be instantiated immediately, the definition information should be directly obtained. If the definition information contains the parent class, the parent class must be created before subclasses can be created.

/ / merge the superclass BeanDefinition RootBeanDefinition bd = getMergedLocalBeanDefinition (beanName);Copy the code
protected RootBeanDefinition getMergedBeanDefinition( String beanName, BeanDefinition bd, @ Nullable BeanDefinition containingBd) throws BeanDefinitionStoreException {/ / synchronization: Use from the bean name mapping to merge RootBeanDefinition collection lock synchronized (enclosing mergedBeanDefinitions) {/ / used to store the bd MergedBeanDefinition RootBeanDefinition mbd = null; // This variable represents the MBD from the bean name mapped to the merged RootBeanDefinition set and the MBD needs to be remerged RootBeanDefinition Previous = null; // Check with full lock now in order to enforce the same merged instance. If (containingBd == null) {// From bean name mapping to merge RootBeanDefinition collection to obtain corresponding BeanDefinition as MBD beanName MBD = this. MergedBeanDefinitions. Get (beanName); } / / if MBD is null or MDB definition need to merge the if (MBD = = null | | MBD. Stale) {/ / the MDN as previous previous = MBD; If (bd.getparentName () == null) {// Use copy of given root Bean definition Use a copy of the given RootBeanDefinition if the original BeanDefinition is the RootBeanDefinition object if (bd instanceof RootBeanDefinition) {// Clone the Bean definition of bd and assign it to MDB MBD = ((RootBeanDefinition) bd).cloneBeanDefinition(); } else {// Create a new RootBeanDefinition as a deep copy of bd and assign MBD MBD = new RootBeanDefinition(bd); } } else { // Child bean definition: Merged with parent BeanDefinition BeanDefinition PBD; merged with parent BeanDefinition PBD; merged with parent BeanDefinition PBD; merged with parent BeanDefinition PBD; merged with parent BeanDefinition PBD; ParentBeanName = transformedBeanName(bd.getParentName()); // If the current bean name is not equal to the parent bean name Beanname.equals (parentBeanName)) {// Get the "merged "BeanDefinition of parentBeanName assigned to PDB PBD = getMergedBeanDefinition(parentBeanName); } // If the parent beanName is the same as the bd beanName, then the parent BeanFactory is allowed to define beanName as the parent BeanFactory. Else {BeanFactory parent = getParentBeanFactory(); // If the parent BeanFactory is ConfigurableBeanFactory, ConfigurableBeanFactory: ConfigurableBeanFactory: ConfigurableBeanFactory: ConfigurableBeanFactory: ConfigurableBeanFactory: ConfigurableBeanFactory: ConfigurableBeanFactory: ConfigurableBeanFactory: ConfigurableBeanFactory: ConfigurableBeanFactory: ConfigurableBeanFactory: ConfigurableBeanFactory ConfigurableBeanFactory: PDB: PDB: PDB: PDB: PDB: PDB: PDB: PDB: PDB: PDB: PDB: PDB parent).getMergedBeanDefinition(parentBeanName); } else {// If the parent factory is not ConfigurableBeanFactory, the parent bean named parentBeanName equals the bean name named beanName; / / not AbstractBeanFactory parent cannot solve throw new NoSuchBeanDefinitionException (parentBeanName, "Parent name '" + parentBeanName + "' is equal to bean name '" + beanName + "': cannot be resolved without a ConfigurableBeanFactory parent"); } } } catch (NoSuchBeanDefinitionException ex) { throw new BeanDefinitionStoreException(bd.getResourceDescription(), beanName, "Could not resolve parent bean definition '" + bd.getParentName() + "'", ex); MBD = new RootBeanDefinition(PBD); // Override the parent definition information with the original BD definition information: // 1. If specified in the given bean definition, beanClass // 2 will be overridden. Will always from the given bean definition for the abstract, the scope, lazyInit, autowireMode, / / dependencyCheck and dependsOn / / 3. A given bean definition ConstructorArgumentValues propertyValues, / / methodOverrides added to an existing bean definition / / 4. If specified in the given bean definitions, will cover factoryBeanName, factoryMethodName, / / initMethodName, and destroyMethodName MBD. OverrideFrom (bd); } // Set the default singleton scope, if not configured before. Stringutils.haslength (mbd.getScope())) {// Set the scope of MBD to singleton mbd.setScope(SCOPE_SINGLETON); } // A bean contained in a non-singleton bean cannot be a singleton itself. // Let's correct this on the fly here, since this might be the result of // parent-child merging for the outer bean, in which case the original inner bean // definition will not have inherited the merged outer bean's singleton status. // A bean contained in a non-singleton bean cannot itself bea singleton. // Let's make a quick correction here, because this could be the result of a parent-child merge of the external bean, in which case the original inner bean definition will not inherit the singleton state of the merged external bean. // MBD is a singleton if (containingBd! = null && ! IsSingleton () &&mbd.issingleton ()) {// Make the scope of MBD the same as that of containingBd mbd.setScope(containingBd.getScope()); } // Cache the merged bean definition for the time being // (it might still get re-merged later on in order to pick up Metadata changes) // Temporarily cache the merged bean definition (it may still be remerged later for metadata corrections), if no containing bean definition is passed in and the current factory agrees to cache the bean metadata if (containingBd == null &&) IsCacheBeanMetadata ()) {// Add the relationship between beanName and MBD to the set of rootBeanDefinitions mapped from the bean name to the merged RootBeanDefinition this.mergedBeanDefinitions.put(beanName, mbd); }} // If there is a previous MBD from the bean name mapped to the merged RootBeanDefinition collection // and the MBD needs to be remerged if (previous! = null) {// use previous to remerge MDB: // 1. Set MBD target type to previous target type // 2. Set MBD's factory bean flag to previous's factory bean flag // 3. Set MBD's defined Class for caching a given bean definition to previous's defined Class for caching a given bean definition // 4. Set MBD factory method return type to previous factory method return type // 5. Set the MBD used to cache the only factory method used for introspection candidate for previous used to cache the only factory method used for introspection candidate copyRelevantMergedBeanDefinitionCaches (previous, MBD); } // MergedBeanDefinition return MBD; }}Copy the code
  • The BeanFactory and FactoryBean

When an object is created, there is an isFactoryBean judgment that determines whether the FactoryBean interface is implemented. BeanFactory and FactoryBean are both object factories used to create object differences: BeanFactory interface must strictly follow the lifecycle interface of SpringBean, from instantiation to initialization, to invokeAwareMethod, invokeInitMethodr, beforef, after 2. FactoryBean: You do not need to follow this creation order and return the object directly through the getObject method. When we use the FactoryBean interface to create objects, we create two objects, a subclass object that implements the FactoryBean interface and an object returned by the getObject method. Both objects are managed by Spring, but note that the objects that implement the FactoryBean interface are cached at level 1, but the objects returned by calling getObject are cached at factoryBeanObjectCache.