这两篇 主要是在集成过程中 对相关知识的学习
1、了解springApplication 非spring boot 使用Spring cloud config (1) 了解springApplication
spring ApplicationContext 自定义
1 2 3 4 5 ApplicationContext是“事实上”的容器标准,它基于BeanFactory并对其做了一些功能上的扩展。例如: 通过MessageResource支持国际化 提供了容器内部的消息发布机制 自动添加BeanFactoryPostProcessor、BeanPostProcessor到容器中
作用:
获取xml 更改
生成bean 更改
扩展点:
1 2 3 4 5 6 图中表示出了Spring容器中设计到的很多扩展点,主要可以分为以下几类: BeanFactoryPostProcessor 各种Aware BeanPostProcessor 隐藏的一些特殊功能
BeanFactoryPostProcessor 1 解析成BeanDefinition后,实例化之前。从名字可以看出来,BeanFactoryPostProcessor针对的应该是容器级别的扩展,名为“BeanFactory PostProcessor”即对容器中所有的BeanDefinition都起普遍作用。BeanFactoryPostProcessor有几个我们比较常用的子类PropertyPlaceholderConfigurer、CustomEditorConfigurer,前者用于配置文件中的${var}变量替换,后者用于自定义编辑BeanDefinition中的属性值,合理利用CustomEditorConfigurer会有一些意想不到的效果
1 ApplicationContext在初始化过程中会调用invokeBeanFactoryPostProcessors(beanFactory),该函数会找出所有BeanFactoryPostProcessor类型的bean,调用postProcessBeanFactory方法。
BeanPostProcessor 对于Bean这一级别,关注的主要是Bean实例化后,初始化前后的
1 BeanPostProcessor在BeanFactory的初始化bean的函数initializeBean中,主要代码为,基本就是取出所有的BeanPostProcessor,然后遍历调用其postProcessBeforeInitialization或者postProcessAfterInitialization方法。
参考:http://www.jianshu.com/p/2692bf784976
初始化:
ContextLoaderListener 的作用
1 2 3 该类可以作为Listener使用,在启动Tomcat容器的时候,该类的作用就是自动装载ApplicationContext的配置信息 ContextLoaderListener会读取这些XML文件并产生 WebApplicationContext对象,然后将这个对象放置在ServletContext的属性里,这样我们只要可以得到Servlet就可 以得到WebApplicationContext对象,并利用这个对象访问spring 容器管理的bean。
参考:http://blog.csdn.net/zjw10wei321/article/details/40145241
1 2 3 4 5 @Override public void contextInitialized(ServletContextEvent event) { initWebApplicationContext(event.getServletContext()); }
ContextLoader中,会根据servlet 上下文,创建WebApplicationContext,也会打印log
1 2 3 4 5 6 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。
1 2 3 4 5 6 7 8 9 10 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的实现
1 2 3 4 5 /** * Config param for the root WebApplicationContext implementation class to use: {@value} * @see #determineContextClass(ServletContext) */ public static final String CONTEXT_CLASS_PARAM = "contextClass";
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 * @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
1 2 ( web.xml配置的locatorFactorySelector和parentContextKey,设置父上下文 BeanFactoryLocator locator )
然后获取parent Context,加载父上下文的主要原因 没看懂。。。不过web应用,一般没有,不用担心
如何获取ApplicationContext
1.WebApplicationContext wac = ContextLoader.getCurrentWebApplicationContext();
当前应用的WebApplicationContext就保存在 ContextLoader的currentContextPerThread属性当中
1 2 3 4 5 6 7 ClassLoader ccl = Thread.currentThread().getContextClassLoader(); if (ccl == ContextLoader.class.getClassLoader()) { currentContext = this.context; } else if (ccl != null) { currentContextPerThread.put(ccl, this.context); }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 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时注入ApplicationContext 3.1:继承自抽象类ApplicationObjectSupport 说明:抽象类ApplicationObjectSupport提供getApplicationContext()方法,可以方便的获取到ApplicationContext。 Spring初始化时,会通过该抽象类的setApplicationContext(ApplicationContext context)方法将ApplicationContext 对象注入。 3.2:继承自抽象类WebApplicationObjectSupport 说明:类似上面方法,调用getWebApplicationContext()获取WebApplicationContext 3.3:实现接口ApplicationContextAware 说明:实现该接口的setApplicationContext(ApplicationContext context)方法,并保存ApplicationContext 对象。 总结:Context结构复杂,parentContext结构的作用,及如何的去加载bean工厂的逻辑原理。
如果创建的是,ConfigurableWebApplicationContext, 会读loadParentContext
1 2 3 4 5 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 1 2 3 4 5 PropertySource:属性源,key-value属性对抽象,比如用于配置数据 PropertyResolver:属性解析器,用于解析相应key的value Environment:环境,本身是一个PropertyResolver,但是提供了Profile特性,即可以根据环境得到相应数据(即激活不同的Profile,可以得到不同的属性数据,比如用于多环境场景的配置(正式机、测试机、开发机DataSource配置))
2.Environment
1 2 3 Environment接口是Spring对当前程序运行期间的环境的封装(spring)。主要提供了两大功能:profile和property(顶级接口PropertyResolver提供)。目前主要有StandardEnvironment、 开发环境,比如JDK环境,系统环境;每个环境都有自己的配置数据,如System.getProperties()可以拿到JDK环境数据、System.getenv()可以拿到系统变量,ServletContext.getInitParameter()可以拿到Servlet环境配置数据。 Spring抽象了一个Environment来表示Spring应用程序环境配置,它整合了各种各样的外部环境,并且提供统一访问的方法。
1 2 3 4 5 6 7 8 9 10 11 public interface Environment extends PropertyResolver { //得到当前明确激活的剖面 String[] getActiveProfiles(); //得到默认激活的剖面,而不是明确设置激活的 String[] getDefaultProfiles(); //是否接受某些剖面 boolean acceptsProfiles(String... profiles); }
http://img.blog.csdn.net/20160531142913985
1 StandardServletEnvironment和MockEnvironment3种实现,分别代表普通程序、Web程序以及测试程序的环境。通过上述的getOrCreateEnvironment方法处理逻辑也是可以总结出来的。
会读取配置文件如servletConfigInitParams,servletContextInitParams,jdni,系统配置等
StubPropertySource
临时作为一个PropertySource的占位,后期会被真实的PropertySource取代。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 2.环境的装载 public class StandardServletEnvironment extends StandardEnvironment implements ConfigurableWebEnvironment { @Override protected void customizePropertySources(MutablePropertySources propertySources) { propertySources.addLast(new StubPropertySource(SERVLET_CONFIG_PROPERTY_SOURCE_NAME)); //servletConfigInitParams propertySources.addLast(new StubPropertySource(SERVLET_CONTEXT_PROPERTY_SOURCE_NAME)); //servletContextInitParams if (JndiLocatorDelegate.isDefaultJndiEnvironmentAvailable()) { propertySources.addLast(new JndiPropertySource(JNDI_PROPERTY_SOURCE_NAME)); } super.customizePropertySources(propertySources); }
配置文件添加:
MutablePropertySources类中有一个list (PropertySource)如下,配置信息 (PropertySource)add 到这个list当中
1 2 3 public class MutablePropertySources implements PropertySources { private final Log logger; private final List> propertySourceList;
1 2 3 4 5 addFirst:在propertySourceList 头部添加元素。 addLast:在propertySourceList 尾部添加元素。 addAtIndex:在propertySourceList 指定的位置添加元素。
配置信息类:PropertySource 一个 name 和T source,即 key 和源头
1 2 3 4 5 6 7 8 9 public abstract class PropertySource {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); //得到属性名对应的属性值 }
1 2 3 4 5 6 7 8 9 10 11 RandomValuePropertySource:source是random。 ServletConfigPropertySource:source是ServletConfig。 ServletContextPropertySource:source是ServletContext。 JndiPropertySource:source是JndiLocatorDelegate。 StubPropertySource:source是Object。 MapPropertySource:source是Map。
配置信息类 PropertySources
包含多个PropertySource,继承了Iterable接口,所以它的子类还具有迭代的能力。
1 2 3 实现类 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或方法属于哪个剖面 示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 @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"; } @Bean public String str3() { return "str3"; } }
profile:http://www.jianshu.com/p/49e950b0b008
http://blog.csdn.net/u011179993/article/details/51511364
@propertySource
Java Config方式的注解,其属性会自动注册到相应的Environment
1 2 3 4 @Configuration @PropertySource(value = "classpath:resources.properties", ignoreResourceNotFound = false) public class AppConfig { }
综上说明:
1 先添加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
这两篇 主要是在集成过程中 对相关知识的学习
1、了解springApplication 非spring boot 使用Spring cloud config (1) 了解springApplication
spring ApplicationContext 自定义
1 2 3 4 5 ApplicationContext是“事实上”的容器标准,它基于BeanFactory并对其做了一些功能上的扩展。例如: 通过MessageResource支持国际化 提供了容器内部的消息发布机制 自动添加BeanFactoryPostProcessor、BeanPostProcessor到容器中
作用:
获取xml 更改
生成bean 更改
扩展点:
1 2 3 4 5 6 图中表示出了Spring容器中设计到的很多扩展点,主要可以分为以下几类: BeanFactoryPostProcessor 各种Aware BeanPostProcessor 隐藏的一些特殊功能
BeanFactoryPostProcessor 1 解析成BeanDefinition后,实例化之前。从名字可以看出来,BeanFactoryPostProcessor针对的应该是容器级别的扩展,名为“BeanFactory PostProcessor”即对容器中所有的BeanDefinition都起普遍作用。BeanFactoryPostProcessor有几个我们比较常用的子类PropertyPlaceholderConfigurer、CustomEditorConfigurer,前者用于配置文件中的${var}变量替换,后者用于自定义编辑BeanDefinition中的属性值,合理利用CustomEditorConfigurer会有一些意想不到的效果
1 ApplicationContext在初始化过程中会调用invokeBeanFactoryPostProcessors(beanFactory),该函数会找出所有BeanFactoryPostProcessor类型的bean,调用postProcessBeanFactory方法。
BeanPostProcessor 对于Bean这一级别,关注的主要是Bean实例化后,初始化前后的
1 BeanPostProcessor在BeanFactory的初始化bean的函数initializeBean中,主要代码为,基本就是取出所有的BeanPostProcessor,然后遍历调用其postProcessBeforeInitialization或者postProcessAfterInitialization方法。
参考:http://www.jianshu.com/p/2692bf784976
初始化:
ContextLoaderListener 的作用
1 2 3 该类可以作为Listener使用,在启动Tomcat容器的时候,该类的作用就是自动装载ApplicationContext的配置信息 ContextLoaderListener会读取这些XML文件并产生 WebApplicationContext对象,然后将这个对象放置在ServletContext的属性里,这样我们只要可以得到Servlet就可 以得到WebApplicationContext对象,并利用这个对象访问spring 容器管理的bean。
参考:http://blog.csdn.net/zjw10wei321/article/details/40145241
1 2 3 4 5 @Override public void contextInitialized(ServletContextEvent event) { initWebApplicationContext(event.getServletContext()); }
ContextLoader中,会根据servlet 上下文,创建WebApplicationContext,也会打印log
1 2 3 4 5 6 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。
1 2 3 4 5 6 7 8 9 10 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的实现
1 2 3 4 5 /** * Config param for the root WebApplicationContext implementation class to use: {@value} * @see #determineContextClass(ServletContext) */ public static final String CONTEXT_CLASS_PARAM = "contextClass";
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 * @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
1 2 ( web.xml配置的locatorFactorySelector和parentContextKey,设置父上下文 BeanFactoryLocator locator )
然后获取parent Context,加载父上下文的主要原因 没看懂。。。不过web应用,一般没有,不用担心
如何获取ApplicationContext
1.WebApplicationContext wac = ContextLoader.getCurrentWebApplicationContext();
当前应用的WebApplicationContext就保存在 ContextLoader的currentContextPerThread属性当中
1 2 3 4 5 6 7 ClassLoader ccl = Thread.currentThread().getContextClassLoader(); if (ccl == ContextLoader.class.getClassLoader()) { currentContext = this.context; } else if (ccl != null) { currentContextPerThread.put(ccl, this.context); }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 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时注入ApplicationContext 3.1:继承自抽象类ApplicationObjectSupport 说明:抽象类ApplicationObjectSupport提供getApplicationContext()方法,可以方便的获取到ApplicationContext。 Spring初始化时,会通过该抽象类的setApplicationContext(ApplicationContext context)方法将ApplicationContext 对象注入。 3.2:继承自抽象类WebApplicationObjectSupport 说明:类似上面方法,调用getWebApplicationContext()获取WebApplicationContext 3.3:实现接口ApplicationContextAware 说明:实现该接口的setApplicationContext(ApplicationContext context)方法,并保存ApplicationContext 对象。 总结:Context结构复杂,parentContext结构的作用,及如何的去加载bean工厂的逻辑原理。
如果创建的是,ConfigurableWebApplicationContext, 会读loadParentContext
1 2 3 4 5 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 1 2 3 4 5 PropertySource:属性源,key-value属性对抽象,比如用于配置数据 PropertyResolver:属性解析器,用于解析相应key的value Environment:环境,本身是一个PropertyResolver,但是提供了Profile特性,即可以根据环境得到相应数据(即激活不同的Profile,可以得到不同的属性数据,比如用于多环境场景的配置(正式机、测试机、开发机DataSource配置))
2.Environment
1 2 3 Environment接口是Spring对当前程序运行期间的环境的封装(spring)。主要提供了两大功能:profile和property(顶级接口PropertyResolver提供)。目前主要有StandardEnvironment、 开发环境,比如JDK环境,系统环境;每个环境都有自己的配置数据,如System.getProperties()可以拿到JDK环境数据、System.getenv()可以拿到系统变量,ServletContext.getInitParameter()可以拿到Servlet环境配置数据。 Spring抽象了一个Environment来表示Spring应用程序环境配置,它整合了各种各样的外部环境,并且提供统一访问的方法。
1 2 3 4 5 6 7 8 9 10 11 public interface Environment extends PropertyResolver { //得到当前明确激活的剖面 String[] getActiveProfiles(); //得到默认激活的剖面,而不是明确设置激活的 String[] getDefaultProfiles(); //是否接受某些剖面 boolean acceptsProfiles(String... profiles); }
http://img.blog.csdn.net/20160531142913985
1 StandardServletEnvironment和MockEnvironment3种实现,分别代表普通程序、Web程序以及测试程序的环境。通过上述的getOrCreateEnvironment方法处理逻辑也是可以总结出来的。
会读取配置文件如servletConfigInitParams,servletContextInitParams,jdni,系统配置等
StubPropertySource
临时作为一个PropertySource的占位,后期会被真实的PropertySource取代。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 2.环境的装载 public class StandardServletEnvironment extends StandardEnvironment implements ConfigurableWebEnvironment { @Override protected void customizePropertySources(MutablePropertySources propertySources) { propertySources.addLast(new StubPropertySource(SERVLET_CONFIG_PROPERTY_SOURCE_NAME)); //servletConfigInitParams propertySources.addLast(new StubPropertySource(SERVLET_CONTEXT_PROPERTY_SOURCE_NAME)); //servletContextInitParams if (JndiLocatorDelegate.isDefaultJndiEnvironmentAvailable()) { propertySources.addLast(new JndiPropertySource(JNDI_PROPERTY_SOURCE_NAME)); } super.customizePropertySources(propertySources); }
配置文件添加:
MutablePropertySources类中有一个list (PropertySource)如下,配置信息 (PropertySource)add 到这个list当中
1 2 3 public class MutablePropertySources implements PropertySources { private final Log logger; private final List> propertySourceList;
1 2 3 4 5 addFirst:在propertySourceList 头部添加元素。 addLast:在propertySourceList 尾部添加元素。 addAtIndex:在propertySourceList 指定的位置添加元素。
配置信息类:PropertySource 一个 name 和T source,即 key 和源头
1 2 3 4 5 6 7 8 9 public abstract class PropertySource {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); //得到属性名对应的属性值 }
1 2 3 4 5 6 7 8 9 10 11 RandomValuePropertySource:source是random。 ServletConfigPropertySource:source是ServletConfig。 ServletContextPropertySource:source是ServletContext。 JndiPropertySource:source是JndiLocatorDelegate。 StubPropertySource:source是Object。 MapPropertySource:source是Map。
配置信息类 PropertySources
包含多个PropertySource,继承了Iterable接口,所以它的子类还具有迭代的能力。
1 2 3 实现类 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或方法属于哪个剖面 示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 @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"; } @Bean public String str3() { return "str3"; } }
profile:http://www.jianshu.com/p/49e950b0b008
http://blog.csdn.net/u011179993/article/details/51511364
@propertySource
Java Config方式的注解,其属性会自动注册到相应的Environment
1 2 3 4 @Configuration @PropertySource(value = "classpath:resources.properties", ignoreResourceNotFound = false) public class AppConfig { }
综上说明:
1 先添加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