Spring3.1提供了新的属性管理API,而且功能非常强大且很完善,对于一些属性配置信息都应该使用新的API来管理。虽然现在Spring已经到4版本了,这篇文章来的晚点。
新的属性管理API
PropertySource:属性源,key-value属性对抽象,比如用于配置数据
PropertyResolver:属性解析器,用于解析相应key的value
Environment:环境,本身是一个PropertyResolver,但是提供了Profile特性,即可以根据环境得到相应数据(即激活不同的Profile,可以得到不同的属性数据,比如用于多环境场景的配置(正式机、测试机、开发机DataSource配置))
Profile:剖面,只有激活的剖面的组件/配置才会注册到Spring容器,类似于maven中profile
也就是说,新的API主要从配置属性、解析属性、不同环境解析不同的属性、激活哪些组件/配置进行注册这几个方面进行了重新设计,使得API的目的更加清晰,而且功能更加强大。
PropertySource
key-value对,API如下所示:
public String getName() //属性源的名字 public T getSource() //属性源(比如来自Map,那就是一个Map对象) public boolean containsProperty(String name) //是否包含某个属性 public abstract Object getProperty(String name) //得到属性名对应的属性值
非常类似于Map;用例如下:
@Test public void test() throws IOException { Map<String, Object> map = new HashMap<>(); map.put("encoding", "gbk"); PropertySource propertySource1 = new MapPropertySource("map", map); System.out.println(propertySource1.getProperty("encoding")); ResourcePropertySource propertySource2 = new ResourcePropertySource("resource", "classpath:resources.properties"); //name, location System.out.println(propertySource2.getProperty("encoding")); }
MapPropertySource的属性来自于一个Map,而ResourcePropertySource的属性来自于一个properties文件,另外还有如PropertiesPropertySource,其属性来自Properties,ServletContextPropertySource的属性来自ServletContext上下文初始化参数等等,大家可以查找PropertySource的继承层次查找相应实现。
@Test public void test2() throws IOException { //省略propertySource1/propertySource2 CompositePropertySource compositePropertySource = new CompositePropertySource("composite"); compositePropertySource.addPropertySource(propertySource1); compositePropertySource.addPropertySource(propertySource2); System.out.println(compositePropertySource.getProperty("encoding")); }
CompositePropertySource提供了组合PropertySource的功能,查找顺序就是注册顺序。
另外还有一个PropertySources,从名字可以看出其包含多个PropertySource:
public interface PropertySources extends Iterable<PropertySource<?>> { boolean contains(String name); //是否包含某个name的PropertySource PropertySource<?> get(String name); //根据name找到PropertySource }
示例如下:
@Test public void test3() throws IOException { //省略propertySource1/propertySource2 MutablePropertySources propertySources = new MutablePropertySources(); propertySources.addFirst(propertySource1); propertySources.addLast(propertySource2); System.out.println(propertySources.get("resource").getProperty("encoding")); for(PropertySource propertySource : propertySources) { System.out.println(propertySource.getProperty("encoding")); } }
默认提供了一个MutablePropertySources实现,我们可以调用addFirst添加到列表的开头,addLast添加到末尾,另外可以通过addBefore(propertySourceName, propertySource)或addAfter(propertySourceName, propertySource)添加到某个propertySource前面/后面;最后大家可以通过iterator迭代它,然后按照顺序获取属性。
到目前我们已经有属性了,接下来需要更好的API来解析属性了。
PropertyResolver
属性解析器,用来根据名字解析其值等。API如下所示:
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; }
从API上我们已经看出解析器的作用了,具体功能就不要罗嗦了。示例如下:
@Test public void test() throws Exception { //省略propertySources PropertyResolver propertyResolver = new PropertySourcesPropertyResolver(propertySources); System.out.println(propertyResolver.getProperty("encoding")); System.out.println(propertyResolver.getProperty("no", "default")); System.out.println(propertyResolver.resolvePlaceholders("must be encoding ${encoding}")); //输出must be encoding gbk }
从如上示例可以看出其非常简单。另外Environment也继承了PropertyResolver。
Environment
环境,比如JDK环境,Servlet环境,Spring环境等等;每个环境都有自己的配置数据,如System.getProperties()、System.getenv()等可以拿到JDK环境数据;ServletContext.getInitParameter()可以拿到Servlet环境配置数据等等;也就是说Spring抽象了一个Environment来表示环境配置。
public interface Environment extends PropertyResolver {//继承PropertyResolver //得到当前明确激活的剖面 String[] getActiveProfiles(); //得到默认激活的剖面,而不是明确设置激活的 String[] getDefaultProfiles(); //是否接受某些剖面 boolean acceptsProfiles(String... profiles); }
从API上可以看出,除了可以解析相应的属性信息外,还提供了剖面相关的API,目的是: 可以根据剖面有选择的进行注册组件/配置。比如对于不同的环境注册不同的组件/配置(正式机、测试机、开发机等的数据源配置)。它的主要几个实现如下所示:
MockEnvironment:模拟的环境,用于测试时使用;
StandardEnvironment:标准环境,普通Java应用时使用,会自动注册System.getProperties() 和 System.getenv()到环境;
StandardServletEnvironment:标准Servlet环境,其继承了StandardEnvironment,Web应用时使用,除了StandardEnvironment外,会自动注册ServletConfig(DispatcherServlet)、ServletContext及JNDI实例到环境;
除了这些,我们也可以根据需求定义自己的Environment。示例如下:
@Test public void test() { //会自动注册 System.getProperties() 和 System.getenv() Environment environment = new StandardEnvironment(); System.out.println(environment.getProperty("file.encoding")); }
其默认有两个属性:systemProperties(System.getProperties())和systemEnvironment(System.getenv())。
在web环境中首先在web.xml中配置:
<context-param> <param-name>myConfig</param-name> <param-value>hello</param-value> </context-param> <servlet> <servlet-name>spring</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:spring-mvc.xml</param-value> </init-param> </servlet>
使用StandardServletEnvironment加载时,默认除了StandardEnvironment的两个属性外,还有另外三个属性:servletContextInitParams(ServletContext)、servletConfigInitParams(ServletConfig)、jndiProperties(JNDI)。
然后在程序中通过如下代码注入Environment:
@Autowired Environment env;
另外也可以直接使用ApplicationContext.getEnvironment()获取;接着就可以用如下代码获取配置:
System.out.println(env.getProperty("myConfig")); System.out.println(env.getProperty("contextConfigLocation"));
另外我们在运行应用时可以通过-D传入系统参数(System.getProperty()),如java -Ddata=123 com.sishuok.spring3.EnvironmentTest,那么我们可以通过environment.getProperty("data") 获取到。
如果我们拿到的上下文是ConfigurableApplicationContext类型,那么可以:ctx.getEnvironment().getPropertySources() ;然后通过PropertySources再添加自定义的PropertySource。
Profile
profile,剖面,大体意思是:我们程序可能从某几个剖面来执行应用,比如正式机环境、测试机环境、开发机环境等,每个剖面的配置可能不一样(比如开发机可能使用本地的数据库测试,正式机使用正式机的数据库测试)等;因此呢,就需要根据不同的环境选择不同的配置;如果用过maven,maven中就有profile的概念。
profile有两种:
默认的:通过“spring.profiles.default”属性获取,如果没有配置默认值是“default”
明确激活的:通过“spring.profiles.active”获取
查找顺序是:先进性明确激活的匹配,如果没有指定明确激活的(即集合为空)就找默认的;配置属性值从Environment读取。
API请参考Environment部分。设置profile属性,常见的有三种方式:
一、启动Java应用时,通过-D传入系统参数
-Dspring.profiles.active=dev
二、如果是web环境,可以通过上下文初始化参数设置
<context-param> <param-name>spring.profiles.active</param-name> <param-value>dev</param-value> </context-param>
三 、通过自定义添加PropertySource
Map<String, Object> map = new HashMap<String, Object>(); map.put("spring.profiles.active", "dev"); MapPropertySource propertySource = new MapPropertySource("map", map); env.getPropertySources().addFirst(propertySource);
四、直接设置Profile
env.setActiveProfiles("dev", "test");
以上方式都可以设置多个profile,多个之间通过如逗号/分号等分隔。
接着我们就可以通过如下API判断是否激活相应的Profile了:
if(env.acceptsProfiles("dev", "test"))) { //do something }它们之间是或的关系;即找到一个即可;如果有人想不匹配某个profile执行某些事情,可以通过如"!dev" 即没有dev激活时返回true。
当然这种方式还不是太友好,还需要我们手工编程使用,稍候会介绍如何更好的使用它们。
<context:property-placeholder/>
${key}占位符属性替换器,配置如下:
<context:property-placeholder location="属性文件,多个之间逗号分隔" file-encoding="文件编码" ignore-resource-not-found="是否忽略找不到的属性文件" ignore-unresolvable="是否忽略解析不到的属性,如果不忽略,找不到将抛出异常" properties-ref="本地Properties配置" local-override="是否本地覆盖模式,即如果true,那么properties-ref的属性将覆盖location加载的属性,否则相反" system-properties-mode="系统属性模式,默认ENVIRONMENT(表示先找ENVIRONMENT,再找properties-ref/location的),NEVER:表示永远不用ENVIRONMENT的,OVERRIDE类似于ENVIRONMENT" order="顺序" />
相关推荐
在事务管理方面,Spring 3.1 提供了声明式事务管理的增强,支持更多的事务属性,如PROPAGATION_REQUIRES_NEW,使得事务管理更加灵活和精确。 在测试方面,Spring 3.1 提供了更好的测试支持,包括对Spock测试框架的...
Spring 3.1是该框架的一个重要版本,引入了许多新特性,优化了性能,并增强了对Java EE 6的支持。 1. **依赖注入(Dependency Injection, DI)**:Spring的核心特性之一,允许开发者在运行时通过配置文件或注解来...
在这个“最新 spring3.1 完整jar包”中,包含了Spring框架的所有核心组件和其他相关模块,确保了开发环境的完备性。 1. **核心容器**:Spring的核心在于其IoC(Inversion of Control)容器,它负责管理应用对象的...
数据访问是企业级应用的关键部分,Spring 3.1加强了对各种持久化技术的支持,如JDBC、ORM(对象关系映射)框架如Hibernate和MyBatis,以及JPA(Java Persistence API)。在3.1版本中,Spring Data项目提供了对...
在这个"spring3.1 jar全集"中,我们包含了Spring的核心组件和其他关键模块,如AOP(面向切面编程)和Beans模块。 首先,让我们深入了解一下Spring Core。这是Spring框架的基础,提供了依赖注入(DI)和控制反转...
《Spring3.1开发宝典》是一份详尽的指南,专为那些希望深入了解和掌握Spring框架3.1版本的开发者准备。这份宝典不仅涵盖了Spring框架的核心概念,还深入探讨了新特性、增强功能以及如何在实际项目中应用这些知识。 ...
这个"spring3.1完整包"包含了Spring框架的多个核心模块,下面将详细介绍这些模块及其功能。 1. **org.springframework.context-3.1.0.M1.jar**:这是Spring上下文模块,提供了容器的核心功能,包括Bean的定义、配置...
9. **消息支持**:Spring 3.1加强了对消息传递(如JMS)的支持,提供了一套完整的API来处理消息生产和消费。 10. **国际化**:Spring的国际化支持在3.1版本中也有改进,`MessageSource`接口和`@MessageSource`注解...
标题中的“spring3.1需要的jar包”指的是在使用Spring框架版本3.1时所需的外部依赖库。Spring是一个开源的Java平台,它为构建企业级应用提供了全面的框架支持,包括依赖注入(DI),面向切面编程(AOP),以及用于...
Spring 3.1是该框架的一个重要版本,它引入了许多增强功能和优化,提高了开发效率和应用性能。这个压缩包包含了运行Spring 3.1应用程序所需的所有jar文件,确保了环境的完整性和兼容性。 首先,Spring的核心库`...
spring3.1官方所有的jar包 org.springframework.aop-3.1.RELEASE.jar org.springframework.asm-3.1.RELEASE.jar org.springframework.aspects-3.1.RELEASE.jar org.springframework.beans-3.1.RELEASE.jar org....
Spring 3.1 API是Spring框架的一个重要版本,它带来了许多增强特性和改进,旨在提升开发者在企业级Java应用中的编程体验。这个版本的核心目标是提高性能、简化配置以及增加对Java新特性的支持。 首先,Spring 3.1...
在"spring3.1+xfire1.26 全注解"这个项目中,开发者利用Spring 3.1的注解特性来配置和管理应用程序组件,以及XFire 1.26来处理Web服务的创建和交互。全注解意味着不再需要XML配置文件,而是直接在Java类和方法上使用...
Spring Boot的自定义配置属性源(PropertySource)是框架中一个强大的特性,它允许开发者引入额外的配置文件或从各种来源获取配置,以满足不同环境的特定需求。配置覆盖是解决多环境配置问题的一种常见策略,它允许...
在本示例中,我们将深入探讨Spring框架的3.1版本中的核心概念之一:面向切面编程(Aspect-Oriented Programming,简称AOP)。AOP是Spring框架的强大特性,它允许我们在应用程序中实现关注点的分离,使得我们可以将横...
Spring 3.1是Spring框架的一个重要版本,它在企业级Java应用开发中扮演着核心角色。AOP(面向切面编程)是Spring框架的重要特性,允许开发者将关注点分离,比如日志、事务管理等,从核心业务逻辑中解耦出来。本...
内含Struts1.3 API、Struts2.0 API、Struts1.3标签、Hibernate3.1教程、Hibernate3.1API、Spring3.0 API、Spring3.1API。SSH应有尽有,API均是CHM格式,方便使用。教程为pdf格式。
Spring 3.1 GA API CHM版
Spring3.1是一个重要的Java应用程序开发框架,它以其依赖注入(Dependency Injection,DI)和面向切面编程(Aspect-Oriented Programming,AOP)的核心特性而著名。这个压缩包包含了Spring框架3.1版本的所有核心组件...
在本文中,我们将深入探讨如何将Spring MVC 3.1与MyBatis 3.1框架集成,并讨论其中涉及的关键技术,如事务管理、分页和JSON数据交换。此外,我们还将简要提及开发环境中使用的工具,如Eclipse 4.3、Maven 3.0.5和...