Spring 周边( Environment)

参考:https://blog.csdn.net/sdlyjzh/article/details/79307239

一、体系结构

Environment是一个集成到容器之中的特殊抽象,它针对应用的环境建立了两个关键的概念:profileproperties.

profile是命名好的,其中包含了多个Bean的定义的一个逻辑集合,只有当指定的profile被激活的时候,其中的Bean才会激活。无论是通过XML定义的还是通过注解解析的Bean都可以配置到profile之中。而Environment对象的角色就是跟profile相关联,然后决定来激活哪一个profile,还有哪一个profile为默认的profile。

properties在几乎所有的应用当中都有着重要的作用,当然也可能导致多个数据源:property文件,JVM系统property,系统环境变量,JNDI,servlet上下文参数,ad-hoc属性对象,Map等。Environment对象和property相关联,然后来给开发者一个方便的服务接口来配置这些数据源,并正确解析

下面着重介绍StandardEnviroment和StandardServletEnviroment

二、Environment对properties的处理

         1.StandardEnviroment

protected void customizePropertySources(MutablePropertySources propertySources) {
		propertySources.addLast(new MapPropertySource(SYSTEM_PROPERTIES_PROPERTY_SOURCE_NAME, getSystemProperties()));
		propertySources.addLast(new SystemEnvironmentPropertySource(SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME, getSystemEnvironment()));
	}

将 系统属性 和系统环境变量 保存到 环境中

        2.StandardServletEnviroment

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

1.将 servletConfigInitParams 、servletContextInitParams、jndiProperties保存到环境变量中(这里只是创建了相应对象,无实际内容,真正初始化在StandardServletEnviroment.initPropertySources完成【该方法被ContextLoaderListener调用】,)

2.调用父类StandardEnviroment(将 系统属性 和系统环境变量 保存到 环境中)

三、Environment对profile的处理

StandardEnviroment和StandardServletEnviroment并没有对profile处理,但他们的父类AbstractEnvironment实现了对profile的简单操作

情景描述:

想象这样一种情况,在软件开发的过程中有开发环境和正式环境,他们使用的数据源不同,怎么才能做到无缝切换呢。也就是说怎么让Spring容器在不同的条件下注册不同的Bean。比如说生产环境和测试的环境的数据源


传统做法:

在spring3.0以前我们可以这么做,把这些不同环境的bean定义在不同的xml文件中,然后采用import标签配合PropertySourcesPlaceholderConfigurer导入不同的配置。

如下一个示例:

        <import resource="com/test/dao/dao-${test}.xml" />

上面这个示例要使之工作,需要在spring容器启动之前在System property和环境变量中添加test() 【原因如此.】

1.     带参数启动。启动程序中传入property。如下:

-Dtest=test

2.     在程序中编码添加(需在IOC加载前,或refresh容器)。

Properties pp = System.getProperties();  

pp.put(key, value)


使用profile:

以上的机制的好坏暂且不谈,但是有一点是不同的团队拥有不同的方案,而且配置文件分散,spring的profile提供统一的解决方案。

Profile是<beans>标签的一个属性,定义了一组bean属于同一个profile,如下图:

 <beans profile="qa">
       <bean id="userDao" class="com.test.dao.UserDaoImp">
       </bean>
       <bean id="userDao1" class="com.test.dao.UserDaoImp">
           <qualifier type="com.test.service.MyQualify" value="userMy" />
       </bean>
    </beans>

profile在spring内部由activeProfiles 和defaultProfiles区分,作为成员变量(Map)存在于Environment中

启用profile:

1.     使用代码

context.getEnvironment().setActiveProfiles("test");
context.refresh();

2.     启动时传入参数。

    -Dspring.profiles.active="profile1,profile2"(相当于在system.getProperty添加了k-v)


两种方式对比:

profile相比传统方式 更加细粒度。profile针对于bean,传统方式针对于bean定义文件

 

 

 

 

 

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值