ClassPathXMLApplicationContext上下文加载过程
发布时间:2020-12-16 23:35:03 所属栏目:百科 来源:网络整理
导读:今天看了一下《spring技术内幕》,看了下spring IOC容器的加载过程,但是里面的代码很杂,就自己用源码的测试用例debug了一下看了下过程 测试用例 @Test public void testSingleConfigLocation() throws IOException { ClassPathXmlApplicationContext ctx =
今天看了一下《spring技术内幕》,看了下spring IOC容器的加载过程,但是里面的代码很杂,就自己用源码的测试用例debug了一下看了下过程 测试用例 @Test public void testSingleConfigLocation() throws IOException { ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext(FQ_SIMPLE_CONTEXT); assertTrue(ctx.containsBean("someMessageSource")); LazyBean bean = ctx.getBean(LazyBean.class); Environment environment =ctx.getEnvironment(); String[] profiles =environment.getDefaultProfiles(); for(String s :profiles){ System.out.println(s); } CollectionBean bean2 = (CollectionBean) ctx.getBean("collection"); SingletonBean bean3 = ctx.getBean(SingletonBean.class); SingletonBean bean4 = ctx.getBean(SingletonBean.class); if (bean != null) { System.out.println(bean.getTestFiled()); } if (bean2 != null) { System.out.println(bean2.getList()); } if (bean3 != null) { bean3.process(); } if (bean4 != null) { bean4.process(); } System.out.println(ctx.getBeanDefinitionCount()); /* * System.out.println(ctx.getBean("lazyBean")); * System.out.println(ctx.getBean("lazyBean")); */ ctx.close(); } 加载过程
static { // Eagerly load the ContextClosedEvent class to avoid weird classloader issues // on application shutdown in WebLogic 8.1. (Reported by Dustin Woods.) ContextClosedEvent.class.getName(); } 大概就是说为了避免一些奇怪的问题会首先发布一个ContextClosedEvent事件,然后按照正常的初始化依次初始化父类。
public ClassPathXmlApplicationContext( String[] configLocations,boolean refresh,@Nullable ApplicationContext parent) throws BeansException { super(parent); setConfigLocations(configLocations); if (refresh) { refresh(); } }
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); } }
@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); } /** * Initialize the bean definition reader used for loading the bean * definitions of this context. Default implementation is empty. * <p>Can be overridden in subclasses,e.g. for turning off XML validation * or using a different XmlBeanDefinitionParser implementation. * @param reader the bean definition reader used by this context * @see org.springframework.beans.factory.xml.XmlBeanDefinitionReader#setDocumentReaderClass */ protected void initBeanDefinitionReader(XmlBeanDefinitionReader reader) { reader.setValidating(this.validating); } /** * Load the bean definitions with the given XmlBeanDefinitionReader. * <p>The lifecycle of the bean factory is handled by the {@link #refreshBeanFactory} * method; hence this method is just supposed to load and/or register bean definitions. * @param reader the XmlBeanDefinitionReader to use * @throws BeansException in case of bean registration errors * @throws IOException if the required XML document isn‘t found * @see #refreshBeanFactory * @see #getConfigLocations * @see #getResources * @see #getResourcePatternResolver */ 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); } }
protected void processBeanDefinition(Element ele,BeanDefinitionParserDelegate delegate) { 上面黑体标注的是将解析的BeanDefinition注册到上下文中的过程,我之前没找到这个方法很奇怪loadBeanDefinition返回的都是int我就在想,BeanDefinition哪去了。静态方法会调用BeanDefinitionRegistry 接口的registerBeanDefinition方法。而DefaultListableBeanFactory实现了这个接口, 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); } } } 到此BeanDefinition就被注册到了ClassPathXmlApplicationContext中,还有很多细节没贴出来,自己debug一下很有意思的 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |