spring boot 源码

	PropertySource和Enviroment   http://blog.csdn.net/u011179993/article/details/51511364
	统一抽象资源---Resource  http://blog.csdn.net/u011179993/article/details/51531140
	SpringApplicationRunListener及其周期  http://blog.csdn.net/u011179993/article/details/51555690
	BeanDefinition及读取、注册  http://blog.csdn.net/u011179993/article/details/51598567
	http://blog.csdn.net/u011179993/article/category/5623745
	
	
	
BeanDefinitionRegistry   该类的作用主要是向注册表中注册 BeanDefinition 实例,完成 注册的过程。
		public interface BeanDefinitionRegistry extends AliasRegistry {
	 
	    // 关键 -> 往注册表中注册一个新的 BeanDefinition 实例 
	    void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)throws BeanDefinitionStoreException;
	 
	    // 移除注册表中已注册的 BeanDefinition 实例
	    void removeBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;
	 
	    // 从注册中取得指定的 BeanDefinition 实例
	    BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;
	 
	    // 判断 BeanDefinition 实例是否在注册表中(是否注册)
	    boolean containsBeanDefinition(String beanName);
	 
	    // 取得注册表中所有 BeanDefinition 实例的 beanName(标识)
	    String[] getBeanDefinitionNames();
	 
	    // 返回注册表中 BeanDefinition 实例的数量
	    int getBeanDefinitionCount();
	 
	    // beanName(标识)是否被占用
	    boolean isBeanNameInUse(String beanName);
		}
	
http://blog.csdn.net/u011179993/article/details/51655057	
BeanFactoryPostProcessor  当spring初始化好BenaDefinnitionMap之后,提供了一个接口BeanFactoryPostProcessor,允许我们开发者自定义的去修改BeanFactory中的内容,这也是符合“spring”的开闭原则
		public interface BeanFactoryPostProcessor {

    /**
     * 这里提供了修改beanFacotry的机会
         */
    void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;

		}
	
http://jinnianshilongnian.iteye.com/blog/2000183
PropertySource:属性源,key-value属性对抽象,比如用于配置数据




PropertyResolver 属性解析器,用来根据名字解析其值等
	public interface PropertyResolver {  
	  
	    //是否包含某个属性  
	    boolean containsProperty(String key);  
	   
	        //获取属性值 如果找不到返回null   
	    String getProperty(String key);  
	       
	        //获取属性值,如果找不到返回默认值        
	    String getProperty(String key, String defaultValue);  
	    
	        //获取指定类型的属性值,找不到返回null  
	    <T> T getProperty(String key, Class<T> targetType);  
	  
	        //获取指定类型的属性值,找不到返回默认值  
	    <T> T getProperty(String key, Class<T> targetType, T defaultValue);  
	  
	         //获取属性值为某个Class类型,找不到返回null,如果类型不兼容将抛出ConversionException  
	    <T> Class<T> getPropertyAsClass(String key, Class<T> targetType);  
	  
	        //获取属性值,找不到抛出异常IllegalStateException  
	    String getRequiredProperty(String key) throws IllegalStateException;  
	  
	        //获取指定类型的属性值,找不到抛出异常IllegalStateException         
	    <T> T getRequiredProperty(String key, Class<T> targetType) throws IllegalStateException;  
	  
	        //替换文本中的占位符(${key})到属性值,找不到不解析  
	    String resolvePlaceholders(String text);  
	  
	        //替换文本中的占位符(${key})到属性值,找不到抛出异常IllegalArgumentException  
	    String resolveRequiredPlaceholders(String text) throws IllegalArgumentException;  
	  
	}  	
	
http://blog.csdn.net/u011179993/article/details/51598567
BeanDefinition  这个接口描述bean的结构,对应XML中的< bean >或者配置类中的@Bean 它集成了BeanMetadataElement和AttributeAccessor
	
PropertyValues  包含了一个或者多个PropertyValue对象,通常用作特定的一个目的bean的属性更新	
	
AttributeAccessor接口定义了最基本的对任意对象的元数据的修改或者获取	
	
	
	
	
	private void initialize(Object[] sources) {
		if (sources != null && sources.length > 0) {
			this.sources.addAll(Arrays.asList(sources));
		}
		
		//判断是否web环境 
		//javax.servlet.Servlet"和"org.springframework.web.context.ConfigurableWebApplicationContext"类能被加载到代表为web环境
		this.webEnvironment = deduceWebEnvironment();
		
		
		/*
		*通过Thread.currentThread().getContextClassLoader(); 获取到 类加载器
		*获取 spring-boot-{v}.jar/META-INF/spring.factories 文件中 org.springframework.context.ApplicationContextInitializer 的值
		*   org.springframework.boot.context.ConfigurationWarningsApplicationContextInitializer   配置警告应用程序上下文初始化程序
		*   org.springframework.boot.context.ContextIdApplicationContextInitializer  上下文Id 应用上下文初始化器
		*   org.springframework.boot.context.config.DelegatingApplicationContextInitializer 委托应用程序上下文初始化程序
    *   org.springframework.boot.context.embedded.ServerPortInfoApplicationContextInitializer  设置端口
		*并通过各自的构造方法实例化
		*
		*/
		setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));
	  
	  
	  /*
	  *获取 spring-boot-{v}.jar/META-INF/spring.factories 文件中 org.springframework.context.ApplicationListener 的值,并实例化
	  *  org.springframework.boot.ClearCachesApplicationListener
	  *  org.springframework.boot.builder.ParentContextCloserApplicationListener
	  *  org.springframework.boot.context.FileEncodingApplicationListener
	  *  org.springframework.boot.context.config.AnsiOutputApplicationListener
	  *  org.springframework.boot.context.config.ConfigFileApplicationListener
	  *  org.springframework.boot.context.config.DelegatingApplicationListener
	  *  org.springframework.boot.liquibase.LiquibaseServiceLocatorApplicationListener
	  *  org.springframework.boot.logging.ClasspathLoggingApplicationListener
	  *  org.springframework.boot.logging.LoggingApplicationListener
	  *
		setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
		
		
		
		/*
		*获取main方法所在的类
		*StackTraceElement[] stackTrace = new RuntimeException().getStackTrace(); 获取 虚拟机栈中 栈桢数组
		*/
		this.mainApplicationClass = deduceMainApplicationClass();
	}


public ConfigurableApplicationContext run(String... args) {
		//计时器
		StopWatch stopWatch = new StopWatch();
		//开始计时
		stopWatch.start();
		ConfigurableApplicationContext context = null;
		FailureAnalyzers analyzers = null;
		
		//用来设置java.awt.headless 属性是true 还是false,是J2SE的一种模式用于在缺少显示屏、键盘    
    //或者鼠标时的系统配置
		configureHeadlessProperty();
		
		
		/*
		*获得运行侦听器  获取 spring-boot-{v}.jar/META-INF/spring.factories 文件中 org.springframework.boot.SpringApplicationRunListener 的值
		*  org.springframework.boot.context.event.EventPublishingRunListener 事件发布运行侦听器
		*在EventPublishingRunListener实例化时将 ApplicationListener的所有实现类添加 到SimpleApplicationEventMulticaster 事件中
		*/
		SpringApplicationRunListeners listeners = getRunListeners(args);
		
		
		/*
		*启动SpringApplicationRunListeners侦听器
		*启动EventPublishingRunListener侦听器
		*org.springframework.boot.context.config.ConfigFileApplicationListener   onApplicationEvent没有做任何事
		*org.springframework.boot.logging.LoggingApplicationListener		onApplicationEvent加载 LoggingSystem对象
		*org.springframework.boot.context.config.DelegatingApplicationListener   onApplicationEvent没有做任何事
		*org.springframework.boot.liquibase.LiquibaseServiceLocatorApplicationListener  onApplicationEvent没有做任何事
		*调用以上监听器的onApplicationEvent 方法 
		*/
		listeners.starting();
		
		
		try {
		
			//设置应用参数
			ApplicationArguments applicationArguments = new DefaultApplicationArguments(
					args);
					
			//加载配置
			ConfigurableEnvironment environment = prepareEnvironment(listeners,
					applicationArguments);
					
		  //打印Banner  默认 SpringBootBanner.BANNER
			Banner printedBanner = printBanner(environment);
			
			//获取 上下文ApplicationContext
			context = createApplicationContext();
			//错误处理
			analyzers = new FailureAnalyzers(context);
			//准备上下文
			prepareContext(context, environment, listeners, applicationArguments,
					printedBanner);
			//刷新上下文
			refreshContext(context);
			//完成加载
			afterRefresh(context, applicationArguments);
			//完成侦听器
			listeners.finished(context, null);
			//停止记时
			stopWatch.stop();
			//记录启动信息
			if (this.logStartupInfo) {
				new StartupInfoLogger(this.mainApplicationClass)
						.logStarted(getApplicationLog(), stopWatch);
			}
			return context;
		}
		catch (Throwable ex) {
			handleRunFailure(context, listeners, analyzers, ex);
			throw new IllegalStateException(ex);
		}
	}
	
	
	private ConfigurableEnvironment prepareEnvironment(
			SpringApplicationRunListeners listeners,
			ApplicationArguments applicationArguments) {
			
		// 创建和配置环境    StandardServletEnvironment.customizePropertySources获取配置加载顺序
		ConfigurableEnvironment environment = getOrCreateEnvironment();
		
		
		//获取启动配置
		configureEnvironment(environment, applicationArguments.getSourceArgs());
		
		/**
		*通过 EventPublishingRunListener监听 发送ApplicationEnvironmentPreparedEvent 事件到下面监听器
		*加载配置以下配置的值并加载配置,并调用以下监听的 onApplicationEvent 方法
		*org.springframework.boot.context.config.ConfigFileApplicationListener   加载配置  
		*   获取org.springframework.boot.env.EnvironmentPostProcessor配置的值 
		*      org.springframework.boot.cloud.CloudFoundryVcapEnvironmentPostProcessor
		*          获取 spring cloud config VCAP_APPLICATION  和  VCAP_SERVICES  的配置 
		*
    *      org.springframework.boot.env.SpringApplicationJsonEnvironmentPostProcessor
    *          获取${spring.application.json:${SPRING_APPLICATION_JSON:}}  的配置
    *
		*      org.springframework.boot.context.config.ConfigFileApplicationListener
		*	    		添加属性源  [servletConfigInitParams,servletContextInitParams,systemProperties,systemEnvironment,random]
		*	    		获取 org.springframework.boot.env.PropertySourceLoader的值
		*	    		    org.springframework.boot.env.PropertiesPropertySourceLoader
		*	            org.springframework.boot.env.YamlPropertySourceLoader
		*	            配置文件路径加载顺序  1.获取用户自定义路径地址(spring.config.location的值) 2.[file:./config/, file:./, classpath:/config/, classpath:/]
		*	            文件加载顺序  1.获取用户自定义文件名(spring.config.name的值) 2.默认文件名(application)
		*	            文件后缀加载顺序: [properties, xml, yml, yaml]
		*	             1.file:./config/application.properties
		*	             2.file:./config/application.xml
		*	             3.file:./config/application.yml
		*	             4.file:./config/application.yaml
		*	             file:./application.properties
		*	             file:./application.xml
		*	             file:./application.yml
		*	             file:./application.yaml
		*	             file:./application.yaml
		*	             classpath:/config/application.properties
		*	             classpath:/config/application.xml
		*	             classpath:/config/application.yml
		*	             classpath:/config/application.yaml
		*	             //我配置的是放在  classpath下的
		*	             classpath:/application.properties
		*	             classpath:/application-dev.properties 
		*	        读取完配置,过滤spring bean
		*	        将配置绑定到  SpringApplication    
	  *org.springframework.boot.context.config.AnsiOutputApplicationListener
	  *org.springframework.boot.logging.LoggingApplicationListener
	  *org.springframework.boot.logging.ClasspathLoggingApplicationListener
	  *org.springframework.boot.autoconfigure.BackgroundPreinitializer
	  *org.springframework.boot.context.config.DelegatingApplicationListener
	  *org.springframework.boot.context.FileEncodingApplicationListener
	  *
	  *
	  *
		*/
		listeners.environmentPrepared(environment);
		if (!this.webEnvironment) {
			environment = new EnvironmentConverter(getClassLoader())
					.convertToStandardEnvironmentIfNecessary(environment);
		}
		return environment;
	}
		
		
	/**
	* 配置优先级
	* StandardServletEnvironment.customizePropertySources
	* SERVLET_CONFIG_PROPERTY_SOURCE_NAME > SERVLET_CONTEXT_PROPERTY_SOURCE_NAME > JNDI_PROPERTY_SOURCE_NAME  > 系统属性 > 环境变量
	* servlet配置属性源名称 > servlet上下文属性源名称 > jndi属性源名称 > 系统属性 > 环境变量
	**/
	@Override
	protected void customizePropertySources(MutablePropertySources propertySources) {
		propertySources.addLast(new StubPropertySource(SERVLET_CONFIG_PROPERTY_SOURCE_NAME));
		propertySources.addLast(new StubPropertySource(SERVLET_CONTEXT_PROPERTY_SOURCE_NAME));
		if (JndiLocatorDelegate.isDefaultJndiEnvironmentAvailable()) {
			propertySources.addLast(new JndiPropertySource(JNDI_PROPERTY_SOURCE_NAME));
		}
		//获取系统属性、环境变量
		super.customizePropertySources(propertySources);
	}
	
	
	protected void configureEnvironment(ConfigurableEnvironment environment,
			String[] args) {
		//加载命令行属性
		configurePropertySources(environment, args);
		//获取 spring.profiles.active  的配置
		configureProfiles(environment, args);
	}
	

	
	
	@Override
	public void postProcessEnvironment(ConfigurableEnvironment environment,
			SpringApplication application) {
		addPropertySources(environment, application.getResourceLoader());
		//加载配置
		configureIgnoreBeanInfo(environment);
		绑定资源
		bindToSpringApplication(environment, application);
	}
	
	
	
	protected ConfigurableApplicationContext createApplicationContext() {
		Class<?> contextClass = this.applicationContextClass;
		if (contextClass == null) {
			try {
			  /**
			  * web项目 初始化  org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext
			  * java项目  初始化 org.springframework.context.annotation.AnnotationConfigApplicationContext
			  **/
				contextClass = Class.forName(this.webEnvironment
						? DEFAULT_WEB_CONTEXT_CLASS : DEFAULT_CONTEXT_CLASS);
			}
			catch (ClassNotFoundException ex) {
				throw new IllegalStateException(
						"Unable create a default ApplicationContext, "
								+ "please specify an ApplicationContextClass",
						ex);
			}
		}
		//初始化AnnotationConfigEmbeddedWebApplicationContext  注释Bean定义阅读器 类路径Bean定义扫描器
		return (ConfigurableApplicationContext) BeanUtils.instantiate(contextClass);
	}
	
	
	
	
	private void prepareContext(ConfigurableApplicationContext context,
			ConfigurableEnvironment environment, SpringApplicationRunListeners listeners,
			ApplicationArguments applicationArguments, Banner printedBanner) {
			
		/**
		* 注释Bean定义阅读器
		* 类路径Bean定义扫描器 
		**/	
		context.setEnvironment(environment);
		
		//上下文后处理
		postProcessApplicationContext(context);
		
		//初始化上下文
		applyInitializers(context);
		//上下文准备完成
		listeners.contextPrepared(context);
		if (this.logStartupInfo) {
			logStartupInfo(context.getParent() == null);
			logStartupProfileInfo(context);
		}

		//添加特殊的bean
		context.getBeanFactory().registerSingleton("springApplicationArguments",
				applicationArguments);
		if (printedBanner != null) {
			context.getBeanFactory().registerSingleton("springBootBanner", printedBanner);
		}

		// Load the sources
		Set<Object> sources = getSources();
		Assert.notEmpty(sources, "Sources must not be empty");
		
		//将bean加载到应用程序上下文中。
		load(context, sources.toArray(new Object[sources.size()]));
		//将context添加到监听中
		listeners.contextLoaded(context);
	}
	
	
	
	
	@Override
	public void refresh() throws BeansException, IllegalStateException {
		synchronized (this.startupShutdownMonitor) {
			
			//准备刷新上下文
			prepareRefresh();

			//告诉子类刷新内部bean工厂
			ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

			// 准备在这个上下文中使用的bean工厂
			prepareBeanFactory(beanFactory);

			try {
				// 允许在上下文子类中对bean工厂进行后处理。
				postProcessBeanFactory(beanFactory);

				// 在上下文中调用在Bean中注册的工厂处理器
				invokeBeanFactoryPostProcessors(beanFactory);

				// Register bean processors that intercept bean creation.
				registerBeanPostProcessors(beanFactory);

				// Initialize message source for this context.
				initMessageSource();

				// Initialize event multicaster for this context.
				initApplicationEventMulticaster();

				// Initialize other special beans in specific context subclasses.
				onRefresh();

				// Check for listener beans and register them.
				registerListeners();

				// Instantiate all remaining (non-lazy-init) singletons.
				finishBeanFactoryInitialization(beanFactory);

				// Last step: publish corresponding event.
				finishRefresh();
			}

			catch (BeansException ex) {
				if (logger.isWarnEnabled()) {
					logger.warn("Exception encountered during context initialization - " +
							"cancelling refresh attempt: " + ex);
				}

				// Destroy already created singletons to avoid dangling resources.
				destroyBeans();

				// Reset 'active' flag.
				cancelRefresh(ex);

				// Propagate exception to caller.
				throw ex;
			}

			finally {
				// Reset common introspection caches in Spring's core, since we
				// might not ever need metadata for singleton beans anymore...
				resetCommonCaches();
			}
		}
	}
	
	
	
	protected void prepareRefresh() {
		this.startupDate = System.currentTimeMillis();
		this.closed.set(false);
		this.active.set(true);

		if (logger.isInfoEnabled()) {
			logger.info("Refreshing " + this);
		}

		// 在上下文环境中初始化任何占位符属性源
		initPropertySources();

		
		// 验证所有标记为必需的属性是可解析的
		getEnvironment().validateRequiredProperties();


		this.earlyApplicationEvents = new LinkedHashSet<ApplicationEvent>();
	}
	
    原文作者:Spring Boot
    原文地址: https://blog.csdn.net/zhibo112/article/details/78349666
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞