• Spring源码阅读


    1.Spring 容器几个重要的接口

    org.springframework.core.env.Environment

    Interface representing the environment in which the current application is running.
    

    继承自org.springframework.core.env.PropertyResolver

    Interface for resolving properties against any underlying source.
    

    拥有PropertyResolver,则有用crud properties的行为

    Environment对ActiveProfiles进行了支持


    org.springframework.beans.factory.BeanFactory

    The root interface for accessing a Spring bean container.
    

    Bean container root接口

    关于spring的spring bean的生命周期可以查看该接口的文档,有详细的描述


    org.springframework.beans.factory.config.BeanDefinition

    A BeanDefinition describes a bean instance, which has property values, constructor argument values, and further information supplied byconcrete implementations.
    

    将xml,数据库等中的配置信息装载成一个一个的bean的BeanDefinition

    其继承了两大接口

    org.springframework.beans.BeanMetadataElement

      Interface to be implemented by bean metadata elements
      that carry a configuration source object.
    

    org.springframework.core.AttributeAccessor

    如其名现实该接口,拥有key-value的crud行为


    org.springframework.beans.factory.support.BeanDefinitionReader

    Simple interface for bean definition readers. Specifies load methods with Resource and String location parameters.
    

    加载Definition资源,比如读取xml文件,对应实现类有XmlBeanDefinitionReader


    org.springframework.beans.factory.config.BeanFactoryPostProcessor

    Allows for custom modification of an application context's bean definitions, adapting the bean property values of the context's underlying bean factory.
    

    主要用是对ConfigurableListableBeanFactory进行预处理,可以理解为对BeanFactory进行一些回调处理


    org.springframework.beans.factory.config.BeanPostProcessor

    Factory hook that allows for custom modification of new bean instances,e.g. checking for marker interfaces or wrapping them with proxies.
    

    主要是对SpringBean进行一些回调处理

    org.springframework.context.ApplicationContext

      Central interface to provide configuration for an application.
      This is read-only while the application is running, but may be
      reloaded if the implementation supports this.
    

    胶水接口,实现spring各种核心接口.

    1.org.springframework.core.env.EnvironmentCapable获取environment的行为

    2.org.springframework.beans.factory.ListableBeanFactory对BeanFactory进行了拓展,如其名Listable

    3.org.springframework.beans.factory.HierarchicalBeanFactory

    4.org.springframework.context.MessageSource

    5.org.springframework.context.ApplicationEventPublisher事件发布行为

    6.ResourcePatternResolver拥有加载资源的行为


    总结:从抽象的层面讲,通过Spring容器初始化大概需要以上接口的实现参与,所有行为的执行者当然是ApplicationContext

    Environment读取一些系统变量,例如System.getProperties()

    BeanDefinitionReader加载资源,生成BeanDefinition

    BeanFactory经过BeanFactoryPostProcessor回调处理

    依照BeanDefinition转换为SpringBean(反射)

    Spring的Bean经过BeanPostProcessor回调处理

    PS:以上几点没有时间上的发生顺序,也没有逻辑上的强关联,说得不是特别准确,但是从抽象的角度看,Spring容器的初始化大概会经历这几个流程节点.

    2.Spring容器初始化

    下面正式开始开始进行Spring的源码阅读,阅读源码的入口当然是ApplicationContext,笔者选择AnnotationConfigApplicationContext作为入口进行阅读,该对象是一个标准的spring上下文,接收annotated classes.

    2.1 初始化AnnotationConfigApplicationContext

    public class HelloSpring {
    	public static void main(String[] args) {
    		ApplicationContext context = new AnnotationConfigApplicationContext(Config.class);
    		Cat bean = context.getBean(Cat.class);
    	}
    }
    

    实例代码非常简单,注入一个引导Object的class文件,获取Bean

    2.2 AnnotationConfigApplicationContext实例化方法

    实例代码使用的构造方法

    	public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
    		this();
    		register(annotatedClasses);
    		refresh();
    	}
    

    下面就到了spring源码阅读起来恶心的地方,大量的使用了继承,当我通过该构造方法创建该对象的时候,Spring会先调用其父类的空参构造方法

    Snipaste_2020-10-08_23-01-44

    自上而下说起

    1.DefaultResourceLoader 初始化属性ClassLoader

    2.AbstractApplicationContext初始化属性resourcePatternResolver

    3.GenericApplicationContext初始化属性beanFactory(DefaultListableBeanFactory)这个实现类也繁杂

    4.1this初始化属性AnnotatedBeanDefinitionReader

    4.2this初始化属性ClassPathBeanDefinitionScanner

    简简单单一个this()大概会经历这些...

    2.3this()详解

    2.3.1DefaultResourceLoader

    Snipaste_2020-10-08_23-16-01

    ResourceLoader

     * Strategy interface for loading resources (e.. class path or file system
     * resources). An {@link org.springframework.context.ApplicationContext}
     * is required to provide this functionality, plus extended
     * {@link org.springframework.core.io.support.ResourcePatternResolver} support.
    

    一个加载资源的策略接口ApplicationContext必须提供该行为

    DefaultResourceLoaderResourceLoader的默认实现

    简单的说DefaultResourceLoader就是讲路径(String类型)包装成Resource,Resource是一种输入流.

    2.3.2AbstractApplicationContext

    ApplicationContext的模板方法

    extends:DefaultResourceLoader

    implements:ConfigurableApplicationContext接口

    2.3.2.1ConfigurableApplicationContext

    如其名,给上下文添加Configurable行为,其继承的接口有ApplicationContext,Lifecycle,Closeable

    Lifecycle:加入了start,stop的行为

    Closeable:继承自AutoCloseable 加入close的行为

    ApplicationContext:上文已介绍


    回到正题AbstractApplicationContext

    /* 
     * Create a new AbstractApplicationContext with no parent.
     */
    public AbstractApplicationContext() {
       this.resourcePatternResolver = getResourcePatternResolver();
    }
    

    创建一个ResourcePatternResolver,用于资源加载

    2.3.3GenericApplicationContext

    通用的ApplicatonContext,对AbstractApplicationContext进一步具体化.

    extends:AbstractApplicationContext

    implements:BeanDefinitionRegistry接口

    2.3.3.1BeanDefinitionRegistry

    用于保存Bean定义信息的注册表

    继承AliasRegistry:别名管理,可以进行别名注册


    回到正题GenericApplicationContext,创建一个BeanFactory

    /**
    	 * Create a new GenericApplicationContext.
    	 * @see #registerBeanDefinition
    	 * @see #refresh
    	 */
    	public GenericApplicationContext() {
    		this.beanFactory = new DefaultListableBeanFactory();
    	}
    
    

    这个BeanFactory创建包含了大量需要去了解的地方,后面会专门开一个章节就行介绍,其继承关系如下

    Snipaste_2020-10-08_23-49-40

    2.3.4AnnotationConfigApplicationContext

    extends:GenericApplicationContext

    implements:AnnotationConfigRegistry

    2.3.4.1AnnotationConfigRegistry

    提供了两个行为

    /**
    	 * Register one or more annotated classes to be processed.
    	 * <p>Calls to {@code register} are idempotent; adding the same
    	 * annotated class more than once has no additional effect.
    	 * @param annotatedClasses one or more annotated classes,
    	 * e.g. {@link Configuration @Configuration} classes
    	 */
    	void register(Class<?>... annotatedClasses);
    
    	/**
    	 * Perform a scan within the specified base packages.
    	 * @param basePackages the packages to check for annotated classes
    	 */
    	void scan(String... basePackages);
    

    回到正题,该构造方法主要将连个属性进行实例化AnnotatedBeanDefinitionReader,ClassPathBeanDefinitionScanner

    下面介绍:AnnotatedBeanDefinitionReader

    2.3.4.2AnnotatedBeanDefinitionReader

    public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry) {
    		this(registry, getOrCreateEnvironment(registry));
    	}
    

    第一步:getOrCreateEnvironment

    	/**
    	 * Get the Environment from the given registry if possible, otherwise return a new
    	 * StandardEnvironment.
    	 */
    	private static Environment getOrCreateEnvironment(BeanDefinitionRegistry registry) {
    		//获取 environment
    		if (registry instanceof EnvironmentCapable) {
    			return ((EnvironmentCapable) registry).getEnvironment();
    		}
    		//创建一个environment,很明显,不会走到这一步,因为applicationContext继承了EnvironmentCapable,当然也是创建一个StandardEnvironment
    		return new StandardEnvironment();
    	}
    

    第二部:this方法

    	public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) {
    		this.registry = registry;
    		//根据注册器以及环境变量  创建条件鉴别器,主要使用@Conditional注解
    		this.conditionEvaluator = new ConditionEvaluator(registry, environment, null);
        
    		AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
    	}
    
  • 相关阅读:
    2:编写虚幻引擎中的UC和C++代码
    1:编写虚幻引擎中的UC和C++代码
    0:编写虚幻引擎中的UC和C++代码
    4:虚幻引擎网络架构:技术要点总结篇
    3:虚幻引擎网络架构:GameInfo,PlayerMove
    2:虚幻引擎网络架构:Replication
    1:虚幻引擎网络架构:Actors
    R12-表详解-总帐
    clob 类型
    成本更新和算法
  • 原文地址:https://www.cnblogs.com/cg961107/p/13783405.html
Copyright © 2020-2023  润新知