Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How does springboot2.0.6 start the listener

2025-01-19 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Internet Technology >

Share

Shulou(Shulou.com)06/02 Report--

This article introduces how to start the springboot2.0.6 listener, the content is very detailed, interested friends can use for reference, I hope it can be helpful to you.

Parsing SpringApplication run method parsing public ConfigurableApplicationContext run (String... Args) {. / / omit / / get a run listener, which mainly listens to the SpringApplication object, (there is only one EventPublishingRunListener inside) SpringApplicationRunListeners listeners = getRunListeners (args); / / calls the startup of the listener when the run method of the SpringApplication object is just started (depending on SimpleApplicationEventMulticaster) listeners.starting ();. / omit} 1. SpringApplicationRunListeners

SpringApplicationRunListeners is a collection class that contains a log and a List that contains SpringApplicationRunListener. SpringApplicationRunListener, on the other hand, mainly listens to SpringApplication objects, and the methods in it define when to call various methods of SpringApplicationRunListener.

Each of the following methods, SpringApplicationRunListener, wraps it as an event. Before the spring container successfully refreshed, it uses SimpleApplicationEventMulticaster to find the ApplicationListener interested in the event, and then calls its onApplicationEvent method.

Starting: when the run method of the SpringApplication object is first started (depending on SimpleApplicationEventMulticaster)

EnvironmentPrepared: when environmentPrepared but the spring container has not been created (relying on SimpleApplicationEventMulticaster)

ContextPrepared: when the spring container has been created and ready (currently an empty implementation)

ContextLoaded: when the spring container is already loaded and not refresh. Load registers our primaryClass in the spring container (depending on SimpleApplicationEventMulticaster) and adds all the previously acquired ApplicationListener to the spring container. If the ApplicationListener is still ApplicationContextAware, call its setApplicationContext method.

The started:spring container has been refreshed and the application has been started, but CommandLineRunners and ApplicationRunners have not been called yet and are sent directly through the spring container itself (because ApplicationListener has joined the spring container)

Running: we have called CommandLineRunners and sent it directly through the spring container (because ApplicationListener has joined the spring container)

Failed: call this when an exception occurs. If the spring container does not have loaded or activation, use SimpleApplicationEventMulticaster, otherwise it still depends on the spring container itself.

two。 Get SpringApplicationRunListeners instance source code analysis 1. GetRunListenerspublic class SpringApplication {/ / get listening private SpringApplicationRunListeners getRunListeners (String [] args) {/ / define class array Class [] types = new Class [] {SpringApplication.class, String [] .class}; / / create SpringApplicationRunListeners object return new SpringApplicationRunListeners (logger, getSpringFactoriesInstances (SpringApplicationRunListener.class, types, this, args);}}

By default, the getRunListeners method finds out that the classes whose key is SpringApplicationRunListener from the spring.factories file are:

Org.springframework.boot.context.event.EventPublishingRunListener

Here we see a familiar method getSpringFactoriesInstances (SpringApplicationRunListener.class, types, this, args). In the previous blog post, we have described in detail how this method obtains the value of the specified key in META-INF/spring.factories step by step, and how to instantiate the class in the future (see). Execute the obtained values as shown in the following figure

From the debug result in the figure above, we can see that we have obtained a listener EventPublishingRunListener, which is the startup listener of the Spring container. The listeners.starting () method turns on listening for events

2. SpringApplicationRunListener implementation class EventPublishingRunListenerpublic class EventPublishingRunListener implements SpringApplicationRunListener, Ordered {private final SpringApplication application; private final String [] args; private final SimpleApplicationEventMulticaster initialMulticaster; / / load listener class public EventPublishingRunListener (SpringApplication application, String [] args) {this.application = application; this.args = args; this.initialMulticaster = new SimpleApplicationEventMulticaster (); / / add listener for (ApplicationListener listener: application.getListeners ()) {this.initialMulticaster.addApplicationListener (listener) to initialMulticaster }} / / the implementation class calls the method public void starting () {this.initialMulticaster.multicastEvent of EventPublishingRunListener (/ / creates an ApplicationStartingEvent event and passes in the this.application of springapplication, so the SpringApplication instance new ApplicationStartingEvent (this.application, this.args) is obtained when listening;}. / / omitted}

In the initialization method of EventPublishingRunListener, application and args are assigned, and SimpleApplicationEventMulticaster is initialized, then the listeners in application are obtained and added to the SimpleApplicationEventMulticaster object.

Enter the initialization method of the SimpleApplicationEventMulticaster class, as follows

Public class SimpleApplicationEventMulticaster extends AbstractApplicationEventMulticaster {private Executor taskExecutor; private ErrorHandler errorHandler; public void multicastEvent (ApplicationEvent event) {multicastEvent (event, resolveDefaultEventType (event));} public void multicastEvent (final ApplicationEvent event, @ Nullable ResolvableType eventType) {ResolvableType type = (eventType! = null? EventType: resolveDefaultEventType (event)); / / notice that getApplicationListeners gets the corresponding event listener for (final ApplicationListener listener: getApplicationListeners (event, type)) {Executor executor = getTaskExecutor (); if (executor! = null) {executor.execute (()-> invokeListener (listener, event));} else {invokeListener (listener, event);}

The SimpleApplicationEventMulticaster class inherits AbstractApplicationEventMulticaster

Public abstract class AbstractApplicationEventMulticaster implements ApplicationEventMulticaster, BeanClassLoaderAware, BeanFactoryAware {protected Collection sourceType = (source! = null? Source.getClass (): null); ListenerCacheKey cacheKey = new ListenerCacheKey (eventType, sourceType); / / Quick check for existing entry on ConcurrentHashMap... / / quickly detect the existing entry of COncurrentHashMap ListenerRetriever retriever = this.retrieverCache.get (cacheKey); if (retriever! = null) {return retriever.getApplicationListeners () } if (this.beanClassLoader = = null | | (ClassUtils.isCacheSafe (event.getClass (), this.beanClassLoader) & & (sourceType = = null | | ClassUtils.isCacheSafe (sourceType, this.beanClassLoader) {/ / Fully synchronized building and caching of a ListenerRetriever synchronized (this.retrievalMutex) {retriever = this.retrieverCache.get (cacheKey) If (retriever! = null) {return retriever.getApplicationListeners ();} retriever = new ListenerRetriever (true); Collection > retrieveApplicationListeners (ResolvableType eventType, @ Nullable Class sourceType, @ Nullable ListenerRetriever retriever) {List > listeners; Set listenerBeans Synchronized (this.retrievalMutex) {/ / this listener collection is the 10 listeners filtered from the configuration mentioned earlier (figure 1) listeners = new LinkedHashSet (this.defaultRetriever.applicationListeners); listenerBeans = new LinkedHashSet (this.defaultRetriever.applicationListenerBeans) } / / Loop 10 listener calls supportsEvent method for (ApplicationListener listener: listeners) {if (supportsEvent (listener, eventType, sourceType)) {if (retriever! = null) {retriever.applicationListeners.add (listener);} allListeners.add (listener) }}. / / omit AnnotationAwareOrderComparator.sort (allListeners); if (retriever! = null & & retriever.applicationListenerBeans.isEmpty ()) {retriever.applicationListeners.clear (); retriever.applicationListeners.addAll (allListeners);} return allListeners;} protected boolean supportsEvent (ApplicationListener listener, ResolvableType eventType, @ Nullable Class sourceType) {GenericApplicationListener smartListener = (listener instanceof GenericApplicationListener? (GenericApplicationListener) listener: new GenericApplicationListenerAdapter (listener); return (smartListener.supportsEventType (eventType) & & smartListener.supportsSourceType (sourceType));}} 3. Monitoring process

-- > Program start

-- > call getRunListeners (args) to get SpringApplicationRunListeners instance

-- > getSpringFactoriesInstances () gets the collection of Spring factory instances

-- > loadFactoryNames () loads the / META-INF/spring.factories file through classLoader to get the collection of fully qualified names of the class corresponding to the specified class

-- > loadSpringFactories () loads the / META-INF/spring.factories file through the classLoader loop, and returns the collection of fully qualified names of classes in the file.

-- > createSpringFactoriesInstances () creates a factory instance based on the collection of fully qualified names of classes returned by the load file, reflecting

-- > listeners.starting () starts the listener

MulticastEvent (ApplicationEvent event) Multicast ApplicationEvent event

-- > getApplicationListeners () determines whether the listener type is the same as the current listener type

-- > retrieveApplicationListeners (eventType, sourceType, retriever) retrieves application listeners of a given event and source type.

-- > supportsEvent (listener, eventType, sourceType) confirms whether a given listener supports a given event.

-- > GenericApplicationListenerAdapter (ApplicationListener delegate) creates a new GenericApplicationListener for the given delegate.

-- > resolveDeclaredEventType (ApplicationListener listener) publish event listening

-- > supportsEventType (eventType) parses events from the specified type

-- > end

4. The relationship between SpringApplicationRunListener,ApplicationListener and SimpleApplicationEventMulticaster

The underlying SpringApplicationRunListener methods still rely on the spring container to publish events

The bottom layer will still be monitored by ApplicationListener.

After the spring container prepareContext call, ApplicationListener is added to the SimpleApplicationEventMulticaster, and after that, all events are sent by lazy, that is, the earlyApplicationEvents exists first. Wait until after the spring container refresh to register all ApplicationListener, and then the events stored before being uniformly sent.

On how to start the springboot2.0.6 listener to share here, I hope that the above content can be of some help to you, can learn more knowledge. If you think the article is good, you can share it for more people to see.

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Internet Technology

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report