1. Create an IOC container on the web
Starting the Web server (Tomcat) loads the web. XML (ContextLoaderListener listener) :
public class ContextLoaderListener extends ContextLoader implements ServletContextListener {
public ContextLoaderListener(WebApplicationContext context) {
super(context);
}
/** * This method is called when the serveltContext domain object is created
@Override
public void contextInitialized(ServletContextEvent event) {// Initialize the Spring container in the Web environment
initWebApplicationContext(event.getServletContext());
}
/** * Close the root web application context. */
@Override
public void contextDestroyed(ServletContextEvent event) { closeWebApplicationContext(event.getServletContext()); ContextCleanupListener.cleanupAttributes(event.getServletContext()); }}Copy the code
When we click initWebApplicationContext method in May find the following the source code This method in contextLoader Namely Contextloader create the spring container and initialize the spring bean instance
try {
// Store context in local instance variable, to guarantee that
// it is available on ServletContext shutdown.
if (this.context == null) {This step is to create the Spring container
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);
}// The Spring container initializes instances of the singleton beanconfigureAndRefreshWebApplicationContext(cwac, servletContext); }}Copy the code
ConfigureAndRefreshWebApplicationContext method called initialization Bean refresh method in the end
protected void configureAndRefreshWebApplicationContext(ConfigurableWebApplicationContext wac, ServletContext sc) {
if (ObjectUtils.identityToString(wac).equals(wac.getId())) {
// The application context id is still set to its original default value
// -> assign a more useful id based on available information
String idParam = sc.getInitParameter(CONTEXT_ID_PARAM);
if(idParam ! =null) {
wac.setId(idParam);
}
else {
// Generate default id...
wac.setId(ConfigurableWebApplicationContext.APPLICATION_CONTEXT_ID_PREFIX +
ObjectUtils.getDisplayString(sc.getContextPath()));
}
}
wac.setServletContext(sc);
String configLocationParam = sc.getInitParameter(CONFIG_LOCATION_PARAM);
if(configLocationParam ! =null) {
wac.setConfigLocation(configLocationParam);
}
// The wac environment's #initPropertySources will be called in any case when the context
// is refreshed; do it eagerly here to ensure servlet property sources are in place for
// use in any post-processing or initialization that occurs below prior to #refresh
ConfigurableEnvironment env = wac.getEnvironment();
if (env instanceof ConfigurableWebEnvironment) {
((ConfigurableWebEnvironment) env).initPropertySources(sc, null);
}
customizeContext(sc, wac);
// This method is invoked in both web and Java environments to instantiate beans
wac.refresh();
}
Copy the code
If there is no contextClass element in web.xml, Spring will find its own contextLoad.properties file to load
# Default WebApplicationContext implementation class for ContextLoader.
# Used as fallback when no explicit context implementation has been specified as context-param.
# Not meant to be customized by application developers.
org.springframework.web.context.WebApplicationContext=org.springframework.web.context.support.XmlWebApplicationContext
Copy the code
2. How does the IOC container load bean objects
Follow the refresh() method above to his source code
The source code from AbstractApplicationContext
@Override
public void refresh(a) throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// Prepare this context for refreshing.prepareRefresh();// create the real bean container ConfiurabaleBeanFactroy
//2. Load beandefiniton (information describing the Bean to be initialized)
//3. Beandefiniton is registered with the BeanDefitionRegistry
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);// Execute the Bean that implements the BeanFactoryPostProcessor interface
/ / such as accomplished (context: the property - placeholer) is invoked here, replace the placeholder BeanDefition (${}) of the content
// Invoke Factory processors registered as beans in the context
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation. / / such as container automatically loaded with a rear AutowiredAnnotationBeanPostProcessor processor (the @autowired annotation functions)
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.// Instantiate all remaining (non-lazy-init) singletons This singleton can be customized with scope scope
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(); }}}Copy the code