从ClassPathXmlApplicationContext中看spring在web中如何运行
来源:互联网 发布:iscroll.js 下载 编辑:程序博客网 时间:2024/06/04 00:51
十一小长假在家玩和太happy了。根本没有时间看java之类的东西,今天是假日最后一天,所以会把上次的补上
个人感觉在web中看spring如何解析如何运行是一件比较难的事,spring附加了在我们看来是没有用的代码,但是既然它写了肯定是有用处的,这是我们初级程序员可以学习的地方。好了不多说了。看代码
ApplicationContext ac = new ClassPathXmlApplicationContext("application.xml");我们来看看ClassPathXmlApplicationContext的构造器
public ClassPathXmlApplicationContext(String configLocation)/* */ throws BeansException/* */ {/* 83 */ this(new String[] { configLocation }, true, null);/* */ }
为什么我的反编译有行数的。。你问我。。我也不知道。。。。
this是当前类继续看
public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent)/* */ throws BeansException/* */ {/* 136 */ super(parent);/* 137 */ setConfigLocations(configLocations);/* 138 */ if (refresh)/* 139 */ refresh();/* */ }先看下super。。。super调用的是父类构造器
看下AbstractXmlApplicationContext
public AbstractXmlApplicationContext(ApplicationContext parent)/* */ {/* 58 */ super(parent);/* */ }还是一样。。继续看
看下AbstractRefreshableConfigApplicationContext
public AbstractRefreshableConfigApplicationContext(ApplicationContext parent) { super(parent); }
还是一样。继续看下AbstractRefreshableApplicationContext
public AbstractRefreshableApplicationContext(ApplicationContext parent) { super(parent); }
看下AbstractApplicationContext
public AbstractApplicationContext(ApplicationContext parent) { this.logger = LogFactory.getLog(getClass()); this.id = ObjectUtils.identityToString(this); this.beanFactoryPostProcessors = new ArrayList(); this.active = false; this.activeMonitor = new Object(); this.startupShutdownMonitor = new Object(); this.applicationListeners = new ArrayList(); this.parent = parent; this.resourcePatternResolver = getResourcePatternResolver(); }
上面没有什么好看的。无非是初始化我们看下最后this.resourcePatternResolver = getResourcePatternResolver();
protected ResourcePatternResolver getResourcePatternResolver() { return new PathMatchingResourcePatternResolver(this); }
这是我自己写的PathMatchingResourcePatternResolver
public static void main(String[] args){ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(); Resource[] resources = null;try {resources = resolver.getResources("file:"+System.getProperty("user.dir")+"/WebRoot/WEB-INF/spring01/*/*.xml");System.out.println(resources[0].getURL()); System.out.println(resources.length);} catch (IOException e) {e.printStackTrace();} }
这个类是干嘛的就是匹配*的,所以我们配spring.xml不用一个一个去配了。直接用这类,就行了。。
AbstractApplicationContext中主要是初始化。看不看意义不大,关键看下这个
public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent) throws BeansException { super(parent); setConfigLocations(configLocations); if (refresh) refresh(); }
setConfigLocations(configLocations);这个不用说了吧。。。更简单了,把spring.xml的名字放进来嘛
看下if (refresh)
refresh();
其实refresh肯定为true,这个我们应该能感觉到,事实也是这样
public ClassPathXmlApplicationContext(String configLocation) throws BeansException { this(new String[] { configLocation }, true, null); }
直接把true传过来了
关键是看下refresh()这个方法。。我们来看下。。。。refresh()这个方法是在AbstractApplicationContext这个类中,spring的目的是解耦合,但是他自己写的确实耦合度不是一般的高
public void refresh() throws BeansException, IllegalStateException { synchronized (this.startupShutdownMonitor) { prepareRefresh(); ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); prepareBeanFactory(beanFactory); try { postProcessBeanFactory(beanFactory); invokeBeanFactoryPostProcessors(beanFactory); registerBeanPostProcessors(beanFactory); initMessageSource(); initApplicationEventMulticaster(); onRefresh(); registerListeners(); finishBeanFactoryInitialization(beanFactory); finishRefresh(); } catch (BeansException ex) { beanFactory.destroySingletons(); cancelRefresh(ex); throw ex; } } }
synchronized (this.startupShutdownMonitor) {
prepareRefresh();
这个我们这里就不看了。无非是同步一些东西,看也看不懂,继续
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
我们看下obtainFreshBeanFactory这个方法
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() { refreshBeanFactory(); ConfigurableListableBeanFactory beanFactory = getBeanFactory(); if (this.logger.isInfoEnabled()) { this.logger.info("Bean factory for application context [" + getId() + "]: " + ObjectUtils.identityToString(beanFactory)); } if (this.logger.isDebugEnabled()) { this.logger.debug(beanFactory.getBeanDefinitionCount() + " beans defined in " + this); } return beanFactory; }
看下refreshBeanFactory()这个方法
protected abstract void refreshBeanFactory() throws BeansException, IllegalStateException;
在他自己类中是这样写的。我们是看父类代码还是看子类代码呢。。。肯定是看子类的代码吗。abstract在,,那不用看了。。去他的子类找一找
在AbstractRefreshableApplicationContext中找到了refreshBeanFactory()的实现
protected final void refreshBeanFactory() throws BeansException { if (hasBeanFactory()) { destroyBeans(); closeBeanFactory(); } try { DefaultListableBeanFactory beanFactory = createBeanFactory(); customizeBeanFactory(beanFactory); loadBeanDefinitions(beanFactory); synchronized (this.beanFactoryMonitor) { this.beanFactory = beanFactory; } } catch (IOException ex) { throw new ApplicationContextException("I/O error parsing XML document for application context [" + getDisplayName() + "]", ex); } }
我们看下第一个if()中写的是hasBeanFactory()英文意思写得非常明白是滞有bean工厂吗,有的话销毁beans还有关闭bean工厂吗。如果你是第一次初始化就直接看下try-catch里面代码好了
DefaultListableBeanFactory beanFactory = createBeanFactory();
这个是实例化beanFactory其实我们不用看的。浪费时间。。。。
继续
customizeBeanFactory(beanFactory);定制客户的专属bean工厂也不用看的
关键的来了
loadBeanDefinitions(beanFactory);我们看下原码
在它的本类中
protected abstract void loadBeanDefinitions(DefaultListableBeanFactory paramDefaultListableBeanFactory) throws IOException, BeansException;
写的又是这样一句话。。。。看子类嘛。。。。其实第一次看真的会晕
在AbstractXmlApplicationContext这个类中实现了loadBeanDefinitions的方法。看下
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws IOException { XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory); beanDefinitionReader.setResourceLoader(this); beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this)); initBeanDefinitionReader(beanDefinitionReader); loadBeanDefinitions(beanDefinitionReader); }
我们看最关键的
loadBeanDefinitions(beanDefinitionReader);
protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException { Resource[] configResources = getConfigResources(); if (configResources != null) reader.loadBeanDefinitions(configResources); String[] configLocations = getConfigLocations(); if (configLocations != null) reader.loadBeanDefinitions(configLocations); }
getConfigResources();
protected Resource[] getConfigResources() { return null; }
你说看了有什么用。。。直接不用看
String[] configLocations = getConfigLocations();
我们刚刚在refresh()上面是不是setConfigLocations()了;
那这里我们不就是直接获得了嘛,简单
if (configLocations != null)
reader.loadBeanDefinitions(configLocations);
这里configLocations肯定不为空啊。
看下
public int loadBeanDefinitions(String[] locations) throws BeanDefinitionStoreException { Assert.notNull(locations, "Location array must not be null"); int counter = 0; for (int i = 0; i < locations.length; ++i) <pre class="html" name="code">counter += loadBeanDefinitions(locations[i]); return counter; }
看下
counter += loadBeanDefinitions(locations[i]);
我就直接copy出来了
public int loadBeanDefinitions(String location) throws BeanDefinitionStoreException { return loadBeanDefinitions(location, null); } public int loadBeanDefinitions(String location, Set 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) { try { Resource[] resources = ((ResourcePatternResolver)resourceLoader).getResources(location); loadCount = loadBeanDefinitions(resources); if (actualResources != null) for (int i = 0; i < resources.length; ++i) actualResources.add(resources[i]); if (this.logger.isDebugEnabled()) this.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); } } Resource resource = resourceLoader.getResource(location); int loadCount = loadBeanDefinitions(resource); if (actualResources != null) actualResources.add(resource); if (this.logger.isDebugEnabled()) this.logger.debug("Loaded " + loadCount + " bean definitions from location [" + location + "]"); return loadCount; }
Resource[] resources = ((ResourcePatternResolver)resourceLoader).getResources(location);
这个方法可以去看看上面我写的PathMatchingResourcePatternResolver这个类。。你就知道干嘛的了
loadCount = loadBeanDefinitions(resources);
主要看下这个
public int loadBeanDefinitions(Resource[] resources) throws BeanDefinitionStoreException { Assert.notNull(resources, "Resource array must not be null"); int counter = 0; for (int i = 0; i < resources.length; ++i) counter += loadBeanDefinitions(resources[i]); return counter; }
点开loadBeanDefinitions里进入到BeanDefiitionReader中的方法
public abstract int loadBeanDefinitions(Resource paramResource) throws BeanDefinitionStoreException;
还是看子类啊
看下XmlBeanDifintionReader
public int loadBeanDefinitions(Resource resource) throws BeanDefinitionStoreException { return loadBeanDefinitions(new EncodedResource(resource)); }
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()); } 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); } }
看下doLoadBeanDefinitions这个类
protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource) throws BeanDefinitionStoreException { int validationMode; try { validationMode = getValidationModeForResource(resource); Document doc = this.documentLoader.loadDocument(inputSource, getEntityResolver(), this.errorHandler, validationMode, isNamespaceAware()); 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这个类了吗,肯定是dom解析xml吗。。这里我们不用管了。解析xml不是spring的范围。所以不用太在意。下一篇会总结一下。。。其实也不用总结了。。。差不多就是这个过程 。web中也是这样调的。。。。。。。。看懂了这个。。。差不多。。。web也没有问题
个人写得比较详细,第一个是让自己更好的学习,也希望大家有问题可以和我说。。大家一起进步
- 从ClassPathXmlApplicationContext中看spring在web中如何运行
- spring在web中如何运行1
- Spring中ClassPathXmlApplicationContext类
- Spring中ClassPathXmlApplicationContext的简述
- Spring中ClassPathXmlApplicationContext类的简单使用/在jar包中访问spring配置文件的方式
- spring ClassPathXmlApplicationContext
- spring在web运行2
- spring中ClassPathXmlApplicationContext类的简单使用
- Spring中ClassPathXmlApplicationContext类的简单使用
- Spring中ClassPathXmlApplicationContext类的简单使用
- Spring中ClassPathXmlApplicationContext类的简单使用
- Spring中ClassPathXmlApplicationContext类的简单使用
- Spring中ClassPathXmlApplicationContext类的简单使用
- Spring中ClassPathXmlApplicationContext类的简单使用
- Spring中ClassPathXmlApplicationContext类的简单使用
- SPRING中CLASSPATHXMLAPPLICATIONCONTEXT类的简单使用
- Spring中ClassPathXmlApplicationContext类的简单使用
- Spring中ClassPathXmlApplicationContext类的简单使用
- EOF是什么?
- 修改与添加Administrator的方法?
- 链表排序的两种实现方法
- VRPN学习笔记(二) 配置server和编写client
- TRIZ系列-创新原理-2-抽取原理
- 从ClassPathXmlApplicationContext中看spring在web中如何运行
- HDOJ 1022 Train Problem I
- HDU 3158 PropBot(DFS)
- 数据结构之栈的练习
- Spring3 注解 设置某控制器的统一的的访问路径
- 黑马程序员——面向对象6:关于静态
- hbase总结(二)-hbase安装
- 3D 打印
- OJ2017题、2018题