Instance and initialization of Spring source code parsing

Keywords: Java source code

pojo

package com.kuang.pojo;

public class Hello {
    private String str;

    public String getStr() {
        return str;
    }

    public void setStr(String str) {
        this.str = str;
    }

    @Override
    public String toString() {
        return "Hello{" +
                "str='" + str + '\'' +
                '}';
    }
}

xml file

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd   ">

    <!--use spring To create an object, in spring These have become Bean-->
    <bean id="hello" class="com.kuang.pojo.Hello">
        <property name="str" value="Spring"/>
    </bean>
</beans>

 

Interface BeanDefinitionReader

Description information

Simple interface for bean definition readers.
* Specifies load methods with Resource and String location parameters.
bean Define a simple interface for the reader. use Resource and String The location parameter specifies the loading method

Interface BeanDefinition

A BeanDefinition describes a bean instance, which has property values, constructor argument values, and further information supplied by concrete implementations.
This is just a minimal interface: The main intention is to allow a BeanFactoryPostProcessor such as PropertyPlaceholderConfigurer to introspect and modify property values and other bean metadata.

 BeanDefinition Describes a bean Instance, which has attribute values, constructor parameter values, and more information provided by the concrete implementation.
This is just a minimal interface: the main purpose is to allow BeanFactoryPostProcessor for example PropertyPlaceholderConfigurer Introspection and modification of attribute values and others bean metadata

In short: BeanDefinition is used to obtain the information of bean objects in xml

Interface BeanFactory

Description information:

The root interface for accessing a Spring bean container 

BeanFactory instantiates bean s with reflection  

 

  Interface PostProcessor

  PostProcessor is also called intensifier or PostProcessor. Its purpose is to expand. Because spring has good scalability, it has good ecology and extends springboot and springcloud

 

How to parse the $character and let it pass the corresponding value to BeanFactory?

It is implemented through this beanfactoryprocessor,

  The interface implementation class is PlaceholderConfigurerSupport. Of course, there are many implementation classes with different functions

public abstract class PlaceholderConfigurerSupport extends PropertyResourceConfigurer
      implements BeanNameAware, BeanFactoryAware {

  This implementation class is used to parse the following format

It can be seen from his functional description

 Abstract base class for property resource configurers that resolve placeholders
* in bean definition property values. Implementations <em>pull</em> values from a
* properties file or other {@linkplain org.springframework.core.env.PropertySource
* property source} into bean definitions.
*

Interface BeanPostProcessor

  There are two methods;

@Nullable
default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
   return bean;
}
@Nullable
default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
   return bean;

The function is to operate the bean information before and after initializing the bean

  Then enter the source code link to see what happened when initializing the configuration file?

debug it

  Configuration file information;

Some of the less important ones are ignored

1. Set the location of the configuration file to facilitate subsequent reading

  2 then enter the refresh method

@Override
public void refresh() throws BeansException, IllegalStateException {
   synchronized (this.startupShutdownMonitor) {
      // Prepare this context for refreshing.
      prepareRefresh();

      // Tell the subclass to refresh the internal bean factory.
      ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

      // Prepare the bean factory for use in this context.
      prepareBeanFactory(beanFactory);

      try {
         // Allows post-processing of the bean factory in context subclasses.
         postProcessBeanFactory(beanFactory);

         // Invoke factory processors registered as beans in the context.
         invokeBeanFactoryPostProcessors(beanFactory);

         // Register bean processors that intercept bean creation.
         registerBeanPostProcessors(beanFactory);

         // Initialize message source for this context.
         initMessageSource();

         // Initialize event multicaster for this context.
         initApplicationEventMulticaster();

         // Initialize other special beans in specific context subclasses.
         onRefresh();

         // Check for listener beans and register them.
         registerListeners();

         // Instantiate all remaining (non-lazy-init) singletons.
         finishBeanFactoryInitialization(beanFactory);

         // Last step: publish corresponding event.
         finishRefresh();
      }

      catch (BeansException ex) {
         if (logger.isWarnEnabled()) {
            logger.warn("Exception encountered during context initialization - " +
                  "cancelling refresh attempt: " + ex);
         }

         // Destroy already created singletons to avoid dangling resources.
         destroyBeans();

         // Reset 'active' flag.
         cancelRefresh(ex);

         // Propagate exception to caller.
         throw ex;
      }

      finally {
         // Reset common introspection caches in Spring's core, since we
         // might not ever need metadata for singleton beans anymore...
         resetCommonCaches();
      }
   }
}

Enter prepareRefresh() at 3:00;

protected void prepareRefresh() {
   // Switch to active.
   this.startupDate = System.currentTimeMillis();
   this.closed.set(false);
   this.active.set(true);

   if (logger.isDebugEnabled()) {
      if (logger.isTraceEnabled()) {
         logger.trace("Refreshing " + this);
      }
      else {
         logger.debug("Refreshing " + getDisplayName());
      }
   }

   // Initialize any placeholder property sources in the context environment.
   initPropertySources();

   // Validate that all properties marked as required are resolvable:
   // see ConfigurablePropertyResolver#setRequiredProperties
   getEnvironment().validateRequiredProperties();

   // Store pre-refresh ApplicationListeners...
   if (this.earlyApplicationListeners == null) {
      this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);
   }
   else {
      // Reset local application listeners to pre-refresh state.
      this.applicationListeners.clear();
      this.applicationListeners.addAll(this.earlyApplicationListeners);
   }

   // Allow for the collection of early ApplicationEvents,
   // to be published once the multicaster is available...
   this.earlyApplicationEvents = new LinkedHashSet<>();
}

/**
 * <p>Replace any stub property sources with actual instances.
 * @see org.springframework.core.env.PropertySource.StubPropertySource
 * @see org.springframework.web.context.support.WebApplicationContextUtils#initServletPropertySources
 */
protected void initPropertySources() {
   // For subclasses: do nothing by default.
}

To sum up, this method is to set some environments, initialize attribute resources, obtain environment objects, and create a series of collections

4. After the refresh method is completed, the factory will be created

 ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
   refreshBeanFactory();
   return getBeanFactory();
}
A new factory must be created
@Override
protected final void refreshBeanFactory() throws BeansException {
   if (hasBeanFactory()) {
      destroyBeans();
      closeBeanFactory();
   }
   try {
      DefaultListableBeanFactory beanFactory = createBeanFactory();
      beanFactory.setSerializationId(getId());
      customizeBeanFactory(beanFactory);
      loadBeanDefinitions(beanFactory);
      this.beanFactory = beanFactory;
   }
   catch (IOException ex) {
      throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
   }
}

loadBeanDefinitions(beanFactory); Load profile

Before loading

  After loading

So I got the name of Bean

5. Then execute prepareBeanFactory(beanFactory);

Why do you want to perform this step? Because many values are not initialized after the factory is created. You can see a pile of 0 and true of the following attributes. This method is used to assign values to these attributes

protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
   // Tell the internal bean factory to use the context's class loader etc.
   beanFactory.setBeanClassLoader(getClassLoader());
   beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
   beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));

   // Configure the bean factory with context callbacks.
   beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
   beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
   beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
   beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
   beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
   beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
   beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);

   // BeanFactory interface not registered as resolvable type in a plain factory.
   // MessageSource registered (and found for autowiring) as a bean.
   beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
   beanFactory.registerResolvableDependency(ResourceLoader.class, this);
   beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
   beanFactory.registerResolvableDependency(ApplicationContext.class, this);

   // Register early post-processor for detecting inner beans as ApplicationListeners.
   beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));

   // Detect a LoadTimeWeaver and prepare for weaving, if found.
   if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
      beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
      // Set a temporary ClassLoader for type matching.
      beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
   }

   // Register default environment beans.
   if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
      beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
   }
   if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
      beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
   }
   if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
      beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
   }
}

  After reading the notes below, we can briefly summarize the standard context characteristics of the configuration factory;

6. Execute postProcessBeanFactory(beanFactory);

// Allows post-processing of the bean factory in context subclasses.
postProcessBeanFactory(beanFactory);

Click in to find that the method is empty. It is a method written to facilitate expansion

protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
}

7invokeBeanFactoryPostProcessors(beanFactory);

// Invoke factory processors registered as beans in the context. 
Call the factory processor registered as a bean in the context.
invokeBeanFactoryPostProcessors(beanFactory); 

 

/**
 * Instantiate and invoke all registered BeanFactoryPostProcessor beans,
 * respecting explicit order if given.
 * <p>Must be called before singleton instantiation.
 */
 Instantiate and call all registered BeanFactoryPostProcessor bean
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
   PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());

   // Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime
   // (e.g. through an @Bean method registered by ConfigurationClassPostProcessor)
   if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
      beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
      beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
   }
}

Beanfactoryprocessor does a series of things, such as parsing $expressions to replace values

8registerBeanPostProcessors(beanFactory);

// Register bean processors that intercept bean creation.
Registration interception bean Created bean Processor.
registerBeanPostProcessors(beanFactory);

9initMessageSource();

initMessageSource(); For international processing

10initApplicationEventMulticaster();

// Initialize event multicaster for this context.
Initialize the event multicast for this context. For publishing listeners
initApplicationEventMulticaster();

11onRefresh();

Empty, don't bird him

12.registerListeners();

// Check for listener beans and register them.
registerListeners();     // Register listener  

13.finishBeanFactoryInitialization(beanFactory);

// Instantiate all remaining (non-lazy-init) singletons.
Instantiate all remaining (non deferred initialization) singletons
finishBeanFactoryInitialization(beanFactory);

  Instantiate all remaining (non delayed initialization) singletons with reflection, and then populate the attribute values

These three things were found in the dolls:

These are used for extension

 

 

Posted by newcastle_unite on Mon, 29 Nov 2021 05:54:00 -0800