您的位置:首页 > 编程语言 > Java开发

具体代码分析Spring启动流程

2018-02-08 00:00 459 查看
start:...........

new一个上下文容器对象

ApplicationContext app = new ClassPathXmlApplicationContext(paths);

容器的构造方法

public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent)
throws BeansException {

super(parent);
setConfigLocations(configLocations);
if (refresh) {
refresh();//关键的方法,跳到祖师爷(AbstractApplicationContext)的方法中
}
}

祖师爷refresh()的实现

@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// Prepare this context for refreshing.
prepareRefresh();

// Tell the subclass to refresh the internal bean factory.
//关键的步骤在这里!!!!!!!!!!!!!!!!!!!!!获得一个 beanFactory,所有bean的定义信息
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

// Prepare the bean factory for use in this context.
prepareBeanFactory(beanFactory);

try {
.........
}catch{
......
} finally {
......
}
}

obtainFreshBeanFactory()还在本类中

protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
//关键步骤!!!!!
refreshBeanFactory();
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
if (logger.isDebugEnabled()) {
logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory);
}
return beanFactory;
}

refreshBeanFactory()有两个实现类,目前走的实现类是AbstractRefreshableApplicationContext

@Override
protected final void refreshBeanFactory() throws BeansException {
if (hasBeanFactory()) {
destroyBeans();
closeBeanFactory();
}
try {
DefaultListableBeanFactory beanFactory = createBeanFactory();
beanFactory.setSerializationId(getId());
customizeBeanFactory(beanFactory);
//关键步骤!!!!
loadBeanDefinitions(beanFactory);
synchronized (this.beanFactoryMonitor) {
this.beanFactory = beanFactory;
}
}
catch (IOException ex) {
throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
}
}

loadBeanDefinitions(DefaultListableBeanFactory beanFactory)跳到类
AbstractXmlApplicationContext
这个地方需要再斟酌....

@Override
protected 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(this.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.
initBeanDefinitionReader(beanDefinitionReader);
//关键步骤!!!!
loadBeanDefinitions(beanDefinitionReader);
}

loadBeanDefinitions(XmlBeanDefinitionReader reader)的实现类是:AbstractXmlApplicationContext

protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException {
Resource[] configResources = getConfigResources();
//两种配置文件
if (configResources != null) {
//XML配置文件解析走
reader.loadBeanDefinitions(configResources);
}
String[] configLocations = getConfigLocations();
if (configLocations != null) {
//properties配置文件解析走
reader.loadBeanDefinitions(configLocations);
}
}

目前走的是XML解析,loadBeanDefinitions(Resource... resources)的实现类是

AbstractBeanDefinitionReader

@Override
public int loadBeanDefinitions(Resource... resources) throws BeanDefinitionStoreException {
Assert.notNull(resources, "Resource array must not be null");
int counter = 0;
//多个配置文件的解析
for (Resource resource : resources) {
counter += loadBeanDefinitions(resource);
}
return counter;
}

loadBeanDefinitions(Resource resource)走XML解析的实现类:XmlBeanDefinitionReader

@Override
public int loadBeanDefinitions(Resource resource) throws BeanDefinitionStoreException {
//走的是 XML解析
return loadBeanDefinitions(new EncodedResource(resource));
}

XmlBeanDefinitionReader对XML具体解析,主要是想将xml的配置信息,转换成java对象(Document)持有;

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();
}
}
}

如何将xml配置信息转换成Document对像持有

protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource)
throws BeanDefinitionStoreException {
try {
//关键步骤,将配置文件的信息数据,转换成java对象持有
Document doc = doLoadDocument(inputSource, resource);
//关键步骤,然后解析java对象,循环,根据各种节点key,判断,开始进行注册业务实现类对象之间的关系.....
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);
}
}


!!!!!具体如何解析Document.....!!!!!!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  spring IOC AOP 启动流程