Cet article analyse la recherche sur le code source d'IOC au démarrage de Spring Web
Pour étudier IOC, créez d'abord un projet web simple.xml nous ajouterons la phrase ci-dessus
<context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:applicationContext.xml</param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener>
signifie que lorsque le conteneur Web démarre, il entrera d'abord dans la classe ContextLoaderListener puis chargez-le. fichier applicationContext.xml sous classpath. Ensuite, l'accent est mis sur ContextLoaderListener, cliquez sur le code open source :
/** * Initialize the root web application context. */ @Override public void contextInitialized(ServletContextEvent event) { initWebApplicationContext(event.getServletContext()); } /** * Close the root web application context. */ @Override public void contextDestroyed(ServletContextEvent event) { closeWebApplicationContext(event.getServletContext()); ContextCleanupListener.cleanupAttributes(event.getServletContext()); }
qui contient principalement deux méthodes d'implémentation de ServletContextListenerinterface . Le conteneur Web appellera d'abord la méthode contextInitialized, transmettra les ressources du conteneur encapsulées par Tomcat, puis appellera la méthode du conteneur d'initialisation de la classe parent.
/*** The root WebApplicationContext instance that this loader manages.*/private WebApplicationContext context;public WebApplicationContext initWebApplicationContext(ServletContext servletContext) { ...........省略// Store context in local instance variable, to guarantee that // it is available on ServletContext shutdown. if (this.context == null) { this.context = createWebApplicationContext(servletContext); } if (this.context instanceof ConfigurableWebApplicationContext) { ConfigurableWebApplicationContext cwac = (ConfigurableWebApplicationContext) this.context; if (!cwac.isActive()) { // The context has not yet been refreshed -> provide services such as // setting the parent context, setting the application context id, etc if (cwac.getParent() == null) { // The context instance was injected without an explicit parent -> // determine parent for root web application context, if any. ApplicationContext parent = loadParentContext(servletContext); cwac.setParent(parent); } configureAndRefreshWebApplicationContext(cwac, servletContext); } } servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, this.context); ClassLoader ccl = Thread.currentThread().getContextClassLoader(); if (ccl == ContextLoader.class.getClassLoader()) { currentContext = this.context; } else if (ccl != null) { currentContextPerThread.put(ccl, this.context); } ......省略 return this.context; }
L'étape principale de cette méthode est la méthode createWebApplicationContext, qui est utilisée pour créer le conteneur racine de XmlWebApplicationContext, qui est extrait de servletContextEvent.
La méthode loadParentContext est utilisée pour charger le conteneur parent. La méthode principale configureAndRefreshWebApplicationContext est utilisée pour configurer et actualiser le conteneur racine. La méthode la plus importante au sein de la méthode est la méthode d'actualisation, qui implémente les fonctions les plus importantes.
@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) { 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; } } }
La méthode prepareRefresh est utilisée pour préparer l'environnement qui sera utilisé ultérieurement.
La méthode getFreshBeanFactory obtient le beanFactory
@Override protected final void refreshBeanFactory() throws BeansException { if (hasBeanFactory()) { destroyBeans(); closeBeanFactory(); } try { DefaultListableBeanFactory beanFactory = createBeanFactory(); beanFactory.setSerializationId(getId()); customizeBeanFactory(beanFactory); loadBeanDefinitions(beanFactory); synchronized (this.beanFactoryMonitor) { this.beanFactory = beanFactory; } } catch (IOException ex) { throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex); } }
Le beanFactory réellement renvoyé est sa classe d'implémentation DefaultListableBeanFactory, qui est instanciée pour un chargement ultérieur. en XML.
loadBeanDefinitions est une méthode importante, utilisée pour charger réellement la classe. Les précédentes étaient toutes des travail de préparation.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!