zoukankan      html  css  js  c++  java
  • Spring源码阅读

    ① 定位:定位资源文件(定位配置文件或扫描相关注解)

    ② 加载:解析配置信息

    ③ 注册:将Bean的信息表示解析成BeanDefinition注册到BeanDefinitionMap

    ClassPathXmlApplicationContext:

    1. 初始化资源加载器:AbstractApplicationContext()
    // AbstractApplicationContext类
    	public AbstractApplicationContext() {
    		this.resourcePatternResolver = getResourcePatternResolver();
    	}
    	
    	//获取一个Spring Source的加载器用于读入Spring Bean定义资源文件
    	protected ResourcePatternResolver getResourcePatternResolver() {
    		//AbstractApplicationContext继承DefaultResourceLoader,因此也是一个资源加载器
    		return new PathMatchingResourcePatternResolver(this);
    	}
    
    1. 设置资源路径:setConfigLocations(configLocations);

    2. 容器初始化AbstractApplicationContext#refresh()

       // ClassPathXmlApplicationContext类
       public ClassPathXmlApplicationContext(
           String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)      throws BeansException {
           // IOC 1:初始化资源加载器   
           super(parent);   
           // IOC 2: 设置资源路径   
           setConfigLocations(configLocations);      
           if (refresh) {      
               // IOC 3:IOC容器初始化入口,重启、刷新、重置、相关组件初始化
               // AbstractApplicationContext#refresh()
               refresh();   
           }}
    
    • 刷新bean factory:AbstractRefreshableApplicationContext#refreshBeanFactory()
    AbstractApplicationContext#refresh():
        ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
    AbstractApplicationContext#obtainFreshBeanFactory():
        refreshBeanFactory();
    
    // AbstractRefreshableApplicationContext#refreshBeanFactory()
    	@Override
    	protected final void refreshBeanFactory() throws BeansException {
    		// IOC : 如果已经有容器,销毁容器中的bean,关闭容器
    		if (hasBeanFactory()) {
    			destroyBeans();
    			closeBeanFactory();
    		}
    		try {
    			// IOC :创建IOC容器
    			DefaultListableBeanFactory beanFactory = createBeanFactory();
    			beanFactory.setSerializationId(getId());
    			// 对IOC容器进行定制化,如设置启动参数,开启注解的自动装配等
    			customizeBeanFactory(beanFactory);
    			
    			// IOC 5:开始加载BeanDefinitions.(由具体子类实现)
    			loadBeanDefinitions(beanFactory);
    			synchronized (this.beanFactoryMonitor) {
    				this.beanFactory = beanFactory;
    			}
    		}
    		catch (IOException ex) {
    			throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
    		}
    	}
    
    • 加载BeanDefinitions(子类实现):AbstractXmlApplicationContext#loadBeanDefinitions()
    // AbstractXmlApplicationContext#loadBeanDefinitions()
    protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) 
        throws BeansException, IOException {
    		// IOC : 创建XmlBeanDefinitionReader,即创建Bean读取器,并通过回调设置到容器中去,容器使用该读取器读取Bean定义资源
    		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);
    
    		// IOC 6 : Bean读取器真正实现加载的方法
    		loadBeanDefinitions(beanDefinitionReader);
    	}
    
    // AbstractXmlApplicationContext#loadBeanDefinitions()
    protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) 
        throws BeansException, IOException {
    		// 获取资源定位
    		Resource[] configResources = getConfigResources();
    		if (configResources != null) {
    			// IOC 7: Xml读取器调用其父类AbstractBeanDefinitionReader读取定位的Bean定义资源
    			reader.loadBeanDefinitions(configResources);
    		}
    		
            // 获取FileSystemXmlApplicationContext构造方法中setConfigLocations方法设置的资源
    		String[] configLocations = getConfigLocations();
    		if (configLocations != null) {
    			reader.loadBeanDefinitions(configLocations);
    		}
    	}
    
    // IOC : 遍历加载
    AbstractBeanDefinitionReader#loadBeanDefinitions():
    	  counter += loadBeanDefinitions(location);
    
    public int loadBeanDefinitions(EncodedResource encodedResource) 
        throws BeanDefinitionStoreException {
    		try {
    			// IOC :将资源文件转为InputStream的IO流
    			InputStream inputStream = encodedResource.getResource().getInputStream();
    			try {
    				InputSource inputSource = new InputSource(inputStream);
    				if (encodedResource.getEncoding() != null) {
    					inputSource.setEncoding(encodedResource.getEncoding());
    				}
    				// IOC 8 : 具体解析资源文件
    				return doLoadBeanDefinitions(inputSource, encodedResource.getResource());
    			}
    			finally {
    				//关闭从Resource中得到的IO流
    				inputStream.close();
    			}
    		}
        }
    
    • 解析资源文件,并注册到BeanDefinitionMap:XmlBeanDefinitionReader#doLoadBeanDefinitions()
    // XmlBeanDefinitionReader#doLoadBeanDefinitions()
    protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource)
    	throws BeanDefinitionStoreException {
    		try {
    			// IOC : 将XML文件转换为DOM对象,解析过程由documentLoader实现
    			Document doc = doLoadDocument(inputSource, resource);
    			// IOC 9: 这里是启动对Bean定义解析的详细过程,该解析过程会用到Spring的Bean配置规则
    			return registerBeanDefinitions(doc, resource);
    		}catch(Exception ex){
                // ...
            }
    }
    
    //按照Spring的Bean语义要求将Bean定义资源解析并转换为容器内部数据结构
    public int registerBeanDefinitions(Document doc, Resource resource) 
        throws BeanDefinitionStoreException {
    		//得到BeanDefinitionDocumentReader来对xml格式的BeanDefinition解析
    		BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader();
    		//获得容器中注册的Bean数量
    		int countBefore = getRegistry().getBeanDefinitionCount();
    
    		// IOC 10:具体的解析实现过程由实现类DefaultBeanDefinitionDocumentReader完成
    		documentReader.registerBeanDefinitions(doc, createReaderContext(resource));
    		//统计解析的Bean数量
    		return getRegistry().getBeanDefinitionCount() - countBefore;
    	}
    
    // IOC 11:解析并注册BeanDefinitions
    DefaultBeanDefinitionDocumentReader#registerBeanDefinitions():
    	  doRegisterBeanDefinitions(root);
    
    // IOC 12 : 从根元素开始对Document元素进行解析,
     DefaultBeanDefinitionDocumentReader#doRegisterBeanDefinitions():
    	  parseBeanDefinitions(root, this.delegate);
     DefaultBeanDefinitionDocumentReader#parseBeanDefinitions():
    	  parseDefaultElement(ele, delegate);
    
    // IOC 13: 元素节点既不是导入元素,也不是别名元素,即普通的<Bean>元素
    DefaultBeanDefinitionDocumentReader#parseDefaultElement():
    	else if (delegate.nodeNameEquals(ele, BEAN_ELEMENT)) {
    		processBeanDefinition(ele, delegate);}
    
    //DefaultBeanDefinitionDocumentReader#processBeanDefinition():
    protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
    		// BeanDefinitionHolder是对BeanDefinition的封装,即Bean定义的封装类
        	// IOC 14:将解析出的beanName和beanDefinition封装成Holder。
    		BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
    		if (bdHolder != null) {
    			bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
    			try {
    				// IOC 15:向Spring IOC容器注册解析得到的Bean定义
    				BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());
    			}
    			catch (BeanDefinitionStoreException ex) {
    				getReaderContext().error("Failed to register bean definition with name '" +
    						bdHolder.getBeanName() + "'", ele, ex);
    			}
    
    			//在完成向Spring IOC容器注册解析得到的Bean定义之后,发送注册事件
    			getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
    		}
    	}
    
    

    AnnotationConfigApplicationContext

    1. 初始化注解Bean读取器和包路径扫描器:AnnotationConfigApplicationContext()
    public AnnotationConfigApplicationContext() {   
        this.reader = new AnnotatedBeanDefinitionReader(this);   
        this.scanner = new ClassPathBeanDefinitionScanner(this);
    }
    
    public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
    	// IOC 1 : 初始化注解Bean读取器和包路径扫描器
        this();
    	// IOC 2 :直接注册beanDefinition到容器中
    	register(annotatedClasses);
        // IOC 3 :刷新容器
    	refresh();
    }
    
    public AnnotationConfigApplicationContext(String... basePackages) {
    	this();
    	// IOC 2 :设置扫描包路径,将包路径下的所有Bean对象注册到容器中
    	scan(basePackages);
    	refresh();
    }
    
    • 直接注册:register(Class<?>... annotatedClasses)
    // IOC 2 :为容器注册一个要被处理的注解Bean,必须手动调用容器的refresh()方法刷新容器,触发容器对新注册的Bean的处理
    public void register(Class<?>... annotatedClasses) {   
        Assert.notEmpty(annotatedClasses, "At least one annotated class must be specified");     this.reader.register(annotatedClasses);
    }
    
    • 设置扫描路径:scan(String... basePackages)
    // IOC 2 :扫描指定包路径及其子包下的注解类,为了使新添加的类被处理,必须手动调用refresh()方法刷新容器
    public void scan(String... basePackages) {   
    	Assert.notEmpty(basePackages, "At least one base package must be specified");   		this.scanner.scan(basePackages);
    }
    
  • 相关阅读:
    iptables
    linux时间同步
    iftop使用
    linux目录结构及定时任务
    awk基本用法
    二、Java面向对象(6)_深入变量
    二、Java面向对象(5)_static修饰符
    二、Java面向对象(4)_构造函数
    二、Java面向对象(3)_类和对象
    二、Java面向对象(2)_软件开发方式
  • 原文地址:https://www.cnblogs.com/kiqi/p/14346756.html
Copyright © 2011-2022 走看看