spring boot refresh process

Disclaimer: This article is a blogger original article, shall not be reproduced without the bloggers allowed. https://blog.csdn.net/yj1499945/article/details/87090676

As used herein, it is spring boot 1.5.9

Look at the specific method

    public void refresh() throws BeansException, IllegalStateException {
        synchronized(this.startupShutdownMonitor) {
            this.prepareRefresh();
            ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
            this.prepareBeanFactory(beanFactory);

            try {
                this.postProcessBeanFactory(beanFactory);
                this.invokeBeanFactoryPostProcessors(beanFactory);
                this.registerBeanPostProcessors(beanFactory);
                this.initMessageSource();
                this.initApplicationEventMulticaster();
                this.onRefresh();
                this.registerListeners();
                this.finishBeanFactoryInitialization(beanFactory);
                this.finishRefresh();
            } catch (BeansException var9) {
                if (this.logger.isWarnEnabled()) {
                    this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + var9);
                }

                this.destroyBeans();
                this.cancelRefresh(var9);
                throw var9;
            } finally {
                this.resetCommonCaches();
            }

        }
    }

Few actually looks like the whole spring boot to start most of the time here

prepareRefresh

Set the start time, initialize some configuration, check whether there are some of the necessary configuration

prepareBeanFactory

The bean factory settings a lot of attributes, such as: classloader (Appclassloader), set expression parser (expressions StandardBeanExpressionResolver resolve some of the bean definition), add the attribute editor registrar (ResourceEditorRegistrar), add BeanPostProcessor

Inject some other information bean, such as environment, systemProperties like.

postProcessBeanFactory

Let subclass of context to do something, used in spring boot is AnnotationConfigEmbeddedWebApplicationContext

protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
        super.postProcessBeanFactory(beanFactory);
        if (this.basePackages != null && this.basePackages.length > 0) {
            this.scanner.scan(this.basePackages);
        }

        if (this.annotatedClasses != null && this.annotatedClasses.length > 0) {
            this.reader.register(this.annotatedClasses);
        }

    }

Subclass to do is to set down the package path scanning and registration bean. But this requires you to set the default value to Null

invokeBeanFactoryPostProcessors

The literal meaning is to initialize BeanFactoryPostProcessors. For example: ConfigurationClassPostProcessor, AutowiredAnnotationBeanPostProcessor and so on.

    public static void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
   if (beanFactory instanceof BeanDefinitionRegistry) {
            BeanDefinitionRegistry registry = (BeanDefinitionRegistry)beanFactory;
            List<BeanFactoryPostProcessor> regularPostProcessors = new LinkedList();
            List<BeanDefinitionRegistryPostProcessor> registryProcessors = new LinkedList();
            Iterator var6 = beanFactoryPostProcessors.iterator();

            while(var6.hasNext()) {
                BeanFactoryPostProcessor postProcessor = (BeanFactoryPostProcessor)var6.next();
                if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
                    BeanDefinitionRegistryPostProcessor registryProcessor = (BeanDefinitionRegistryPostProcessor)postProcessor;
                    registryProcessor.postProcessBeanDefinitionRegistry(registry);
                    registryProcessors.add(registryProcessor);
                } else {
                    regularPostProcessors.add(postProcessor);
                }
            }
}
}

The above code is taken part, can be seen to some beanFactoryPostProcessors incoming processing. Call the core methods postProcessBeanDefinitionRegistry, this method is a different implementation class is not the same. Said here about realization ConfigurationClassPostProcessor this class. postProcessBeanDefinitionRegistry methods of this class will look for all @Configuration with the class. Class will be parsed and saved to beanfactory here only saved a string, other operations are not done. This is down to how the operation can not say here, expand too much.

The next three levels of priority are acquired from the class implements BeanDefinitionRegistryPostProcessor beanfactoty and postProcessBeanDefinitionRegistry method call. Priorities were PriorityOrdered, Ordered, not implementation.

The next step is to obtain the above routine class implements BeanFactoryPostProcessor, and calls postProcessBeanFactory method.

Here to say a difference, BeanDefinitionRegistryPostProcessor and a BeanFactoryPostProcessor.

BeanFactoryPostProcessor

Judging from the name, it is a BeanFactorypost-processing class, we first understand BeanFactory.

BeanFactoryThe position is quite high, it is a variety Beanof plants, provides a range of getBeanmethods commonly used ApplicationContextto inherit it.

BeanFactoryPostProcessorThat is, BeanFactorypost-processing class, we can BeanFactorydo some operations after initialization. It provides a postProcessBeanFactory()method, when this method is called, all Beanhave been created, but has not been initialized. In other words, through which we can initialize any Beanbefore, do various operations, even to read and modify BeanDefinition(bean metadata definition).

BeanDefinitionRegistryPostProcessor

This interface inherits BeanFactoryPostProcessorfrom the name of view, this interface is a BeanDefinitionRegistrypost-processor, we first introduced BeanDefinitionRegistry.

BeanDefinitionRegistryIs used to register BeanDefinitionin. BeanDefinitionIs the Beanconfiguration or metadata Beandescription information, such as Beanattribute values, parameter values and other configuration methods. The above BeanFactoryis BeanDefinitionalso by its registration.

BeanDefinitionRegistryPostProcessorIt is BeanFactoryPostProcessoran extension of the permit BeanFactoryPostProcessorbefore being called to BeanDefinitiondo something, especially it can be registered BeanFactoryPostProcessorin BeanDefinition. It provides a method postProcessBeanDefinitionRegistry(), when this method is called, all BeanDefinitionhave been loaded, but all Beanhas not been created.

note:

  • All Beangeneration have a sequence: 定义 --> 创建 --> 初始化.
  • BeanDefinitionRegistryPostProcessorThe postProcessBeanDefinitionRegistrymethod Beanis 定义however not yet been 创建executed when.
  • BeanFactoryPostProcessorThe postProcessBeanFactorymethod Beanis 创建however not yet been 初始化time to execute

 

registerBeanPostProcessors

The next step is registered BeanPostProcessors. First is to get the corresponding class BeanPostProcessor implemented according to an order from the beanfactory.

According to the precedence being PriorityOrdered, Ordered, not implementation. Add the three categories of BeanPostProcessors to beanfactory, this addition is added according to priority.

initMessageSource

    protected void initMessageSource() {
        ConfigurableListableBeanFactory beanFactory = this.getBeanFactory();
        if (beanFactory.containsLocalBean("messageSource")) {
            this.messageSource = (MessageSource)beanFactory.getBean("messageSource", MessageSource.class);
            if (this.parent != null && this.messageSource instanceof HierarchicalMessageSource) {
                HierarchicalMessageSource hms = (HierarchicalMessageSource)this.messageSource;
                if (hms.getParentMessageSource() == null) {
                    hms.setParentMessageSource(this.getInternalParentMessageSource());
                }
            }

            if (this.logger.isDebugEnabled()) {
                this.logger.debug("Using MessageSource [" + this.messageSource + "]");
            }
        } else {
            DelegatingMessageSource dms = new DelegatingMessageSource();
            dms.setParentMessageSource(this.getInternalParentMessageSource());
            this.messageSource = dms;
            beanFactory.registerSingleton("messageSource", this.messageSource);
            if (this.logger.isDebugEnabled()) {
                this.logger.debug("Unable to locate MessageSource with name 'messageSource': using default [" + this.messageSource + "]");
            }
        }

    }

Initiated a DelegatingMessageSource handling class as internationalization.

initApplicationEventMulticaster

First, we have to make clear some of the concepts

Event: ApplicationEvent

Event listeners: ApplicationListener, to listen to the event for processing.

Event broadcaster: ApplicationEventMulticaster, the Springpublish event broadcast to all listeners.

    protected void initApplicationEventMulticaster() {
        ConfigurableListableBeanFactory beanFactory = this.getBeanFactory();
        if (beanFactory.containsLocalBean("applicationEventMulticaster")) {
            this.applicationEventMulticaster = (ApplicationEventMulticaster)beanFactory.getBean("applicationEventMulticaster", ApplicationEventMulticaster.class);
            if (this.logger.isDebugEnabled()) {
                this.logger.debug("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
            }
        } else {
            this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
            beanFactory.registerSingleton("applicationEventMulticaster", this.applicationEventMulticaster);
            if (this.logger.isDebugEnabled()) {
                this.logger.debug("Unable to locate ApplicationEventMulticaster with name 'applicationEventMulticaster': using default [" + this.applicationEventMulticaster + "]");
            }
        }

    }

This method initializes a SimpleApplicationEventMulticaster as the default broadcaster

onRefresh

This method is implemented by the parent EmbeddedWebApplicationContext AnnotationConfigEmbeddedWebApplicationContext

    private void createEmbeddedServletContainer() {
        EmbeddedServletContainer localContainer = this.embeddedServletContainer;
        ServletContext localServletContext = this.getServletContext();
        if (localContainer == null && localServletContext == null) {
            EmbeddedServletContainerFactory containerFactory = this.getEmbeddedServletContainerFactory();
            this.embeddedServletContainer = containerFactory.getEmbeddedServletContainer(new ServletContextInitializer[]{this.getSelfInitializer()});
        } else if (localServletContext != null) {
            try {
                this.getSelfInitializer().onStartup(localServletContext);
            } catch (ServletException var4) {
                throw new ApplicationContextException("Cannot initialize servlet context", var4);
            }
        }

        this.initPropertySources();
    }

This is part of the code, is generated where the main vessel of a TomcatEmbeddedServletContainer. Here a total of three container

UndertowEmbeddedServletContainer

JettyEmbeddedServletContainer

TomcatEmbeddedServletContainer

registerListeners

 protected void registerListeners() {
        Iterator var1 = this.getApplicationListeners().iterator();

        while(var1.hasNext()) {
            ApplicationListener<?> listener = (ApplicationListener)var1.next();
            this.getApplicationEventMulticaster().addApplicationListener(listener);
        }

        String[] listenerBeanNames = this.getBeanNamesForType(ApplicationListener.class, true, false);
        String[] var7 = listenerBeanNames;
        int var3 = listenerBeanNames.length;

        for(int var4 = 0; var4 < var3; ++var4) {
            String listenerBeanName = var7[var4];
            this.getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
        }

        Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
        this.earlyApplicationEvents = null;
        if (earlyEventsToProcess != null) {
            Iterator var9 = earlyEventsToProcess.iterator();

            while(var9.hasNext()) {
                ApplicationEvent earlyEvent = (ApplicationEvent)var9.next();
                this.getApplicationEventMulticaster().multicastEvent(earlyEvent);
            }
        }

    }

The time listeners in the Spring container and BeanFactory in time listeners are added in the event broadcaster

 

finishBeanFactoryInitialization

 protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
        if (beanFactory.containsBean("conversionService") && beanFactory.isTypeMatch("conversionService", ConversionService.class)) {
            beanFactory.setConversionService((ConversionService)beanFactory.getBean("conversionService", ConversionService.class));
        }

        if (!beanFactory.hasEmbeddedValueResolver()) {
            beanFactory.addEmbeddedValueResolver(new StringValueResolver() {
                public String resolveStringValue(String strVal) {
                    return AbstractApplicationContext.this.getEnvironment().resolvePlaceholders(strVal);
                }
            });
        }

        String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
        String[] var3 = weaverAwareNames;
        int var4 = weaverAwareNames.length;

        for(int var5 = 0; var5 < var4; ++var5) {
            String weaverAwareName = var3[var5];
            this.getBean(weaverAwareName);
        }

        beanFactory.setTempClassLoader((ClassLoader)null);
        beanFactory.freezeConfiguration();
        beanFactory.preInstantiateSingletons();
    }

Remember those before beanfactory only string bean object it, where they want to get the real objects through reflection. The most important method by preInstantiateSingletons, this is the default beanfactory DefaultListableBeanFactory

 

finishRefresh

    protected void finishRefresh() {
        this.initLifecycleProcessor();
        this.getLifecycleProcessor().onRefresh();
        this.publishEvent((ApplicationEvent)(new ContextRefreshedEvent(this)));
        LiveBeansView.registerApplicationContext(this);
    }

Here to refresh to achieve a LifecycleProcessoer class.

Posted ContextRefreshedEvent event ApplicationListener inform the corresponding response of the operation

There is registerApplicationContext registered by jmx related things

Guess you like

Origin blog.csdn.net/yj1499945/article/details/87090676