这两篇 主要是在集成过程中 对相关知识的学习

1、了解springApplication

非spring boot 使用Spring cloud config (1) 了解springApplication

spring ApplicationContext 自定义

ApplicationContext是“事实上”的容器标准,它基于BeanFactory并对其做了一些功能上的扩展。例如:通过MessageResource支持国际化
提供了容器内部的消息发布机制
自动添加BeanFactoryPostProcessor、BeanPostProcessor到容器中复制代码

作用:

获取xml 更改

生成bean 更改

扩展点:

图中表示出了Spring容器中设计到的很多扩展点,主要可以分为以下几类:BeanFactoryPostProcessor各种AwareBeanPostProcessor隐藏的一些特殊功能
复制代码

BeanFactoryPostProcessor

解析成BeanDefinition后,实例化之前。从名字可以看出来,BeanFactoryPostProcessor针对的应该是容器级别的扩展,名为“BeanFactory  PostProcessor”即对容器中所有的BeanDefinition都起普遍作用。BeanFactoryPostProcessor有几个我们比较常用的子类PropertyPlaceholderConfigurer、CustomEditorConfigurer,前者用于配置文件中的${var}变量替换,后者用于自定义编辑BeanDefinition中的属性值,合理利用CustomEditorConfigurer会有一些意想不到的效果复制代码
ApplicationContext在初始化过程中会调用invokeBeanFactoryPostProcessors(beanFactory),该函数会找出所有BeanFactoryPostProcessor类型的bean,调用postProcessBeanFactory方法。复制代码

BeanPostProcessor

对于Bean这一级别,关注的主要是Bean实例化后,初始化前后的

BeanPostProcessor在BeanFactory的初始化bean的函数initializeBean中,主要代码为,基本就是取出所有的BeanPostProcessor,然后遍历调用其postProcessBeforeInitialization或者postProcessAfterInitialization方法。复制代码

参考:http://www.jianshu.com/p/2692bf784976

初始化:

ContextLoaderListener 的作用

该类可以作为Listener使用,在启动Tomcat容器的时候,该类的作用就是自动装载ApplicationContext的配置信息ContextLoaderListener会读取这些XML文件并产生 WebApplicationContext对象,然后将这个对象放置在ServletContext的属性里,这样我们只要可以得到Servlet就可 以得到WebApplicationContext对象,并利用这个对象访问spring 容器管理的bean。
复制代码

参考:http://blog.csdn.net/zjw10wei321/article/details/40145241

@Overridepublic void contextInitialized(ServletContextEvent event) {initWebApplicationContext(event.getServletContext());}复制代码

ContextLoader中,会根据servlet 上下文,创建WebApplicationContext,也会打印log

        try {// Store context in local instance variable, to guarantee that// it is available on ServletContext shutdown.if (this.context == null) {this.context = createWebApplicationContext(servletContext);}
复制代码

根据提供的servlet上下文去初始化Spring的web应用上下文,在构造时使用当前应用上下文或者在web.xml中配置参数contextClass和contextConfigLocation去创建新的上下文。

(1)先确定contextClass 读配置参数,需要时ConfigurableWebApplicationContext的子类,如果不是抛出异常,然后把contextClass 强制转换为ConfigurableWebApplicationContext。

   protected WebApplicationContext createWebApplicationContext(ServletContext sc) {//这里需要确定我们载入的根WebApplication的类型,  //由在web.xml中配置的contextClass中配置的参数, 如果没有使用默认的 WebApplicationContext。
Class<?> contextClass = determineContextClass(sc);if (!ConfigurableWebApplicationContext.class.isAssignableFrom(contextClass)) {throw new ApplicationContextException("Custom context class [" + contextClass.getName() +"] is not of type [" + ConfigurableWebApplicationContext.class.getName() + "]");}return (ConfigurableWebApplicationContext) BeanUtils.instantiateClass(contextClass);}复制代码

获取根据servlet上下文,获取ContextClass,即 配置的Contextcalss 或者默认的(XmlWebApplicationContext)。必须是ConfigurableWebApplicationContext的实现

 /*** Config param for the root WebApplicationContext implementation class to use: {@value}* @see #determineContextClass(ServletContext)*/public static final String CONTEXT_CLASS_PARAM = "contextClass";
复制代码
     * @return the WebApplicationContext implementation class to use* @see #CONTEXT_CLASS_PARAM* @see org.springframework.web.context.support.XmlWebApplicationContext*/protected Class<?> determineContextClass(ServletContext servletContext) {String contextClassName = servletContext.getInitParameter(CONTEXT_CLASS_PARAM);if (contextClassName != null) {try {return ClassUtils.forName(contextClassName, ClassUtils.getDefaultClassLoader());}catch (ClassNotFoundException ex) {throw new ApplicationContextException("Failed to load custom context class [" + contextClassName + "]", ex);}}//默认else {contextClassName = defaultStrategies.getProperty(WebApplicationContext.class.getName());try {return ClassUtils.forName(contextClassName, ContextLoader.class.getClassLoader());}catch (ClassNotFoundException ex) {throw new ApplicationContextException("Failed to load default context class [" + contextClassName + "]", ex);}}}
复制代码

(2)读loadParentContext

(     web.xml配置的locatorFactorySelector和parentContextKey,设置父上下文
BeanFactoryLocator locator )
复制代码

然后获取parent Context,加载父上下文的主要原因 没看懂。。。不过web应用,一般没有,不用担心

如何获取ApplicationContext

1.WebApplicationContext wac = ContextLoader.getCurrentWebApplicationContext();

当前应用的WebApplicationContext就保存在 ContextLoader的currentContextPerThread属性当中

            ClassLoader ccl = Thread.currentThread().getContextClassLoader();if (ccl == ContextLoader.class.getClassLoader()) {currentContext = this.context;}else if (ccl != null) {currentContextPerThread.put(ccl, this.context);}
复制代码
2.基于ServletContext上下文获取的方式ServletContext sc = request.getSession().getServletContext();ApplicationContext ac1 = WebApplicationContextUtils.getRequiredWebApplicationContext(sc);ApplicationContext ac2 = WebApplicationContextUtils.getWebApplicationContext(sc);WebApplicationContext wac1 = (WebApplicationContext) sc.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);3.还有一些更合适的,基于Spring提供的抽象类或者接口,在初始化Bean时注入ApplicationContext3.1:继承自抽象类ApplicationObjectSupport说明:抽象类ApplicationObjectSupport提供getApplicationContext()方法,可以方便的获取到ApplicationContext。Spring初始化时,会通过该抽象类的setApplicationContext(ApplicationContext context)方法将ApplicationContext 对象注入。3.2:继承自抽象类WebApplicationObjectSupport说明:类似上面方法,调用getWebApplicationContext()获取WebApplicationContext3.3:实现接口ApplicationContextAware说明:实现该接口的setApplicationContext(ApplicationContext context)方法,并保存ApplicationContext 对象。总结:Context结构复杂,parentContext结构的作用,及如何的去加载bean工厂的逻辑原理。
复制代码

如果创建的是,ConfigurableWebApplicationContext, 会读loadParentContext

protected ApplicationContext loadParentContext(ServletContext servletContext) {ApplicationContext parentContext = null;String locatorFactorySelector = servletContext.getInitParameter(LOCATOR_FACTORY_SELECTOR_PARAM);String parentContextKey = servletContext.getInitParameter(LOCATOR_FACTORY_KEY_PARAM);复制代码

2、了解environment

PropertySource:属性源,key-value属性对抽象,比如用于配置数据PropertyResolver:属性解析器,用于解析相应key的valueEnvironment:环境,本身是一个PropertyResolver,但是提供了Profile特性,即可以根据环境得到相应数据(即激活不同的Profile,可以得到不同的属性数据,比如用于多环境场景的配置(正式机、测试机、开发机DataSource配置))复制代码

2.Environment

   Environment接口是Spring对当前程序运行期间的环境的封装(spring)。主要提供了两大功能:profile和property(顶级接口PropertyResolver提供)。目前主要有StandardEnvironment、开发环境,比如JDK环境,系统环境;每个环境都有自己的配置数据,如System.getProperties()可以拿到JDK环境数据、System.getenv()可以拿到系统变量,ServletContext.getInitParameter()可以拿到Servlet环境配置数据。
Spring抽象了一个Environment来表示Spring应用程序环境配置,它整合了各种各样的外部环境,并且提供统一访问的方法。
复制代码
public interface Environment extends PropertyResolver {  //得到当前明确激活的剖面  String[] getActiveProfiles();  //得到默认激活的剖面,而不是明确设置激活的  String[] getDefaultProfiles();  //是否接受某些剖面  boolean acceptsProfiles(String... profiles);  }
复制代码

https://img-blog.csdn.net/20160531142913985

StandardServletEnvironment和MockEnvironment3种实现,分别代表普通程序、Web程序以及测试程序的环境。通过上述的getOrCreateEnvironment方法处理逻辑也是可以总结出来的。
复制代码

会读取配置文件如servletConfigInitParams,servletContextInitParams,jdni,系统配置等

StubPropertySource

临时作为一个PropertySource的占位,后期会被真实的PropertySource取代。

2.环境的装载
public class StandardServletEnvironment extends StandardEnvironment implements ConfigurableWebEnvironment {@Overrideprotected void customizePropertySources(MutablePropertySources propertySources) {propertySources.addLast(new StubPropertySource(SERVLET_CONFIG_PROPERTY_SOURCE_NAME));//servletConfigInitParamspropertySources.addLast(new StubPropertySource(SERVLET_CONTEXT_PROPERTY_SOURCE_NAME));//servletContextInitParamsif (JndiLocatorDelegate.isDefaultJndiEnvironmentAvailable()) {propertySources.addLast(new JndiPropertySource(JNDI_PROPERTY_SOURCE_NAME));}super.customizePropertySources(propertySources);}
复制代码

配置文件添加:

MutablePropertySources类中有一个list (PropertySource)如下,配置信息 (PropertySource)add 到这个list当中

public class MutablePropertySources implements PropertySources {private final Log logger;private final List<PropertySource<?>> propertySourceList;
复制代码
 addFirst:在propertySourceList 头部添加元素。addLast:在propertySourceList 尾部添加元素。addAtIndex:在propertySourceList 指定的位置添加元素。
复制代码

配置信息类:PropertySource 一个 name 和T source,即 key 和源头

public abstract class PropertySource<T> {protected final   String name;//属性源名称protected final T source;//属性源(比如来自Map,那就是一个Map对象)public String getName();  //获取属性源的名字  public T getSource();        //获取属性源  public boolean containsProperty(String name);  //是否包含某个属性  public abstract Object getProperty(String name);   //得到属性名对应的属性值
}
复制代码
 RandomValuePropertySource:source是random。ServletConfigPropertySource:source是ServletConfig。ServletContextPropertySource:source是ServletContext。JndiPropertySource:source是JndiLocatorDelegate。StubPropertySource:source是Object。MapPropertySource:source是Map<String, Object>。
复制代码

配置信息类 PropertySources

包含多个PropertySource,继承了Iterable接口,所以它的子类还具有迭代的能力。

实现类 MutablePropertySources它包含了一个CopyOnWriteArrayList集合,用来包含多个PropertySource
复制代码

profile :切面

profile 配置是一个被命名的,bean定义的逻辑组,这些bean只有在给定的profile配置激活时才会注册到容器。不管是XML还是注解,Beans都有可能指派给profile配置。Environment环境对象的作用,对于profiles配置来说,它能决定当前激活的是哪个profile配置,和哪个profile是默认。就需要根据不同的环境选择不同的配置;

profile有两种: 默认的:通过环境中“spring.profiles.default”属性获取,如果没有配置默认值是“default” 明确激活的:通过环境中“spring.profiles.active”获取 查找顺序是:先进性明确激活的匹配,如果没有指定明确激活的(即集合为空)就找默认的;配置属性值从Environment读取。

@Profile()的使用
可以使用在类或方法上,表示这个bean或方法属于哪个剖面 示例:

@Configuration
public class Test {public static void main(String[] args) throws ClassNotFoundException {System.setProperty("spring.profiles.active","dev");ApplicationContext context = new AnnotationConfigApplicationContext(Test.class);System.out.println(Arrays.asList(context.getBeanNamesForType(String.class)));}@Bean()@Profile("test")public String str1() {return "str1";}@Bean@Profile("dev")public String str2() {return "str2";}@Beanpublic String str3() {return "str3";}
}
复制代码

profile:http://www.jianshu.com/p/49e950b0b008

http://blog.csdn.net/u011179993/article/details/51511364

@propertySource

Java Config方式的注解,其属性会自动注册到相应的Environment

@Configuration
@PropertySource(value = "classpath:resources.properties", ignoreResourceNotFound = false)
public class AppConfig {
}
复制代码

综上说明:

先添加servletConfigInitParams,然后添加servletContextInitParams,其次判断是否是jndi环境,如果是则添加jndiProperties,最后调用父类的customizePropertySources(propertySources)。
复制代码

PropertySourceLocator

PlaceHolder 是什么

property的属性${canal.instance.mysql.slaveId:1234} 取配置文件key的时候带了:后面跟了一个默认值

参考“:

http://www.jianshu.com/p/df57fefe0ab7

https://www.cnblogs.com/dragonfei/archive/2016/10/09/5906474.html

https://github.com/Eric-ly/spring-mvc-with-spring-cloud-config-client-without-springboot

http://www.jianshu.com/p/df57fefe0ab7

https://www.cnblogs.com/dragonfei/archive/2016/10/09/5906474.html

https://github.com/Eric-ly/spring-mvc-with-spring-cloud-config-client-without-springboot

spring 集成 spring cloud config 的相关知识相关推荐

  1. Spring系列(十三):AOP相关知识笔记

    今天给大家分享AOP相关的知识,希望对大家能有所帮助! 1.AOP定义 AOP全称为Aspect Oriented Programming,中文含义为:面向切面编程. 通过预编译方式和运行期动态代理实 ...

  2. 为Spring Cloud Config插上管理的翅膀

    最近一致在更新Spring Cloud Config的相关内容,主要也是为这篇埋个伏笔,相信不少调研过Spring Cloud Config的用户都会吐槽它的管理能力太弱.因此,就有了下面为讲推荐的这 ...

  3. Spring Cloud Config配置中心的使用

    一.概述 1. 为什么使用? 1> 配置文件太多,不方便维护 2> 配置文件一般都保存这各种明文显示的密码,无法保证配置内容的安全性,也无法做到按权限分配给个人 3> 更新配置项目需 ...

  4. Activiti学习——Activiti与Spring集成

    与Spring集成 基础准备 目录结构 相关jar包 Activiti的相关jar包  Activiti依赖的相关jar包  Spring的相关jar包  Spring依赖的相关jar包  本示例相关 ...

  5. Spring集成单元测试

    Spring集成单元测试 @(Spring)[单元测试, Spring, 集成] Spring集成单元测试 第一步导入jar包 第二步创建一个类 第三步集成Spring单元测试 第四步编写测试代码 第 ...

  6. spring(7)spring mvc 的高级技术

    [0]README 1)本文部分文字描述转自:"Spring In Action(中/英文版)",旨在review  "spring(7)spring mvc 的高级技术 ...

  7. Spring Cloud(九)高可用的分布式配置中心 Spring Cloud Config 集成 Eureka 服务

    上一篇文章,讲了SpringCloudConfig 集成Git仓库,这一篇我们讲一下SpringCloudConfig 配和 Eureka 注册中心一起使用 在分布式系统中,由于服务数量巨多,为了方便 ...

  8. Spring Cloud(八)高可用的分布式配置中心 Spring Cloud Config

    在分布式系统中,由于服务数量巨多,为了方便服务配置文件统一管理,实时更新,所以需要分布式配置中心组件.在Spring Cloud中,有分布式配置中心组件spring cloud config,它支持配 ...

  9. spring cloud config将配置存储在数据库中

    点击上方"方志朋",选择"置顶或者星标" 你的关注意义重大! Spring Cloud Config Server最常见是将配置文件放在本地或者远程Git仓库, ...

最新文章

  1. spring的事务隔离_再深一点:面试工作两不误,源码级理解Spring事务
  2. 【每日一念经】四轮面试,我如何拿到美团的offer?
  3. 交换机与路由器大战已结束,超大规模计算公司胜出
  4. CrateDB——全文搜索使用的是lucene,尚不知其底层实现
  5. CSS进阶(10)—— 深入理解BFC结界
  6. linux磁盘和文件系统管理
  7. #3864. Hero meet devil dp套dp + 状压 + 状态机
  8. Install Shield制作安装包技巧(SQL篇)
  9. 【转载】python几种经典排序方法的实现
  10. Apache/MySQL/PHP 集体升级
  11. PyQt5实现软键盘
  12. 项目管理办公室(PMO) 的不同定位
  13. 呼叫中心系统建设方案
  14. Homekit直连的灯带控制套装
  15. 中科矿业带你走进SWARM/BZZ,选择去或留?
  16. HDU - 2586 - How far away ? (最短路)
  17. 快速入门——深度学习理论解析与实战应用
  18. 喜讯 | 人大金仓荣获行业信息化领航企业奖
  19. Opera 11.01的Bug
  20. 趣味老北京歇后语释疑

热门文章

  1. graphpad prism显著性差异分析_【市场表现】2020年第三季度企业债利差分析
  2. oracle存储一个数字格式,Oracle根本数据类型存储格式研究(二)—数字类型
  3. 一梦江湖一直获取服务器信息啥意思,《一梦江湖》原《楚留香》手游:叮咚!少侠你的NPC侠缘送来信物...
  4. java websocket 生存期_Java WebSocket生命周期
  5. mysql更新数据库中int 1_Mysql数据库int(1)和tinyint(1)的区别扩展阅读
  6. android 错误解决,Android常用错误解决汇总
  7. php基类控制器,控制器基类
  8. git checkoutbranch 回退到某个版本进行修改
  9. vue 表单 select option
  10. Hadoop HIVE 复合数据类型