Spring 初始化过程详细分析 [源码] (二)

来源:互联网 发布:淘宝做任务返利 编辑:程序博客网 时间:2024/04/28 04:55

上章讲到org.springframework.context.support.AbstractApplicationContext.refresh() ,这个方法完成了spring IOC容器的初始化, 在看代码前,我们首先要大概了解下spring BeanFactory,web项目默认用实现类XmlWebApplicationContext,它作为web上下文,而他的父类AbstractRefreshableApplicationContext类有个DefaultListableBeanFactory的属性, 这才是真正的容器,所有的bean的初始化都是通过此类,他们都实现了BeanFactory接口, 先看看下面的类图, 一些本文主要涉及的类。



我们继续上一章,来看看refresh方法具体做了什么。


@Overridepublic void refresh() throws BeansException, IllegalStateException {synchronized (this.startupShutdownMonitor) {// Prepare this context for refreshing.prepareRefresh();// Tell the subclass to refresh the internal bean factory.返回的是DefaultListableBeanFactoryConfigurableListableBeanFactory 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;}}}


首先看第一步 调用了prepareRefresh()方法,看方法名就知道是准备工作,主要是记录开始时间,标记激活标记,servlet初始化参数及校验


/** * Prepare this context for refreshing, setting its startup date and * active flag as well as performing any initialization of property sources. */protected void prepareRefresh() {this.startupDate = System.currentTimeMillis();this.active.set(true);if (logger.isInfoEnabled()) {logger.info("Refreshing " + this);}// Initialize any placeholder property sources in the context environmentinitPropertySources();// Validate that all properties marked as required are resolvable// see ConfigurablePropertyResolver#setRequiredPropertiesgetEnvironment().validateRequiredProperties();}

回到refresh(), 下一步调用obtainFreshBeanFactory(),初始化bean工厂, 使用的是DefaultListableBeanFactory类,该类实现两大接口ConfigurableListableBeanFactory(BeanFactory子类)和BeanDefinitionRegistry接口,就有了bean容器和bean注册功能。

上面已经说到AbstractRefreshableApplicationContext类有DefaultListableBeanFactory的属性,beanFactory就存此属性.


/** * Tell the subclass to refresh the internal bean factory. * @return the fresh BeanFactory instance * @see #refreshBeanFactory() * @see #getBeanFactory() */protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {refreshBeanFactory();//父类AbstractRefreshableApplicationContext类的方法,刷新beanfactory,存在就重建ConfigurableListableBeanFactory beanFactory = getBeanFactory();if (logger.isDebugEnabled()) {logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory);}return beanFactory;}/** * This implementation performs an actual refresh of this context's underlying * bean factory, shutting down the previous bean factory (if any) and * initializing a fresh bean factory for the next phase of the context's lifecycle. */@Overrideprotected final void refreshBeanFactory() throws BeansException {if (hasBeanFactory()) {//如果已经存在先清除destroyBeans();closeBeanFactory();}try {DefaultListableBeanFactory beanFactory = createBeanFactory();beanFactory.setSerializationId(getId());customizeBeanFactory(beanFactory);// 自定义设置bean是否覆盖和是否支持bean循环引用, 默认都为trueloadBeanDefinitions(beanFactory); //子类实现synchronized (this.beanFactoryMonitor) {this.beanFactory = beanFactory;}}catch (IOException ex) {throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);}}        protected DefaultListableBeanFactory createBeanFactory() {return new DefaultListableBeanFactory(getInternalParentBeanFactory());}        protected void customizeBeanFactory(DefaultListableBeanFactory beanFactory) {if (this.allowBeanDefinitionOverriding != null) {beanFactory.setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);}if (this.allowCircularReferences != null) {beanFactory.setAllowCircularReferences(this.allowCircularReferences);}}


看下loadBeanDefinitions(DefaultListableBeanFactory beanFactory),  它由org.springframework.web.context.support.XmlWebApplicationContext实现,主要是解析xml, 转换成beanDefinition.

@Overrideprotected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {// Create a new XmlBeanDefinitionReader for the given BeanFactory.XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);// Configure the bean definition reader with this context's// resource loading environment.beanDefinitionReader.setEnvironment(getEnvironment());beanDefinitionReader.setResourceLoader(this);beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));//设置xsd dtd解析类// Allow a subclass to provide custom initialization of the reader,// then proceed with actually loading the bean definitions.initBeanDefinitionReader(beanDefinitionReader);loadBeanDefinitions(beanDefinitionReader);}

进入org.springframework.beans.factory.xml.XmlBeanDefinitionReader父类的构造方法:

protected AbstractBeanDefinitionReader(BeanDefinitionRegistry registry) {Assert.notNull(registry, "BeanDefinitionRegistry must not be null");this.registry = registry;// Determine ResourceLoader to use.if (this.registry instanceof ResourceLoader) {this.resourceLoader = (ResourceLoader) this.registry;}else {//DefaultListableBeanFactory没有继承ResourceLoader接口,进入这个判断this.resourceLoader = new PathMatchingResourcePatternResolver();}// Inherit Environment if possibleif (this.registry instanceof EnvironmentCapable) {this.environment = ((EnvironmentCapable) this.registry).getEnvironment();}else {this.environment = new StandardEnvironment();}}
再看下一步,进入loadBeanDefinitions方法, 这里把(web.xml)配置的xml路径交给BeanDefinitionReader解析并加载成BeanDefinition


protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws IOException {String[] configLocations = getConfigLocations();if (configLocations != null) {for (String configLocation : configLocations) {reader.loadBeanDefinitions(configLocation);}}}public int loadBeanDefinitions(String location, Set<Resource> actualResources) throws BeanDefinitionStoreException {ResourceLoader resourceLoader = getResourceLoader();if (resourceLoader == null) {throw new BeanDefinitionStoreException("Cannot import bean definitions from location [" + location + "]: no ResourceLoader available");}if (resourceLoader instanceof ResourcePatternResolver) {// Resource pattern matching available.try {   //这里返回的是上面初始化的PathMatchingResourcePatternResolver, 支持classpath*:,读取所有xml配置文件Resource[] resources = ((ResourcePatternResolver) resourceLoader).getResources(location);int loadCount = loadBeanDefinitions(resources);//主要是看这方法if (actualResources != null) {for (Resource resource : resources) {actualResources.add(resource);}}if (logger.isDebugEnabled()) {logger.debug("Loaded " + loadCount + " bean definitions from location pattern [" + location + "]");}return loadCount;}catch (IOException ex) {throw new BeanDefinitionStoreException("Could not resolve bean definition resource pattern [" + location + "]", ex);}}else {// Can only load single resources by absolute URL.Resource resource = resourceLoader.getResource(location);int loadCount = loadBeanDefinitions(resource);if (actualResources != null) {actualResources.add(resource);}if (logger.isDebugEnabled()) {logger.debug("Loaded " + loadCount + " bean definitions from location [" + location + "]");}return loadCount;}}
从上面的loadBeanDefinitions(resource)一层层调用(中单比较简单的调用就省略了),  最终进入下面XmlBeanDefinitionReader的loadBeanDefinitions方法, 这个方法


public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException {Assert.notNull(encodedResource, "EncodedResource must not be null");if (logger.isInfoEnabled()) {logger.info("Loading XML bean definitions from " + encodedResource.getResource());}Set<EncodedResource> currentResources = this.resourcesCurrentlyBeingLoaded.get();//当前线程缓存if (currentResources == null) { //第一次为空currentResources = new HashSet<EncodedResource>(4);this.resourcesCurrentlyBeingLoaded.set(currentResources);}if (!currentResources.add(encodedResource)) {//避免循环导入throw new BeanDefinitionStoreException("Detected cyclic loading of " + encodedResource + " - check your import definitions!");}try {InputStream inputStream = encodedResource.getResource().getInputStream();//把配置文件读成流try {InputSource inputSource = new InputSource(inputStream);if (encodedResource.getEncoding() != null) {inputSource.setEncoding(encodedResource.getEncoding());}return doLoadBeanDefinitions(inputSource, encodedResource.getResource());}finally {inputStream.close();}}catch (IOException ex) {throw new BeanDefinitionStoreException("IOException parsing XML document from " + encodedResource.getResource(), ex);}finally {currentResources.remove(encodedResource);if (currentResources.isEmpty()) {this.resourcesCurrentlyBeingLoaded.remove();}}}

进入doLoadBeanDefinitions方法, 这个方法先加载xml文件,再注册bean定义 


protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource)throws BeanDefinitionStoreException {try {Document doc = doLoadDocument(inputSource, resource);//解析xmlreturn registerBeanDefinitions(doc, resource);//注册bean定义}catch (BeanDefinitionStoreException ex) {throw ex;}catch (SAXParseException ex) {throw new XmlBeanDefinitionStoreException(resource.getDescription(),"Line " + ex.getLineNumber() + " in XML document from " + resource + " is invalid", ex);}catch (SAXException ex) {throw new XmlBeanDefinitionStoreException(resource.getDescription(),"XML document from " + resource + " is invalid", ex);}catch (ParserConfigurationException ex) {throw new BeanDefinitionStoreException(resource.getDescription(),"Parser configuration exception parsing XML from " + resource, ex);}catch (IOException ex) {throw new BeanDefinitionStoreException(resource.getDescription(),"IOException parsing XML document from " + resource, ex);}catch (Throwable ex) {throw new BeanDefinitionStoreException(resource.getDescription(),"Unexpected exception parsing XML document from " + resource, ex);}}

doLoadDocument() 调用了org.springframework.beans.factory.xml.DefaultDocumentLoader的loadDocument方法, 把xml文件解析成Document, 来看这个方法的实现, 传入了EntityResolver, spring实现类为ResourceEntityResolver, 解析spring自定义的xsd, DocumentBuilder实现类这里为com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderImpl, jdk的实现,

看下EntityResolver的类图



public Document loadDocument(InputSource inputSource, EntityResolver entityResolver,ErrorHandler errorHandler, int validationMode, boolean namespaceAware) throws Exception {<span style="white-space:pre"></span>//validationMode 参见常量org.springframework.util.xml.XmlValidationModeDetectorDocumentBuilderFactory factory = createDocumentBuilderFactory(validationMode, namespaceAware);if (logger.isDebugEnabled()) {logger.debug("Using JAXP provider [" + factory.getClass().getName() + "]");} //工厂类生成docment生成器,entityResolver读取本地的xsd文件            DocumentBuilder builder = createDocumentBuilder(factory, entityResolver, errorHandler);return builder.parse(inputSource);}

回到上一步的doLoadBeanDefinitions方法,继续看下一步registerBeanDefinitions方法, 主要是Document转换成BeanDefinition

public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException {BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader();//返回了DefaultBeanDefinitionDocumentReaderdocumentReader.setEnvironment(getEnvironment());int countBefore = getRegistry().getBeanDefinitionCount();documentReader.registerBeanDefinitions(doc, createReaderContext(resource));//把doc读取bean定义类return getRegistry().getBeanDefinitionCount() - countBefore;}

spring xml配置解析采用org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader类解析,看它的registerBeanDefinitions方法

public void registerBeanDefinitions(Document doc, XmlReaderContext readerContext) {this.readerContext = readerContext;logger.debug("Loading bean definitions");Element root = doc.getDocumentElement();doRegisterBeanDefinitions(root);}protected void doRegisterBeanDefinitions(Element root) {// Any nested <beans> elements will cause recursion in this method. In// order to propagate and preserve <beans> default-* attributes correctly,// keep track of the current (parent) delegate, which may be null. Create// the new (child) delegate with a reference to the parent for fallback purposes,// then ultimately reset this.delegate back to its original (parent) reference.// this behavior emulates a stack of delegates without actually necessitating one.BeanDefinitionParserDelegate parent = this.delegate;this.delegate = createDelegate(getReaderContext(), root, parent);//代理类BeanDefinitionParserDelegate, 初始默认参数设置,包括自动注入,延迟初始化 ,依赖检查等,可以在xml文件中root节点配置的if (this.delegate.isDefaultNamespace(root)) {//判断是否beansString profileSpec = root.getAttribute(PROFILE_ATTRIBUTE);//读取profileif (StringUtils.hasText(profileSpec)) {String[] specifiedProfiles = StringUtils.tokenizeToStringArray(profileSpec, BeanDefinitionParserDelegate.MULTI_VALUE_ATTRIBUTE_DELIMITERS);if (!getReaderContext().getEnvironment().acceptsProfiles(specifiedProfiles)) {return;}}}preProcessXml(root);parseBeanDefinitions(root, this.delegate);//解析postProcessXml(root);this.delegate = parent;}protected BeanDefinitionParserDelegate createDelegate(XmlReaderContext readerContext, Element root, BeanDefinitionParserDelegate parentDelegate) {BeanDefinitionParserDelegate delegate = new BeanDefinitionParserDelegate(readerContext);delegate.initDefaults(root, parentDelegate);//初始默认参数return delegate;}    protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) {if (delegate.isDefaultNamespace(root)) {<span style="font-family: Arial, Helvetica, sans-serif;">//root是beans的命名空间的</span>NodeList nl = root.getChildNodes();for (int i = 0; i < nl.getLength(); i++) {Node node = nl.item(i);if (node instanceof Element) {Element ele = (Element) node;if (delegate.isDefaultNamespace(ele)) {//节点是beans的命名空间的parseDefaultElement(ele, delegate);}else {delegate.parseCustomElement(ele);//不是beans命名空间节点的,比如context,mvc等扩展的或者自定义的}}}}else {delegate.parseCustomElement(root);}}


命名空间为http://www.springframework.org/schema/beans的xml节点解析,

private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) {if (delegate.nodeNameEquals(ele, IMPORT_ELEMENT)) {importBeanDefinitionResource(ele);}else if (delegate.nodeNameEquals(ele, ALIAS_ELEMENT)) {processAliasRegistration(ele);}else if (delegate.nodeNameEquals(ele, BEAN_ELEMENT)) {processBeanDefinition(ele, delegate);}else if (delegate.nodeNameEquals(ele, NESTED_BEANS_ELEMENT)) {//profile的情况,多层// recursedoRegisterBeanDefinitions(ele);}}

解析自定义xsd, 不是命名空间为http://www.springframework.org/schema/beans的节点的


        public BeanDefinition parseCustomElement(Element ele) {return parseCustomElement(ele, null);}public BeanDefinition parseCustomElement(Element ele, BeanDefinition containingBd) {String namespaceUri = getNamespaceURI(ele);NamespaceHandler handler = this.readerContext.getNamespaceHandlerResolver().resolve(namespaceUri);if (handler == null) {error("Unable to locate Spring NamespaceHandler for XML schema namespace [" + namespaceUri + "]", ele);return null;}return handler.parse(ele, new ParserContext(this.readerContext, this, containingBd));}

getNamespaceHandlerResolver() 返回的是org.springframework.beans.factory.xml.DefaultNamespaceHandlerResolver,我们来看看resolve的实现

public NamespaceHandler resolve(String namespaceUri) {Map<String, Object> handlerMappings = getHandlerMappings();//获取jar包spring.handlers配置的url映射Object handlerOrClassName = handlerMappings.get(namespaceUri);if (handlerOrClassName == null) {return null;}else if (handlerOrClassName instanceof NamespaceHandler) {//如果是实例就直接返回return (NamespaceHandler) handlerOrClassName;}else {String className = (String) handlerOrClassName;try {Class<?> handlerClass = ClassUtils.forName(className, this.classLoader);if (!NamespaceHandler.class.isAssignableFrom(handlerClass)) {throw new FatalBeanException("Class [" + className + "] for namespace [" + namespaceUri +"] does not implement the [" + NamespaceHandler.class.getName() + "] interface");}NamespaceHandler namespaceHandler = (NamespaceHandler) BeanUtils.instantiateClass(handlerClass);namespaceHandler.init();//初始化节点元素对应的解析类handlerMappings.put(namespaceUri, namespaceHandler);//将class名替换成实例return namespaceHandler;}catch (ClassNotFoundException ex) {throw new FatalBeanException("NamespaceHandler class [" + className + "] for namespace [" +namespaceUri + "] not found", ex);}catch (LinkageError err) {throw new FatalBeanException("Invalid NamespaceHandler class [" + className + "] for namespace [" +namespaceUri + "]: problem with handler class file or dependent class", err);}}}

这个方法返回了命名空间处理器,现在回到调用的parseCustomElement方法,继续看下一步handler.parse方法

/** * Parses the supplied {@link Element} by delegating to the {@link BeanDefinitionParser} that is * registered for that {@link Element}. */@Overridepublic BeanDefinition parse(Element element, ParserContext parserContext) {return findParserForElement(element, parserContext).parse(element, parserContext);}

findParserForElement(element, parserContext)方法根据节点元素名返回具体的解析类(namesapceHandler.init()初始化的),关于如何解析,实现类太多,这里就不做介绍,后面再详细解说。

到此beanFactory实例已经创建成功,这时我们看下beanFactory有几个bean定义 ,已经初始化了6个, 注解方式的到现在还没有解析, (我的工程只有一个controller,没有其它类,所以下面都是spring的类, 而controller是通过DispatcherServlet来初始化的)




回到refresh()方法,看下一步prepareBeanFactory(beanFactory);,主要是bean实例化前的准备工作,为后面实例化后aware接口属性注入,表达式解析,点位符替换

/** * Configure the factory's standard context characteristics, * such as the context's ClassLoader and post-processors. * @param beanFactory the BeanFactory to configure */protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {//实现类为DefaultListableBeanFactory// Tell the internal bean factory to use the context's class loader etc.beanFactory.setBeanClassLoader(getClassLoader());beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));//点位符替换// Configure the bean factory with context callbacks. 设置上下文回调处理类,此类处理下面几个接口上下文的注入beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);//把aware相关接口忽略依赖检查和自动注入beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);beanFactory.ignoreDependencyInterface(MessageSourceAware.class);beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);beanFactory.ignoreDependencyInterface(EnvironmentAware.class);//缓存依赖类的实例// BeanFactory interface not registered as resolvable type in a plain factory.// MessageSource registered (and found for autowiring) as a bean.beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);beanFactory.registerResolvableDependency(ResourceLoader.class, this);beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);beanFactory.registerResolvableDependency(ApplicationContext.class, this);// Detect a LoadTimeWeaver and prepare for weaving, if found.if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));// Set a temporary ClassLoader for type matching.beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));}// Register default environment beans.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());}}

下一步org.springframework.web.context.support.AbstractRefreshableWebApplicationContext.postProcessBeanFactory方法,spring注释写得很清晰了,主要注册web servlet相关处理类的实例

protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {beanFactory.addBeanPostProcessor(new ServletContextAwareProcessor(this.servletContext, this.servletConfig));beanFactory.ignoreDependencyInterface(ServletContextAware.class);beanFactory.ignoreDependencyInterface(ServletConfigAware.class);WebApplicationContextUtils.registerWebApplicationScopes(beanFactory, this.servletContext);WebApplicationContextUtils.registerEnvironmentBeans(beanFactory, this.servletContext, this.servletConfig);}/** * Register web-specific scopes ("request", "session", "globalSession", "application") * with the given BeanFactory, as used by the WebApplicationContext. * @param beanFactory the BeanFactory to configure * @param sc the ServletContext that we're running within */public static void registerWebApplicationScopes(ConfigurableListableBeanFactory beanFactory, ServletContext sc) {beanFactory.registerScope(WebApplicationContext.SCOPE_REQUEST, new RequestScope());beanFactory.registerScope(WebApplicationContext.SCOPE_SESSION, new SessionScope(false));beanFactory.registerScope(WebApplicationContext.SCOPE_GLOBAL_SESSION, new SessionScope(true));if (sc != null) {ServletContextScope appScope = new ServletContextScope(sc);beanFactory.registerScope(WebApplicationContext.SCOPE_APPLICATION, appScope);// Register as ServletContext attribute, for ContextCleanupListener to detect it.sc.setAttribute(ServletContextScope.class.getName(), appScope);}//缓存依赖类的实例beanFactory.registerResolvableDependency(ServletRequest.class, new RequestObjectFactory());beanFactory.registerResolvableDependency(ServletResponse.class, new ResponseObjectFactory());beanFactory.registerResolvableDependency(HttpSession.class, new SessionObjectFactory());beanFactory.registerResolvableDependency(WebRequest.class, new WebRequestObjectFactory());if (jsfPresent) {FacesDependencyRegistrar.registerFacesDependencies(beanFactory);}}/** * Register web-specific environment beans ("contextParameters", "contextAttributes") * with the given BeanFactory, as used by the WebApplicationContext. * @param bf the BeanFactory to configure * @param servletContext the ServletContext that we're running within * @param servletConfig the ServletConfig of the containing Portlet */public static void registerEnvironmentBeans(ConfigurableListableBeanFactory bf, ServletContext servletContext, ServletConfig servletConfig) {if (servletContext != null && !bf.containsBean(WebApplicationContext.SERVLET_CONTEXT_BEAN_NAME)) {bf.registerSingleton(WebApplicationContext.SERVLET_CONTEXT_BEAN_NAME, servletContext);}if (servletConfig != null && !bf.containsBean(ConfigurableWebApplicationContext.SERVLET_CONFIG_BEAN_NAME)) {bf.registerSingleton(ConfigurableWebApplicationContext.SERVLET_CONFIG_BEAN_NAME, servletConfig);}if (!bf.containsBean(WebApplicationContext.CONTEXT_PARAMETERS_BEAN_NAME)) {Map<String, String> parameterMap = new HashMap<String, String>();if (servletContext != null) {Enumeration<?> paramNameEnum = servletContext.getInitParameterNames();while (paramNameEnum.hasMoreElements()) {String paramName = (String) paramNameEnum.nextElement();parameterMap.put(paramName, servletContext.getInitParameter(paramName));}}if (servletConfig != null) {Enumeration<?> paramNameEnum = servletConfig.getInitParameterNames();while (paramNameEnum.hasMoreElements()) {String paramName = (String) paramNameEnum.nextElement();parameterMap.put(paramName, servletConfig.getInitParameter(paramName));}}bf.registerSingleton(WebApplicationContext.CONTEXT_PARAMETERS_BEAN_NAME,Collections.unmodifiableMap(parameterMap));}if (!bf.containsBean(WebApplicationContext.CONTEXT_ATTRIBUTES_BEAN_NAME)) {Map<String, Object> attributeMap = new HashMap<String, Object>();if (servletContext != null) {Enumeration<?> attrNameEnum = servletContext.getAttributeNames();while (attrNameEnum.hasMoreElements()) {String attrName = (String) attrNameEnum.nextElement();attributeMap.put(attrName, servletContext.getAttribute(attrName));}}bf.registerSingleton(WebApplicationContext.CONTEXT_ATTRIBUTES_BEAN_NAME,Collections.unmodifiableMap(attributeMap));}}



回到refresh(), 继续下一步invokeBeanFactoryPostProcessors()方法

/** * Instantiate and invoke all registered BeanFactoryPostProcessor beans, * respecting explicit order if given. * <p>Must be called before singleton instantiation. */protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {                //getBeanFactoryPostProcessors()是父类AbstractApplicationContext的,默认为空,主要用于扩展PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());}

PostProcessorRegistrationDelegate注册后处理代理类, 主要初始化两个类ConfigurationClassPostProcessor和PropertyPlaceholderConfigurer

ConfigurationClassPostProcessor 用于处理配置自动扫描注解

PropertyPlaceholderConfigurer 用于替换点位符

下面方法第一步先按照优先级处理注册的BeanDefinitionRegistryPostProcessor子类,包含了ConfigurationClassPostProcessor类, bean定义注册后处理

每二步按优先级处理注册的BeanFactoryPostProcessor的子类,包含了PropertyPlaceholderConfigurer,初始化并加载配置文件

org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory, List<BeanFactoryPostProcessor>)


public static void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {// Invoke BeanDefinitionRegistryPostProcessors first, if any.Set<String> processedBeans = new HashSet<String>();if (beanFactory instanceof BeanDefinitionRegistry) {BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;List<BeanFactoryPostProcessor> regularPostProcessors = new LinkedList<BeanFactoryPostProcessor>();List<BeanDefinitionRegistryPostProcessor> registryPostProcessors =new LinkedList<BeanDefinitionRegistryPostProcessor>();for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {BeanDefinitionRegistryPostProcessor registryPostProcessor =(BeanDefinitionRegistryPostProcessor) postProcessor;registryPostProcessor.postProcessBeanDefinitionRegistry(registry);registryPostProcessors.add(registryPostProcessor);}else {regularPostProcessors.add(postProcessor);}}// Do not initialize FactoryBeans here: We need to leave all regular beans// uninitialized to let the bean factory post-processors apply to them!// Separate between BeanDefinitionRegistryPostProcessors that implement// PriorityOrdered, Ordered, and the rest.返回注册后处理器,包含String[] postProcessorNames =beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);// First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.List<BeanDefinitionRegistryPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanDefinitionRegistryPostProcessor>();for (String ppName : postProcessorNames) {if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {//接口匹配, 这里会返回org.springframework.context.annotation.ConfigurationClassPostProcessor,此类注册当使用了<context:annotation-config/> or <context:component-scan/>priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));//初始化ConfigurationClassPostProcessorprocessedBeans.add(ppName);}}OrderComparator.sort(priorityOrderedPostProcessors);registryPostProcessors.addAll(priorityOrderedPostProcessors);invokeBeanDefinitionRegistryPostProcessors(priorityOrderedPostProcessors, registry);// Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);List<BeanDefinitionRegistryPostProcessor> orderedPostProcessors = new ArrayList<BeanDefinitionRegistryPostProcessor>();for (String ppName : postProcessorNames) {if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {orderedPostProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));processedBeans.add(ppName);}}OrderComparator.sort(orderedPostProcessors);registryPostProcessors.addAll(orderedPostProcessors);invokeBeanDefinitionRegistryPostProcessors(orderedPostProcessors, registry);// Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.boolean reiterate = true;while (reiterate) {reiterate = false;postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);for (String ppName : postProcessorNames) {if (!processedBeans.contains(ppName)) {BeanDefinitionRegistryPostProcessor pp = beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class);registryPostProcessors.add(pp);processedBeans.add(ppName);pp.postProcessBeanDefinitionRegistry(registry);reiterate = true;}}}// Now, invoke the postProcessBeanFactory callback of all processors handled so far.invokeBeanFactoryPostProcessors(registryPostProcessors, beanFactory);invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);}else {// Invoke factory processors registered with the context instance.invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);}// Do not initialize FactoryBeans here: We need to leave all regular beans// uninitialized to let the bean factory post-processors apply to them!String[] postProcessorNames =beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);// Separate between BeanFactoryPostProcessors that implement PriorityOrdered,// Ordered, and the rest.List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();List<String> orderedPostProcessorNames = new ArrayList<String>();List<String> nonOrderedPostProcessorNames = new ArrayList<String>();for (String ppName : postProcessorNames) { //org.springframework.beans.factory.config.PropertyPlaceholderConfigurer,点位符处理器if (processedBeans.contains(ppName)) {// skip - already processed in first phase above}else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));}else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {orderedPostProcessorNames.add(ppName);}else {nonOrderedPostProcessorNames.add(ppName);}}// First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.OrderComparator.sort(priorityOrderedPostProcessors);invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);// Next, invoke the BeanFactoryPostProcessors that implement Ordered.List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();for (String postProcessorName : orderedPostProcessorNames) {orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));}OrderComparator.sort(orderedPostProcessors);invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);// Finally, invoke all other BeanFactoryPostProcessors.List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();for (String postProcessorName : nonOrderedPostProcessorNames) {nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));}invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);}

我们来看下beanFactory.getBean()做了什么

public <T> T getBean(String name, Class<T> requiredType) throws BeansException {return doGetBean(name, requiredType, null, false);}/** * Return an instance, which may be shared or independent, of the specified bean. * @param name the name of the bean to retrieve * @param requiredType the required type of the bean to retrieve * @param args arguments to use when creating a bean instance using explicit arguments * (only applied when creating a new instance as opposed to retrieving an existing one) * @param typeCheckOnly whether the instance is obtained for a type check, * not for actual use * @return an instance of the bean * @throws BeansException if the bean could not be created */@SuppressWarnings("unchecked")protected <T> T doGetBean(final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly)throws BeansException {final String beanName = transformedBeanName(name);Object bean;// Eagerly check singleton cache for manually registered singletons.Object sharedInstance = getSingleton(beanName);if (sharedInstance != null && args == null) {if (logger.isDebugEnabled()) {if (isSingletonCurrentlyInCreation(beanName)) {logger.debug("Returning eagerly cached instance of singleton bean '" + beanName +"' that is not fully initialized yet - a consequence of a circular reference");}else {logger.debug("Returning cached instance of singleton bean '" + beanName + "'");}}bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);}else {// Fail if we're already creating this bean instance:// We're assumably within a circular reference.if (isPrototypeCurrentlyInCreation(beanName)) {throw new BeanCurrentlyInCreationException(beanName);}// Check if bean definition exists in this factory.BeanFactory parentBeanFactory = getParentBeanFactory();if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {// Not found -> check parent.String nameToLookup = originalBeanName(name);if (args != null) {// Delegation to parent with explicit args.return (T) parentBeanFactory.getBean(nameToLookup, args);}else {// No args -> delegate to standard getBean method.return parentBeanFactory.getBean(nameToLookup, requiredType);}}if (!typeCheckOnly) {markBeanAsCreated(beanName);//标记创建}try {final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);checkMergedBeanDefinition(mbd, beanName, args);//检查bean定义,是否抽象// Guarantee initialization of beans that the current bean depends on.String[] dependsOn = mbd.getDependsOn();if (dependsOn != null) {for (String dependsOnBean : dependsOn) {                            //为依赖的bean确定指定的bean的依赖已经注册或它的任何传递依赖关系, 不能出现循环依赖if (isDependent(beanName, dependsOnBean)) {throw new BeanCreationException(mbd.getResourceDescription(), beanName,"Circular depends-on relationship between '" + beanName + "' and '" + dependsOnBean + "'");}registerDependentBean(dependsOnBean, beanName);getBean(dependsOnBean);//先实例依赖的类}}// Create bean instance.if (mbd.isSingleton()) {sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {@Overridepublic Object getObject() throws BeansException {try {return createBean(beanName, mbd, args);//创建bean,处理bean初始化后aware接口值填充是在AbstractAutowireCapableBeanFactory.<span style="font-family: Arial, Helvetica, sans-serif; "><strong>invokeAwareMethods</strong></span><strong style="font-family: Arial, Helvetica, sans-serif;">里实现,InitializingBean接口也在此类invokeInitMethods调用填充,包括BeanPostProcessor接口等全部都在此类被调用,</strong><span style="font-family: Arial, Helvetica, sans-serif;">,里面就不做详细介绍</span>}catch (BeansException ex) {// Explicitly remove instance from singleton cache: It might have been put there// eagerly by the creation process, to allow for circular reference resolution.// Also remove any beans that received a temporary reference to the bean.destroySingleton(beanName);throw ex;}}});bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);}else if (mbd.isPrototype()) {// It's a prototype -> create a new instance.Object prototypeInstance = null;try {beforePrototypeCreation(beanName);prototypeInstance = createBean(beanName, mbd, args);}finally {afterPrototypeCreation(beanName);}bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);}else {String scopeName = mbd.getScope();final Scope scope = this.scopes.get(scopeName);if (scope == null) {throw new IllegalStateException("No Scope registered for scope '" + scopeName + "'");}try {Object scopedInstance = scope.get(beanName, new ObjectFactory<Object>() {@Overridepublic Object getObject() throws BeansException {beforePrototypeCreation(beanName);try {return createBean(beanName, mbd, args);}finally {afterPrototypeCreation(beanName);}}});bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);}catch (IllegalStateException ex) {throw new BeanCreationException(beanName,"Scope '" + scopeName + "' is not active for the current thread; " +"consider defining a scoped proxy for this bean if you intend to refer to it from a singleton",ex);}}}catch (BeansException ex) {cleanupAfterBeanCreationFailure(beanName);throw ex;}}// Check if required type matches the type of the actual bean instance.if (requiredType != null && bean != null && !requiredType.isAssignableFrom(bean.getClass())) {try {return getTypeConverter().convertIfNecessary(bean, requiredType);}catch (TypeMismatchException ex) {if (logger.isDebugEnabled()) {logger.debug("Failed to convert bean '" + name + "' to required type [" +ClassUtils.getQualifiedName(requiredType) + "]", ex);}throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());}}return (T) bean;}




回到refresh(), 接下来看下一个方法registerBeanPostProcessors(beanFactory)

/** * Instantiate and invoke all registered 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);}


public static void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);// Register BeanPostProcessorChecker that logs an info message when// a bean is created during BeanPostProcessor instantiation, i.e. when// a bean is not eligible for getting processed by all BeanPostProcessors.int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));// Separate between BeanPostProcessors that implement PriorityOrdered,// Ordered, and the rest.List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanPostProcessor>();List<BeanPostProcessor> internalPostProcessors = new ArrayList<BeanPostProcessor>();List<String> orderedPostProcessorNames = new ArrayList<String>();List<String> nonOrderedPostProcessorNames = new ArrayList<String>();for (String ppName : postProcessorNames) {if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);priorityOrderedPostProcessors.add(pp);if (pp instanceof MergedBeanDefinitionPostProcessor) {internalPostProcessors.add(pp);}}else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {orderedPostProcessorNames.add(ppName);}else {nonOrderedPostProcessorNames.add(ppName);}}// First, register the BeanPostProcessors that implement PriorityOrdered.OrderComparator.sort(priorityOrderedPostProcessors);registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);// Next, register the BeanPostProcessors that implement Ordered.List<BeanPostProcessor> orderedPostProcessors = new ArrayList<BeanPostProcessor>();for (String ppName : orderedPostProcessorNames) {BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);orderedPostProcessors.add(pp);if (pp instanceof MergedBeanDefinitionPostProcessor) {internalPostProcessors.add(pp);}}OrderComparator.sort(orderedPostProcessors);registerBeanPostProcessors(beanFactory, orderedPostProcessors);// Now, register all regular BeanPostProcessors.List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<BeanPostProcessor>();for (String ppName : nonOrderedPostProcessorNames) {BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);nonOrderedPostProcessors.add(pp);if (pp instanceof MergedBeanDefinitionPostProcessor) {internalPostProcessors.add(pp);}}registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);// Finally, re-register all internal BeanPostProcessors.OrderComparator.sort(internalPostProcessors);registerBeanPostProcessors(beanFactory, internalPostProcessors);beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));}

invokeBeanFactoryPostProcessors调用完后,我们再看下beanFactory里增加了两个bean定义



再回到refresh方法,

// 初始化messageSource, 如果不存在messageSource的bean定义,就使用
initMessageSource();

// 初始化事件广播, 如果不包含applicationEventMulticaster bean定义就使用默认的SimpleApplicationEventMulticaster
initApplicationEventMulticaster();

//用于注册监听到事件广播 ,必须实现org.springframework.context.ApplicationListener接口, 

registerListeners() 

//初始化主题资源,没有就采用默认

onRefresh()


/** * Initialize the theme capability. */@Overrideprotected void onRefresh() {this.themeSource = UiApplicationContextUtils.initThemeSource(this);}


回到refresh方法,看下一步finishBeanFactoryInitialization(beanFactory), 这个方法把所有定义的单例bean全部初始化

/** * 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.if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {beanFactory.setConversionService(beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));}// Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);for (String weaverAwareName : weaverAwareNames) {getBean(weaverAwareName);}// Stop using the temporary ClassLoader for type matching.beanFactory.setTempClassLoader(null);// Allow for caching all bean definition metadata, not expecting further changes.把上面初始化的8个bean冻结beanFactory.freezeConfiguration();// Instantiate all remaining (non-lazy-init) singletons.把beanFactory定义的bean单例的全部初始化beanFactory.preInstantiateSingletons();}

到这为止看下beanFactory的singletonObjects有多少个实例, 总共有15个

org.springframework.context.annotation.internalCommonAnnotationProcessor
contextAttributes
org.springframework.context.annotation.internalRequiredAnnotationProcessor
messageSource
environment
org.springframework.context.annotation.ConfigurationClassPostProcessor.importAwareProcessor
applicationEventMulticaster
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
contextParameters
org.springframework.context.annotation.ConfigurationClassPostProcessor.enhancedConfigurationProcessor
systemProperties
servletContext
systemEnvironment
org.springframework.beans.factory.config.PropertyPlaceholderConfigurer#0


回到refreash方法,最后一个方法finishRefresh(); 初始化生命周期上下文事件

/** * Finish the refresh of this context, invoking the LifecycleProcessor's * onRefresh() method and publishing the * {@link org.springframework.context.event.ContextRefreshedEvent}. */protected void finishRefresh() {// Initialize lifecycle processor for this context.initLifecycleProcessor();// Propagate refresh to lifecycle processor first.getLifecycleProcessor().onRefresh();// Publish the final event.publishEvent(new ContextRefreshedEvent(this));// Participate in LiveBeansView MBean, if active.LiveBeansView.registerApplicationContext(this);}

到此spring refresh全部完毕。





0 0
原创粉丝点击