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 源码
原文作者:Spring Boot
原文地址: https://blog.csdn.net/zhibo112/article/details/78349666
本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
原文地址: https://blog.csdn.net/zhibo112/article/details/78349666
本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。