Spring原始碼-IOC(三)
阿新 • • 發佈:2018-12-26
Spring原始碼-IOC
springmvc專案啟動入口位置是:web.xml中配置的listener。
在web.xml配置這個監聽器,啟動容器時,就會預設執行它實現的方法。在ContextLoaderListener中關聯了ContextLoader這個類,所以整個載入配置過程由ContextLoader來完成。
//初始化web應用上下文方法:ContextLoader中的initWebApplicationContext方法
public WebApplicationContext initWebApplicationContext(ServletContext servletContext) {
//判斷web用用根上下文是否已經存在:如果存在則丟擲異常,這麼做是為了防止重複載入
if (servletContext.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE) != null) {
throw new IllegalStateException(
"Cannot initialize context because there is already a root application context present - " +
"check whether you have multiple ContextLoader* definitions in your web.xml!" );
}
Log logger = LogFactory.getLog(ContextLoader.class);
servletContext.log("Initializing Spring root WebApplicationContext");
if (logger.isInfoEnabled()) {
logger.info("Root WebApplicationContext: initialization started");
}
long startTime = System.currentTimeMillis();
try {
// Store context in local instance variable, to guarantee that
// it is available on ServletContext shutdown.
//在例項屬性變數裡儲存上下文資訊,為了保證在Servlet上下文關閉的時候可以使用
if (this.context == null) {
//建立上下文資訊:返回的是:在開發人員沒有配置的情況下返回Context.properties中配置的預設XmlWebApplicationContext物件的例項
this.context = createWebApplicationContext(servletContext);
}
//判斷獲取到上下文是否為ConfigurableWebApplicationContext的例項(子類的例項:XmlWebApplicationContext)
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);
}
//重點:配置及重新整理web應用上下文資訊
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) {
//將類載入器、應用上下文放到ConcurrentHashMap容器中
currentContextPerThread.put(ccl, this.context);
}
if (logger.isDebugEnabled()) {
logger.debug("Published root WebApplicationContext as ServletContext attribute with name [" +
WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE + "]");
}
if (logger.isInfoEnabled()) {
long elapsedTime = System.currentTimeMillis() - startTime;
logger.info("Root WebApplicationContext: initialization completed in " + elapsedTime + " ms");
}
return this.context;
}
catch (RuntimeException ex) {
logger.error("Context initialization failed", ex);
servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, ex);
throw ex;
}
catch (Error err) {
logger.error("Context initialization failed", err);
servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, err);
throw err;
}
}
//建立應用上下文
protected WebApplicationContext createWebApplicationContext(ServletContext sc) {
Class<?> contextClass = determineContextClass(sc);
if (!ConfigurableWebApplicationContext.class.isAssignableFrom(contextClass)) {
throw new ApplicationContextException("Custom context class [" + contextClass.getName() +
"] is not of type [" + ConfigurableWebApplicationContext.class.getName() + "]");
}
return (ConfigurableWebApplicationContext) BeanUtils.instantiateClass(contextClass);
}
//根據配置獲取上下文資訊Class
protected Class<?> determineContextClass(ServletContext servletContext) {
//判斷是否配置了intitClass
String contextClassName = servletContext.getInitParameter(CONTEXT_CLASS_PARAM);
if (contextClassName != null) {
try {
return ClassUtils.forName(contextClassName, ClassUtils.getDefaultClassLoader());
}
catch (ClassNotFoundException ex) {
throw new ApplicationContextException(
"Failed to load custom context class [" + contextClassName + "]", ex);
}
}
else {
//預設的:/org/springframework/web/context/ContextLoader.properties中配置的類
contextClassName = defaultStrategies.getProperty(WebApplicationContext.class.getName());
try {
return ClassUtils.forName(contextClassName, ContextLoader.class.getClassLoader());
}
catch (ClassNotFoundException ex) {
throw new ApplicationContextException(
"Failed to load default context class [" + contextClassName + "]", ex);
}
}
}
//配置及重新整理web應用上下文資訊
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);
//重點:bean註冊入口
wac.refresh();
}
//呼叫AbstractApplicationContext類的refresh()方法,XmlWebApplicationContext是它的子類
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// 載入環境配置資訊:配置檔案總的佔位符等資訊初始化
prepareRefresh();
// 獲取beanFactory:返回DefaultListableBeanFactory物件
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// 為bean工廠新增:處理器,註冊器,資源資訊註冊等
prepareBeanFactory(beanFactory);
try {
//允許在上下文子類中對bean工廠進行處理:呼叫XmlWebApplicationContext父類的AbstractRefreshableApplicationContext
//postProcessBeanFactory方法,因為方法被AbstractApplicationContext的子類AbstractRefreshableApplicationContext重寫
//為bean工廠繼續新增bean處理器,併為bean工廠註冊beans生命週期及環境資訊
postProcessBeanFactory(beanFactory);
//開始執行註冊到該上下文的BeanFactoryPostProcessors
invokeBeanFactoryPostProcessors(beanFactory);
// 開始註冊BeanPostProcessor來攔截其他的bean的初始化過程
registerBeanPostProcessors(beanFactory);
// 初始化訊息源
initMessageSource();
//註冊上下文事件的廣播集
initApplicationEventMulticaster();
//初始化一些特殊的bean
onRefresh();
//查詢並校驗監聽器並註冊
registerListeners();
// 解析並建立Class物件所有非懶載入的所有bean
finishBeanFactoryInitialization(beanFactory);
//最後一步釋出所有的運用
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();
}
}
}
//獲取beanFactory方法
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
//重新整理beanFactory:銷燬已經存在的bean資訊,關閉已經存在的工廠
//同時開始解析並建立Class物件bean並註冊到應用上下文中
refreshBeanFactory();//重點的重點
//建立新的工廠:DefaultListableBeanFactory
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
if (logger.isDebugEnabled()) {
logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory);
}
return beanFactory;
}
//呼叫XmlWebApplicationContext父類AbstractRefreshableApplicationContext的refreshBeanFactory方法
@Override
protected final void refreshBeanFactory() throws BeansException {
//銷燬已經存在的bean資訊,關閉已經存在的工廠
if (hasBeanFactory()) {
destroyBeans();
closeBeanFactory();
}
try {
DefaultListableBeanFactory beanFactory = createBeanFactory();
beanFactory.setSerializationId(getId());
//定製bean工廠:允許bean定義過載,允許迴圈引用
customizeBeanFactory(beanFactory);
//載入定義的bean資訊:呼叫子類XmlWebApplicationContext中的實現loadBeanDefinitions
loadBeanDefinitions(beanFactory);
synchronized (this.beanFactoryMonitor) {
this.beanFactory = beanFactory;
}
}
catch (IOException ex) {
throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
}
}
//XmlWebApplicationContext:開始解析並建立Class物件bean並註冊到應用上下文中
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
//通過beanFactory建立XmlBeanDefinitionReader讀取器
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));
// Allow a subclass to provide custom initialization of the reader,
// then proceed with actually loading the bean definitions.
//初始化bean定義讀取器:空實現
initBeanDefinitionReader(beanDefinitionReader);
//
loadBeanDefinitions(beanDefinitionReader);
}
//XmlWebApplicationContext:loadBeanDefinitions(reader)
protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws IOException {
String[] configLocations = getConfigLocations();
if (configLocations != null) {
for (String configLocation : configLocations) {
//XmlBeanDefinitionReader的AbstractBeanDefinitionReader父類的loadBeanDefinitions
reader.loadBeanDefinitions(configLocation);
}
}
}
//AbstractBeanDefinitionReader父類的loadBeanDefinitions
public int loadBeanDefinitions(String location) throws BeanDefinitionStoreException {
return loadBeanDefinitions(location, null);
}
//AbstractBeanDefinitionReader父類的過載方法loadBeanDefinitions:載入配置檔案資訊
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 {
//多個配置檔案載入
Resource[] resources = ((ResourcePatternResolver) resourceLoader).getResources(location);
//呼叫AbstractBeanDefinitionReader的loadBeanDefinitions(resources);
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);
//呼叫XmlBeanDefinitionReader實現BeanDefinitionReader(AbstractBeanDefinitionReader實現了該介面)介面中的loadBeanDefinitions
int loadCount = loadBeanDefinitions(resource);
if (actualResources != null) {
actualResources.add(resource);
}
if (logger.isDebugEnabled()) {
logger.debug("Loaded " + loadCount + " bean definitions from location [" + location + "]");
}
return loadCount;
}
}
//呼叫AbstractBeanDefinitionReader的loadBeanDefinitions(resources);
public int loadBeanDefinitions(Resource... resources) throws BeanDefinitionStoreException {
Assert.notNull(resources, "Resource array must not be null");
int counter = 0;
for (Resource resource : resources) {
//迴圈//呼叫XmlBeanDefinitionReader實現BeanDefinitionReader(AbstractBeanDefinitionReader實現了該介面)介面中的loadBeanDefinitions
counter += loadBeanDefinitions(resource);
}
return counter;
}
//XmlBeanDefinitionReader的loadBeanDefinitions(resource);
public int loadBeanDefinitions(Resource resource) throws BeanDefinitionStoreException {
return loadBeanDefinitions(new EncodedResource(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());
}
//開始載入bean定義資訊
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();
}
}
}
//載入bean定義資訊
protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource)
throws BeanDefinitionStoreException {
try {
//獲取配置檔案的文件物件
Document doc = doLoadDocument(inputSource, resource);
//註冊bean定義資訊:重點
return registerBeanDefinitions(doc, resource);
}
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);
}
}
//註冊bean定義資訊:重點
public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException {
BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader();
int countBefore = getRegistry().getBeanDefinitionCount();
//通過文件讀取器開始讀取並註冊bean資訊
documentReader.registerBeanDefinitions(doc, createReaderContext(resource));
return getRegistry().getBeanDefinitionCount() - countBefore;
}
//BeanDefinitionDocumentReader的子類DefaultBeanDefinitionDocumentReader的registerBeanDefinitions方法
public void registerBeanDefinitions(Document doc, XmlReaderContext readerContext) {
this.readerContext = readerContext;
logger.debug("Loading bean definitions");
//獲取根元素資訊
Element root = doc.getDocumentElement();
//註冊bean定義資訊
doRegisterBeanDefinitions(root);
}
//DefaultBeanDefinitionDocumentReader的doRegisterBeanDefinitions方法
protected void doRegisterBeanDefinitions(Element root) {
//獲取父級bean定義解析代理
BeanDefinitionParserDelegate parent = this.delegate;
this.delegate = createDelegate(getReaderContext(), root, parent);
if (this.delegate.isDefaultNamespace(root)) {
String profileSpec = root.getAttribute(PROFILE_ATTRIBUTE);
if (StringUtils.hasText(profileSpec)) {
String[] specifiedProfiles = StringUtils.tokenizeToStringArray(
profileSpec, BeanDefinitionParserDelegate.MULTI_VALUE_ATTRIBUTE_DELIMITERS);
if (!getReaderContext().getEnvironment().acceptsProfiles(specifiedProfiles)) {
if (logger.isInfoEnabled()) {
logger.info("Skipped XML bean definition file due to specified profiles [" + profileSpec +
"] not matching: " + getReaderContext().getResource());
}
return;
}
}
}
//xml預處理:空實現
preProcessXml(root);
//解析bean定義資訊
parseBeanDefinitions(root, this.delegate);
postProcessXml(root);
this.delegate = parent;
}
/**
* 開始解析bean定義資訊:DefaultBeanDefinitionDocumentReader的方法
* Parse the elements at the root level in the document:
* "import", "alias", "bean".
* @param root the DOM root element of the document
*/
protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) {
//判斷是否是beans空間
if (delegate.isDefaultNamespace(root)) {
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下的import,alias,bean,beans元素
parseDefaultElement(ele, delegate);
}
else {
//其他名稱空間下的子標籤解析:context:component-scan等
delegate.parseCustomElement(ele);
}
}
}
}
else {
//其他名稱空間下的子標籤解析:context:component-scan等
delegate.parseCustomElement(root);
}
}
//===============================================================非註解bean解析過程開始=========================================================
//xml配置類資訊解析:開始解析bean定義資訊:DefaultBeanDefinitionDocumentReader的parseDefaultElement方法
private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) {
if (delegate.nodeNameEquals(ele, IMPORT_ELEMENT)) {
//解析import標籤
importBeanDefinitionResource(ele);
}
else if (delegate.nodeNameEquals(ele, ALIAS_ELEMENT)) {
//解析import標籤
processAliasRegistration(ele);
}
else if (delegate.nodeNameEquals(ele, BEAN_ELEMENT)) {
//解析bean標籤
processBeanDefinition(ele, delegate);
}
else if (delegate.nodeNameEquals(ele, NESTED_BEANS_ELEMENT)) {
//解析巢狀的beans標籤
doRegisterBeanDefinitions(ele);
}
}
//非註解:解析bean標籤
protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
//獲取bean定義資訊
BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
if (bdHolder != null) {
//裝飾bean定義資訊
bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
try {
// 註冊bean
BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());
}
catch (BeanDefinitionStoreException ex) {
getReaderContext().error("Failed to register bean definition with name '" +
bdHolder.getBeanName() + "'", ele, ex);
}
// Send registration event.
getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
}
}
//bean定義解析:BeanDefinitionParserDelegate的parseBeanDefinitionElement方法
public BeanDefinitionHolder parseBeanDefinitionElement(Element ele, BeanDefinition containingBean) {
//獲取bean id 屬性
String id = ele.getAttribute(ID_ATTRIBUTE);
//獲取bean name 屬性
String nameAttr = ele.getAttribute(NAME_ATTRIBUTE);
List<String> aliases = new ArrayList<String>();
if (StringUtils.hasLength(nameAttr)) {
String[] nameArr = StringUtils.tokenizeToStringArray(nameAttr, MULTI_VALUE_ATTRIBUTE_DELIMITERS);
aliases.addAll(Arrays.asList(nameArr));
}
String beanName = id;
//如果bean id和name屬性均為空,則列印日誌
if (!StringUtils.hasText(beanName) && !aliases.isEmpty()) {
beanName = aliases.remove(0);
if (logger.isDebugEnabled()) {
logger.debug("No XML 'id' specified - using '" + beanName +
"' as bean name and " + aliases + " as aliases");
}
}
//校驗bean id是否唯一,如果不存在則放入usedNames的set集合,否則報錯
if (containingBean == null) {
checkNameUniqueness(beanName, aliases, ele);
}
//解析bean的其他屬性
AbstractBeanDefinition beanDefinition = parseBeanDefinitionElement(ele, beanName, containingBean);
if (beanDefinition != null) {
if (!StringUtils.hasText(beanName)) {
try {
if (containingBean != null) {
beanName = BeanDefinitionReaderUtils.generateBeanName(
beanDefinition, this.readerContext.getRegistry(), true);
}
else {
beanName = this.readerContext.generateBeanName(beanDefinition);
// Register an alias for the plain bean class name, if still possible,
// if the generator returned the class name plus a suffix.
// This is expected for Spring 1.2/2.0 backwards compatibility.
String beanClassName = beanDefinition.getBeanClassName();
if (beanClassName != null &&
beanName.startsWith(beanClassName) && beanName.length() > beanClassName.length() &&
!this.readerContext.getRegistry().isBeanNameInUse(beanClassName)) {
aliases.add(beanClassName);
}
}
if (logger.isDebugEnabled()) {
logger.debug("Neither XML 'id' nor 'name' specified - " +
"using generated bean name [" + beanName + "]");
}
}
catch (Exception ex) {
error(ex.getMessage(), ele);
return null;
}
}
String[] aliasesArray = StringUtils.toStringArray(aliases);
return new BeanDefinitionHolder(beanDefinition, beanName, aliasesArray);
}
return null;
}
//非註解bean解析:解析其他屬性
public AbstractBeanDefinition parseBeanDefinitionElement(
Element ele, String beanName, BeanDefinition containingBean) {
//將包含beanName屬性的物件放到解析狀態的棧中:Stack
this.parseState.push(new BeanEntry(beanName));
String className = null;
//判斷當前bean是否包含class屬性
if (ele.hasAttribute(CLASS_ATTRIBUTE)) {
className = ele.getAttribute(CLASS_ATTRIBUTE).trim();
}
try {
String parent = null;
//判斷當前bean是否包含parent屬性
if (ele.hasAttribute(PARENT_ATTRIBUTE)) {
parent = ele.getAttribute(PARENT_ATTRIBUTE);
}
AbstractBeanDefinition bd = createBeanDefinition(className, parent);
//解析bean定義的其他屬性:singleton,scope,abstract,autowire等
parseBeanDefinitionAttributes(ele, beanName, containingBean, bd);
//解析bean的description屬性
bd.setDescription(DomUtils.getChildElementValueByTagName(ele, DESCRIPTION_ELEMENT));
//解析bean的meta元素
parseMetaElements(ele, bd);
//解析bean的lookup-method屬性:方法返回動態載入:特殊的注入方式,很少用到
parseLookupOverrideSubElements(ele, bd.getMethodOverrides());
//解析bean的replaced-method屬性:可以在執行時用新的方法替換舊的方法,很少用到
parseReplacedMethodSubElements(ele, bd.getMethodOverrides());
//解析bean的constructor-arg子元素
parseConstructorArgElements(ele, bd);
//解析property子元素
parsePropertyElements(ele, bd);
//解析qualifier子元素
parseQualifierElements(ele, bd);
bd.setResource(this.readerContext.getResource());
bd.setSource(extractSource(ele));
return bd;
}
catch (ClassNotFoundException ex) {
error("Bean class [" + className + "] not found", ele, ex);
}
catch (NoClassDefFoundError err) {
error("Class that bean class [" + className + "] depends on not found", ele, err);
}
catch (Throwable ex) {
error("Unexpected failure during bean definition parsing", ele, ex);
}
finally {
this.parseState.pop();
}
return null;
}
/**
* 根據bean的className和parentName建立一個封裝了bean class和parent的BeanDefinition物件
* Create a bean definition for the given class name and parent name.
* @param className the name of the bean class
* @param parentName the name of the bean's parent bean
* @return the newly created bean definition
* @throws ClassNotFoundException if bean class resolution was attempted but failed
*/
protected AbstractBeanDefinition createBeanDefinition(String className, String parentName)
throws ClassNotFoundException {
return BeanDefinitionReaderUtils.createBeanDefinition(
parentName, className, this.readerContext.getBeanClassLoader());
}
//
public static AbstractBeanDefinition createBeanDefinition(
String parentName, String className, ClassLoader classLoader) throws ClassNotFoundException {
GenericBeanDefinition bd = new GenericBeanDefinition();
bd.setParentName(parentName);
if (className != null) {
//累載入器不為空:使用者自定義類載入器不為空
if (classLoader != null) {
//spring的反射工具獲取className對應類的的Class物件
bd.setBeanClass(ClassUtils.forName(className, classLoader));
}
else {
//類載入器為空,說明是(bootstrap:對開發人員遮蔽)根載入器,底層有處理,String物件
bd.setBeanClassName(className);
}
}
return bd;
}
//===============================================================非註解bean解析過程完畢=========================================================
//===============================================================非註解bean註冊過程開始=========================================================
//BeanDefinitionReaderUtils的靜態方法registerBeanDefinition
public static void registerBeanDefinition(
BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)
throws BeanDefinitionStoreException {
// Register bean definition under primary name.
String beanName = definitionHolder.getBeanName();
registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());
// Register aliases for bean name, if any.
String[] aliases = definitionHolder.getAliases();
if (aliases != null) {
for (String alias : aliases) {
registry.registerAlias(beanName, alias);
}
}
}
//---------------------------------------------------------------------
// Implementation of BeanDefinitionRegistry interface
//----------------------------------BeanDefinitionRegistry的子類DefaultListableBeanFactory -----------------------------------
///** Map of bean definition objects, keyed by bean name */
//private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<String, BeanDefinition>(256);
@Override
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
throws BeanDefinitionStoreException {
Assert.hasText(beanName, "Bean name must not be empty");
Assert.notNull(beanDefinition, "BeanDefinition must not be null");
if (beanDefinition instanceof AbstractBeanDefinition) {
try {
((AbstractBeanDefinition) beanDefinition).validate();
}
catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
"Validation of bean definition failed", ex);
}
}
BeanDefinition oldBeanDefinition;
//根據當前beanName檢視是否已經註冊
oldBeanDefinition = this.beanDefinitionMap.get(beanName);
if (oldBeanDefinition != null) {
//如果bean不允許過載
if (!isAllowBeanDefinitionOverriding()) {
throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
"Cannot register bean definition [" + beanDefinition + "] for bean '" + beanName +
"': There is already [" + oldBeanDefinition + "] bound.");
}
else if (oldBeanDefinition.getRole() < beanDefinition.getRole()) {
// e.g. was ROLE_APPLICATION, now overriding with ROLE_SUPPORT or ROLE_INFRASTRUCTURE
if (this.logger.isWarnEnabled()) {
this.logger.warn("Overriding user-defined bean definition for bean '" + beanName +
"' with a framework-generated bean definition: replacing [" +
oldBeanDefinition + "] with [" + beanDefinition + "]");
}
}
else if (!beanDefinition.equals(oldBeanDefinition)) {
if (this.logger.isInfoEnabled()) {
this.logger.info("Overriding bean definition for bean '" + beanName +
"' with a different definition: replacing [" + oldBeanDefinition +
"] with [" + beanDefinition + "]");
}
}
else {
if (this.logger.isDebugEnabled()) {
this.logger.debug("Overriding bean definition for bean '" + beanName +
"' with an equivalent definition: replacing [" + oldBeanDefinition +
"] with [" + beanDefinition + "]");
}
}
//如果沒有異常,則用覆蓋老的beanDefainition(concurrentHashMap的key相同則覆蓋)
this.beanDefinitionMap.put(beanName, beanDefinition);
}
else {
//還沒有註冊,新增到快取集合中
//已經開始建立
if (hasBeanCreationStarted()) {
// Cannot modify startup-time collection elements anymore (for stable iteration)
//給bean定義物件儲存結合新增上鎖,防止多執行緒操作
synchronized (this.beanDefinitionMap) {
//將bean定義資訊存到物件的concurrentHashMap集合中
this.beanDefinitionMap.put(beanName, beanDefinition);
//Copy on Write 設計模式,既讀寫分離思想,先建立一個新的集合,然後把原來的集合放到新的裡,老的集合不影響讀取操作,然後再將老的集合的引用指向新的引用
List<String> updatedDefinitions = new ArrayList<String>(this.beanDefinitionNames.size() + 1);
updatedDefinitions.addAll(this.beanDefinitionNames);
updatedDefinitions.add(beanName);
this.beanDefinitionNames = updatedDefinitions;
if (this.manualSingletonNames.contains(beanName)) {
//同樣的設計思想:在java的concurrent併發包下有對應的集合設計
Set<String> updatedSingletons = new LinkedHashSet<String>(this.manualSingletonNames);
updatedSingletons.remove(beanName);
this.manualSingletonNames = updatedSingletons;
}
}
}
else {
// Still in startup registration phase
//仍舊在啟動註冊階段
this.beanDefinitionMap.put(beanName, beanDefinition);
this.beanDefinitionNames.add(beanName);
this.manualSingletonNames.remove(beanName);
}
this.frozenBeanDefinitionNames = null;
}
if (oldBeanDefinition != null || containsSingleton(beanName)) {
//如果已經存在,銷燬當前bean相關的資訊
resetBeanDefinition(beanName);
}
}
//===============================================================非註解bean註冊過程結束=========================================================
//================================================================註解類bean的解析並建立Class物件過程開始====================================================
//BeanDefinitionParserDelegate的parseCustomElement方法
public BeanDefinition parseCustomElement(Element ele) {
return parseCustomElement(ele, null);
}
//BeanDefinitionParserDelegate的過載方法parseCustomElement
public BeanDefinition parseCustomElement(Element ele, BeanDefinition containingBd) {
//根據名稱空間回去對應名稱空間的處理器:例如context名稱空間的處理器為ContextNamespaceHandler
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;
}
//呼叫名稱空間的處理器方法進行解析,返回bean定義資訊
return handler.parse(ele, new ParserContext(this.readerContext, this, containingBd));
}
//ContextNamespaceHandler的父類NamespaceHandlerSupport的parse方法
public class ContextNamespaceHandler extends NamespaceHandlerSupport {
@Override
public void init() {
//註冊各種bean定義解析器
registerBeanDefinitionParser("property-placeholder", new PropertyPlaceholderBeanDefinitionParser());
registerBeanDefinitionParser("property-override", new PropertyOverrideBeanDefinitionParser());
registerBeanDefinitionParser("annotation-config", new AnnotationConfigBeanDefinitionParser());
registerBeanDefinitionParser("component-scan", new ComponentScanBeanDefinitionParser());
registerBeanDefinitionParser("load-time-weaver",