这里只讲一下主线。初始化容器。整理了一小天,比较乱。先对付看。求鼓励:
IOC容器,初始化
ApplicationContext ctx = newFileSystemXmlApplicationContext(“classpath:bean.xml”);
首先去加载 xml文件中写义的类,但是如何加载的呢?
跟踪进入FileSystemXmlApplicationContext.java类中的
public FileSystemXmlApplicationContext(StringconfigLocation) throwsBeansException {
this(new String[]{configLocation}, true, null);
}
继续跟踪
public FileSystemXmlApplicationContext(String[]configLocations, boolean refresh, ApplicationContext parent)
throws BeansException {
super(parent);
setConfigLocations(configLocations);
if (refresh) {
refresh();//此外为关键,ioc其实在此方法中完成。
}
}
继续跟踪AbstractApplicationContext.java类中的方法
publicvoidrefresh() throws BeansException,IllegalStateException {
synchronized (this.startupShutdownMonitor){
// Prepare this context for refreshing.
prepareRefresh();
// Tell the subclass to refresh the internal beanfactory.
//子类中启动refreshBeanFactory()的地方
ConfigurableListableBeanFactorybeanFactory = obtainFreshBeanFactory();
// Prepare the bean factory for use in this context.
prepareBeanFactory(beanFactory);
try {
// Allows post-processing of the bean factory in contextsubclasses.
postProcessBeanFactory(beanFactory);
// Invoke factory processors registered as beans in thecontext.
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 contextsubclasses.
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) {
// Destroy already created singletons to avoid danglingresources.
destroyBeans();
// Reset ‘active’ flag.
cancelRefresh(ex);
// Propagate exception to caller.
throw ex;
}
}
}
继续跟踪AbstractRefreshableApplicationContext.java类中的
protectedfinalvoidrefreshBeanFactory()throwsBeansException {
if (hasBeanFactory()) {
destroyBeans();
closeBeanFactory();
}
try {
//创建IOC容器,使用的是DefaultListableBeanFactory
DefaultListableBeanFactorybeanFactory = createBeanFactory();
beanFactory.setSerializationId(getId());
customizeBeanFactory(beanFactory);
//启动对BeanDefinition的载入
loadBeanDefinitions(beanFactory);
synchronized (this.beanFactoryMonitor){
this.beanFactory = beanFactory;
}
}
catch (IOException ex) {
thrownew ApplicationContextException(“I/O error parsing bean definition source for “ + getDisplayName(), ex);
}
}
继续跟踪AbstractXmlApplicationContext.java类中的
此方法的作用是读xml文件中的类,并进行载入
protectedvoidloadBeanDefinitions(DefaultListableBeanFactorybeanFactory) throwsBeansException, IOException {
// Create a new XmlBeanDefinitionReader for the givenBeanFactory.
XmlBeanDefinitionReaderbeanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
// Configure the bean definition reader with thiscontext’s
// resource loading environment.
beanDefinitionReader.setResourceLoader(this);
beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));
// Allow a subclass to provide custom initialization ofthe reader,
// then proceed with actually loading the beandefinitions.
//启动bean定义信息载入的过程
initBeanDefinitionReader(beanDefinitionReader);
loadBeanDefinitions(beanDefinitionReader);
}
protectedvoidloadBeanDefinitions(XmlBeanDefinitionReaderreader) throwsBeansException, IOException {
Resource[]configResources = getConfigResources();
if (configResources != null) {
reader.loadBeanDefinitions(configResources);
}
String[]configLocations = getConfigLocations();
if (configLocations != null) {
reader.loadBeanDefinitions(configLocations);
}
}
XmlBeanDefinitionReader.java类中的
publicintloadBeanDefinitions(EncodedResource encodedResource) throwsBeanDefinitionStoreException {
Assert.notNull(encodedResource,“EncodedResource must not benull”);
if (logger.isInfoEnabled()) {
logger.info(“Loading XML bean definitions from “ + encodedResource.getResource());
}
Set<EncodedResource>currentResources = this.resourcesCurrentlyBeingLoaded.get();
if (currentResources == null) {
currentResources= newHashSet<EncodedResource>(4);
this.resourcesCurrentlyBeingLoaded.set(currentResources);
}
if(!currentResources.add(encodedResource)) {
thrownewBeanDefinitionStoreException(
“Detected cyclic loading of “ + encodedResource + ” – check yourimport definitions!”);
}
//这里得到xml文件、并得到IO的InputSource准备进行读取
try {
InputStreaminputStream = encodedResource.getResource().getInputStream();
try {
InputSourceinputSource = newInputSource(inputStream);
if(encodedResource.getEncoding() != null) {
inputSource.setEncoding(encodedResource.getEncoding());
}
return doLoadBeanDefinitions(inputSource,encodedResource.getResource());
}
finally {
inputStream.close();
}
}
catch (IOException ex) {
thrownewBeanDefinitionStoreException(
“IOException parsing XML document from “ + encodedResource.getResource(), ex);
}
finally {
currentResources.remove(encodedResource);
if(currentResources.isEmpty()) {
this.resourcesCurrentlyBeingLoaded.remove();
}
}
}
//取得xml文件,实际载入BeanDefinitions的地方
protectedintdoLoadBeanDefinitions(InputSource inputSource, Resource resource)
throwsBeanDefinitionStoreException {
try {
int validationMode =getValidationModeForResource(resource);
Document doc = this.documentLoader.loadDocument(
inputSource,getEntityResolver(), this.errorHandler,validationMode, isNamespaceAware());
//对BeanDefinition的解析过程。
return registerBeanDefinitions(doc,resource);
}
catch(BeanDefinitionStoreException ex) {
throw ex;
}
catch (SAXParseException ex){
thrownewXmlBeanDefinitionStoreException(resource.getDescription(),
“Line “+ ex.getLineNumber() + ” in XML documentfrom “ + resource + ” is invalid”, ex);
}
catch (SAXException ex) {
thrownewXmlBeanDefinitionStoreException(resource.getDescription(),
“XML document from “+ resource + ” is invalid”, ex);
}
catch(ParserConfigurationException ex) {
thrownewBeanDefinitionStoreException(resource.getDescription(),
“Parser configuration exception parsing XML from” + resource, ex);
}
catch (IOException ex) {
thrownewBeanDefinitionStoreException(resource.getDescription(),
“IOException parsing XML document from “ + resource, ex);
}
catch (Throwable ex) {
thrownewBeanDefinitionStoreException(resource.getDescription(),
“Unexpected exception parsing XML document from” + resource, ex);
}
}
publicintregisterBeanDefinitions(Documentdoc, Resource resource) throws BeanDefinitionStoreException {
// Read document based on newBeanDefinitionDocumentReader SPI.
//这里得到 BeanDefinitionDocumentReader来对XML的BeanDefinition进行解析
BeanDefinitionDocumentReaderdocumentReader = createBeanDefinitionDocumentReader();
int countBefore =getRegistry().getBeanDefinitionCount();
//具体的解析过程在registerBeanDefinitions中完成
documentReader.registerBeanDefinitions(doc,createReaderContext(resource));
return getRegistry().getBeanDefinitionCount()- countBefore;
}
继续跟踪DefaultBeanDefinitionDocumentReader.java类中的
publicvoidregisterBeanDefinitions(Documentdoc, XmlReaderContext readerContext) {
this.readerContext = readerContext;
logger.debug(“Loading bean definitions”);
Elementroot = doc.getDocumentElement();
BeanDefinitionParserDelegatedelegate = createHelper(readerContext, root);
preProcessXml(root);
//交给BeanDefinitionParserDelegate来处理
parseBeanDefinitions(root,delegate);
postProcessXml(root);
}
protectedvoidparseBeanDefinitions(Elementroot, BeanDefinitionParserDelegate delegate) {
if(delegate.isDefaultNamespace(root)) {
NodeListnl = root.getChildNodes();
for (int i = 0; i <nl.getLength(); i++) {
Nodenode = nl.item(i);
if (node instanceof Element) {
Elementele = (Element) node;
if(delegate.isDefaultNamespace(ele)) {
//跟踪
parseDefaultElement(ele, delegate);
}
else {
delegate.parseCustomElement(ele);
}
}
}
}
else {
delegate.parseCustomElement(root);
}
}
privatevoidparseDefaultElement(Elementele, BeanDefinitionParserDelegate delegate) {
if(delegate.nodeNameEquals(ele, IMPORT_ELEMENT)) {
importBeanDefinitionResource(ele);
}
elseif(delegate.nodeNameEquals(ele, ALIAS_ELEMENT)) {
processAliasRegistration(ele);
}
elseif(delegate.nodeNameEquals(ele, BEAN_ELEMENT)) {
//跟踪
processBeanDefinition(ele,delegate);
}
}
//处理BeanDefinition的地方
protectedvoidprocessBeanDefinition(Elementele, BeanDefinitionParserDelegate delegate) {
BeanDefinitionHolderbdHolder = delegate.parseBeanDefinitionElement(ele);
if (bdHolder != null) {
bdHolder= delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
try {
// Register the final decorated instance.这里向ioc容器注册解析得到的BeanDefinition
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(newBeanComponentDefinition(bdHolder));
}
}
BeanDefinitionReaderUtils.java类
publicstaticvoidregisterBeanDefinition(
BeanDefinitionHolderdefinitionHolder, BeanDefinitionRegistry registry)
throws BeanDefinitionStoreException{
// Register bean definition under primary name.
StringbeanName = definitionHolder.getBeanName();
//进行注册
registry.registerBeanDefinition(beanName,definitionHolder.getBeanDefinition());
// Register aliases for bean name, if any.
String[] aliases =definitionHolder.getAliases();
if (aliases != null) {
for (String aliase :aliases) {
registry.registerAlias(beanName,aliase);
}
}
}
DefaultListableBeanFactory.java类中
publicvoidregisterBeanDefinition(String beanName, BeanDefinition beanDefinition)
throwsBeanDefinitionStoreException {
Assert.hasText(beanName,“Bean name must not be empty”);
Assert.notNull(beanDefinition,“BeanDefinition must not be null”);
if (beanDefinition instanceofAbstractBeanDefinition) {
try {
((AbstractBeanDefinition)beanDefinition).validate();
}
catch(BeanDefinitionValidationException ex) {
thrownewBeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
“Validation of bean definition failed”, ex);
}
}
synchronized (this.beanDefinitionMap){
ObjectoldBeanDefinition =this.beanDefinitionMap.get(beanName);
if (oldBeanDefinition != null) {
if (!this.allowBeanDefinitionOverriding){
thrownewBeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
“Cannot register bean definition [“ + beanDefinition + “] for bean'” + beanName +
“‘: There is already [“+ oldBeanDefinition+ “] bound.”);
}
else {
if (this.logger.isInfoEnabled()) {
this.logger.info(“Overriding bean definition for bean ‘” + beanName +
“‘: replacing [“+ oldBeanDefinition+ “] with [“ + beanDefinition + “]”);
}
}
}
else {
this.beanDefinitionNames.add(beanName);
this.frozenBeanDefinitionNames= null;
}
//放到ioc容器,ioc容器底层是一个map
this.beanDefinitionMap.put(beanName,beanDefinition);
resetBeanDefinition(beanName);
}
讲到这里,大家对流程比较清楚,到bean是哪里生成实例的呢?
我们回过头来看这个方法
//处理BeanDefinition的地方
protectedvoidprocessBeanDefinition(Elementele, BeanDefinitionParserDelegate delegate) {
/* BeanDefinitionHolder 是BeanDefinition对象的封装类,封装了BeanDefinition,Bean的名子和别名。用它来完成向IoC容器注册。得到了这个BeanDefinitionHolder就意味着BeanDefinition是通过BeanDefinitionParserDelegate对xml元素的信息按照Spring的Bean规则进行解析得到的。*/
BeanDefinitionHolder bdHolder =delegate.parseBeanDefinitionElement(ele);//完成了bean的实例化。
if (bdHolder != null) {
bdHolder= delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
try {
// Register the final decorated instance.这里向ioc容器注册解析得到的BeanDefinition
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(newBeanComponentDefinition(bdHolder));
}
}
跟踪进入:
BeanDefinitionParserDelegate.java类中
public BeanDefinitionHolder parseBeanDefinitionElement(Elementele) {
returnparseBeanDefinitionElement(ele, null);
}
public BeanDefinitionHolder parseBeanDefinitionElement(Elementele, BeanDefinition containingBean) {
Stringid = ele.getAttribute(ID_ATTRIBUTE);
StringnameAttr = ele.getAttribute(NAME_ATTRIBUTE);
List<String>aliases = newArrayList<String>();
if (StringUtils.hasLength(nameAttr)){
String[]nameArr = StringUtils.tokenizeToStringArray(nameAttr, BEAN_NAME_DELIMITERS);
aliases.addAll(Arrays.asList(nameArr));
}
StringbeanName = id;
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”);
}
}
if (containingBean == null) {
checkNameUniqueness(beanName,aliases, ele);
}
//进行实例化
AbstractBeanDefinitionbeanDefinition = 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, ifstill possible,
// if the generator returned the class name plus asuffix.
// This is expected for Spring 1.2/2.0 backwardscompatibility.
StringbeanClassName = 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);
returnnull;
}
}
String[]aliasesArray = StringUtils.toStringArray(aliases);
returnnewBeanDefinitionHolder(beanDefinition, beanName, aliasesArray);
}
returnnull;
}
public AbstractBeanDefinition parseBeanDefinitionElement(
Elementele, String beanName, BeanDefinition containingBean) {
this.parseState.push(new BeanEntry(beanName));
StringclassName = null;
if (ele.hasAttribute(CLASS_ATTRIBUTE)){
className= ele.getAttribute(CLASS_ATTRIBUTE).trim();
}
try {
Stringparent = null;
if (ele.hasAttribute(PARENT_ATTRIBUTE)){
parent= ele.getAttribute(PARENT_ATTRIBUTE);
}
//实例化
AbstractBeanDefinitionbd = createBeanDefinition(className, parent);
parseBeanDefinitionAttributes(ele,beanName, containingBean, bd);
bd.setDescription(DomUtils.getChildElementValueByTagName(ele,DESCRIPTION_ELEMENT));
parseMetaElements(ele,bd);
parseLookupOverrideSubElements(ele,bd.getMethodOverrides());
parseReplacedMethodSubElements(ele,bd.getMethodOverrides());
parseConstructorArgElements(ele,bd);
parsePropertyElements(ele,bd);
parseQualifierElements(ele,bd);
bd.setResource(this.readerContext.getResource());
bd.setSource(extractSource(ele));
return bd;
}
catch (ClassNotFoundExceptionex) {
error(“Bean class [“+ className + “] not found”, ele, ex);
}
catch (NoClassDefFoundErrorerr) {
error(“Class that bean class [“ + className + “] depends on not found”, ele, err);
}
catch (Throwable ex) {
error(“Unexpected failure during bean definitionparsing”, ele, ex);
}
finally {
this.parseState.pop();
}
returnnull;
}
protected AbstractBeanDefinition createBeanDefinition(StringclassName, String parentName)
throws ClassNotFoundException{
//工具类实例化
returnBeanDefinitionReaderUtils.createBeanDefinition(
parentName,className, this.readerContext.getBeanClassLoader());
}
publicstaticAbstractBeanDefinition createBeanDefinition(
StringparentName, String className, ClassLoader classLoader) throws ClassNotFoundException{
GenericBeanDefinitionbd = newGenericBeanDefinition();
bd.setParentName(parentName);
if (className != null) {
if (classLoader != null) {
//例用类加载器,进行反射实例化
bd.setBeanClass(ClassUtils.forName(className,classLoader));
}
else {
bd.setBeanClassName(className);
}
}
return bd;
}
从以上分析可以看出,实例化bean是一个一个对象进行行的。实例化出一个对象,就把这个对象放在ioc容器中。