Spring’s entry is AbstractApplicationContext refresh methods
The Refresh method is designed to invoke the following main methods
- prepareRefresh();
- The prepareRefresh method prepares the container before it refreshes
- Set the startup time of the container
- Set the active state to true
- Set the off state to false
- Gets the Environment object and loads the current system property values into the Environment object
- Collection object ready for listeners and events, an empty collection by default
The source code is as follows, the processing is relatively simple:
Protected void prepareRefresh() {// Switch to active. // Set the time when the container is started this.startupDate = System.currentTimemillis (); // The container's closing bit this.closed. Set (false); // The container's activation flag bit this.active. Set (true); Logger.isdebugenabled ()) {if (logger.istraceEnabled ()) {logger.trace("Refreshing "+ this); } else { logger.debug("Refreshing " + getDisplayName()); } // Initialize any placeholder property sources in the context environment. // Validate that all properties marked as required are resolvable: / / see ConfigurablePropertyResolver# setRequiredProperties / / to create an environment and get the object, Verify whether need properties files are in the environment getEnvironment () validateRequiredProperties (); // Store pre-refresh ApplicationListeners... // Determine whether the application listener collection before the refresh is empty, if so, Add a listener to the collection of the if (this. EarlyApplicationListeners = = null) {enclosing earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners); } else {// Reset local application listeners to pre-refresh state. Collection is empty element object this. ApplicationListeners. The clear (); this.applicationListeners.addAll(this.earlyApplicationListeners); } // Allow for the collection of early ApplicationEvents, // to be published once the multicaster is available... / / create a refresh before listening event set enclosing earlyApplicationEvents = new LinkedHashSet < > (); }Copy the code
- ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
Main Work:
- Create a container object: DefaultListableBeanFactory
- Load the attribute values of the XML configuration file into the current factory, the most important being the BeanDefinition
We can see the DefaultListableBeanFactory class class diagram, take a look at the class hierarchy
Through refreshBeanFactory create DefaultListableBeanFactory object, set the relevant properties of the beanFactory, reads the configuration file parsing to BeanDefinition configuration file content
@override protected final void refreshBeanFactory() throws BeansException { Then destroy beanFactory if (hasBeanFactory()) {destroyBeans(); closeBeanFactory(); } the try {/ / create DefaultListableBeanFactory object DefaultListableBeanFactory the beanFactory = createBeanFactory (); / / to serialize the specified id, can from id deserialized to the beanFactory object the beanFactory. SetSerializationId (getId ()); // Customize the beanFactory, set the related properties, including whether to allow overwriting objects with different definitions of the same name and loop on the customizeBeanFactory(beanFactory); LoadBeanDefinitions (beanFactory) loadBeanDefinitions(beanFactory) loadBeanDefinitions(beanFactory) this.beanFactory = beanFactory; } catch (IOException ex) { throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex); }}Copy the code
- prepareBeanFactory
- BeanFactory preparation to populate various properties
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) { // Tell the internal bean factory to Use the context's classloader etc. // Set beanFactory's classloader to the current context's classloader beanFactory.setBeanClassLoader(getClassLoader()); / / set the beanfactory expression language processor. The beanfactory setBeanExpressionResolver (new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader())); // Add a default propertyEditor to beanFactory, This is mainly to the bean's properties, such as a tool to set up management class. The beanFactory addPropertyEditorRegistrar (new ResourceEditorRegistrar (this, getEnvironment ())); // Configure the bean factory with context callbacks. // Add beanPostProcessor ApplicationContextAwareProcessor such used to accomplish certain Aware objects into the beanFactory. AddBeanPostProcessor (new ApplicationContextAwareProcessor(this)); // Set to ignore autologime interfaces, since implementations of these interfaces are injected by the container via the set method, / / so when using the autowire injection. These interfaces need to ignore the 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. // Set several special rules for autowiring when there are multiple implementations of ioc initializations. Then use the specified object into the beanFactory. RegisterResolvableDependency (the beanFactory. Class, the 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. // Add support for AspectJ. Compiler weaving means that sections are woven into Java classes at the Java compiler, using a special compiler, and classload-time weaving means that sections are woven into Java classes at the time the class bytecode is loaded into the JVM, using a special classloader. // AspectJ provides two ways of weaving. The first is through a special compiler, where aspectJ classes are woven into Java classes, and the second is classload-time weaving. Load Time Weaving, Subsequent here speak the if (the beanFactory containsBean (LOAD_TIME_WEAVER_BEAN_NAME)) {the beanFactory. AddBeanPostProcessor (new LoadTimeWeaverAwareProcessor(beanFactory)); // Set a temporary ClassLoader for type matching. beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader())); } // Register default environment beans. // Register default environment beans to level 1 cache 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()); }}Copy the code
- invokeBeanFactoryPostProcessors
- Call various beanFactory processors
/ * * * to Instantiate and call all have registered of spring beanFactoryPostProcessor, indicate the order follow * * Instantiate and invoke all registered spring beanFactoryPostProcessor beans, * respecting explicit order if given. * <p>Must be called before singleton instantiation. */ protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) { // Access to the current application context beanFactoryPostProcessors the value of a variable, and instance call perform all registered spring beanFactoryPostProcessor / / by default, Through getBeanFactoryPostProcessors BFPP () to obtain has been registered, but the default is empty, then the problem is coming, if you want to expand, how to expand work? 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())); }}Copy the code
- registerBeanPostProcessors
- Register the bean handler, which is just the registration function, and what is really called is the getBean method
/** * Instantiate and register all beanPostProcessor beans * respecting explicit order if given. * <p>Must be called before any instantiation of application beans. */ protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) { PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this); }Copy the code
- initApplicationEventMulticaster
- Initialize the event to listen for multiplexers
/** * Initialize the ApplicationEventMulticaster. * Uses SimpleApplicationEventMulticaster if none defined in the context. * @see org.springframework.context.event.SimpleApplicationEventMulticaster */ protected void InitApplicationEventMulticaster () {/ / get the current bean plant, usually DefaultListableBeanFactory ConfigurableListableBeanFactory beanFactory = getBeanFactory(); / / whether the container exists bdName applicationEventMulticaster bd, multicast is a custom event listeners, Must implement ApplicationEventMulticaster interface if (the beanFactory containsLocalBean (APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {/ / if you have, The object from the bean bean factory this. ApplicationEventMulticaster = the beanFactory. GetBean (APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class); if (logger.isTraceEnabled()) { logger.trace("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "] "); }} else {// If not, The default using SimpleApplicationEventMulticaster enclosing applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory); beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster); if (logger.isTraceEnabled()) { logger.trace("No '" + APPLICATION_EVENT_MULTICASTER_BEAN_NAME + "' bean, using " + "[" + this.applicationEventMulticaster.getClass().getSimpleName() + "]"); }}}Copy the code
- registerListeners
- Look for the Listener bean among all registered beans to register with the message broadcaster
/** ** Listeners that implement ApplicationListener as listeners. * Doesn't affect other listeners, which can be added without being beans. */ protected void registerListeners() { // Register statically specified Listeners first. // Traverse the collection of listeners existing in the application and add listeners to the listeners multiplexer. > listener : getApplicationListeners()) { getApplicationEventMulticaster().addApplicationListener(listener); } // Do not initialize FactoryBeans here: We need to leave all regular beans // uninitialized to let post-processors apply to them! // Get all bd names from the container that implement the ApplicationListener interface // put them in the ApplicationListenerBeans collection String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false); for (String listenerBeanName : listenerBeanNames) { getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName); // getApplicationEventMulticaster().addApplicationListener(this.getBean(listenerBeanName,ApplicationListener.class)); } // Publish early application events now that we finally have a multicaster... / / here first released early listeners collection Set < ApplicationEvent > earlyEventsToProcess = this. EarlyApplicationEvents; this.earlyApplicationEvents = null; if (! CollectionUtils.isEmpty(earlyEventsToProcess)) { for (ApplicationEvent earlyEvent : earlyEventsToProcess) { getApplicationEventMulticaster().multicastEvent(earlyEvent); }}}Copy the code
- finishBeanFactoryInitialization
- Initialize remaining single instances (not lazily loaded)
/** * Finish the initialization of this context's bean factory, * initializing all remaining singleton beans. */ protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) { // Initialize conversion service for this Context. // Initialize the type converter if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) && for the context 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
The core logic in the preInstantiateSingletons method:
@Override public void preInstantiateSingletons() throws BeansException { if (logger.isTraceEnabled()) { logger.trace("Pre-instantiating singletons in " + this); } // Iterate over a copy to allow for init methods which in turn register new bean definitions. // While this may not be part of the regular factory bootstrap, It does otherwise work fine. // Create a collection of all BeanDefinition names List<String> beanNames = new ArrayList<>(this.beanDefinitionNames); // Trigger initialization of all non-lazy singleton beans... // Trigger the initialization of all non-lazy-loaded singleton beans, traversing the collection object for (String beanName: BeanNames) {/ / merge the superclass BeanDefinition RootBeanDefinition bd = getMergedLocalBeanDefinition (beanName); // Conditional judgment, abstract, singleton, non-lazy loading if (! bd.isAbstract() && bd.isSingleton() && ! Bd.islazyinit ()) {if (isFactoryBean(beanName)) {&+beanName = getBean(FACTORY_BEAN_PREFIX + beanName); If (bean instanceof FactoryBean) {FactoryBean<? > factory = (FactoryBean<? >) bean; // Determine if this FactoryBean wants to initialize Boolean isEagerInit immediately; if (System.getSecurityManager() ! = null && factory instanceof SmartFactoryBean) { isEagerInit = AccessController.doPrivileged( (PrivilegedAction<Boolean>) ((SmartFactoryBean<? >) factory)::isEagerInit, getAccessControlContext()); } else { isEagerInit = (factory instanceof SmartFactoryBean && ((SmartFactoryBean<? >) factory).isEagerInit()); } if (isEagerInit) {getBean(beanName); }}} else {// If the bean corresponding to beanName is not a FactoryBean, just plain bean, get the bean instance getBean(beanName); } } } // Trigger post-initialization callback for all applicable beans... / / traverse beanNames, trigger all SmartInitializingSingleton initialization callback after the for (String beanName: Object singletonInstance = getSingleton(beanName); / / determine whether singletonInstance implements SmartInitializingSingleton interface if (singletonInstance instanceof SmartInitializingSingleton) { / / type conversion SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton singletonInstance); / / trigger SmartInitializingSingleton implementation class afterSingletonsInstantiated method if (System. GetSecurityManager ()! = null) { AccessController.doPrivileged((PrivilegedAction<Object>) () -> { smartSingleton.afterSingletonsInstantiated(); return null; }, getAccessControlContext()); } else { smartSingleton.afterSingletonsInstantiated(); }}}}Copy the code