码迷,mamicode.com
首页 > 编程语言 > 详细

Spring源码阅读

时间:2020-10-09 20:48:51      阅读:25      评论:0      收藏:0      [点我收藏+]

标签:not   gen   ebean   beans   actor   接口   core   close   loading   

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会先调用其父类的空参构造方法

技术图片

自上而下说起

1.DefaultResourceLoader 初始化属性ClassLoader

2.AbstractApplicationContext初始化属性resourcePatternResolver

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

4.1this初始化属性AnnotatedBeanDefinitionReader

4.2this初始化属性ClassPathBeanDefinitionScanner

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

2.3this()详解

2.3.1DefaultResourceLoader

技术图片

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创建包含了大量需要去了解的地方,后面会专门开一个章节就行介绍,其继承关系如下

技术图片

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

Spring源码阅读

标签:not   gen   ebean   beans   actor   接口   core   close   loading   

原文地址:https://www.cnblogs.com/cg961107/p/13783405.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!