Spring框架学习之高级依赖关系配置(二)
紧接着上篇内容,本篇文章将主要介绍XML Schema的简化配置和使用SpEL表达式语言来优化我们的配置文件。
一、基于XML Schema的简化配置方式
从Spring2.0以来,Spring支持使用XML Schema来简化配置。在以前的bean元素配置下,所有的属性注入都需要一个property元素,集合属性就需要更多的这样的元素,一旦项目庞大,整个配置文件将无法维护。XML Schema提供的命名空间,可以帮助我们的配置文件缩减容量。主要有三种命名空间:
- p:命名空间简化属性配置
- c:命名空间简化构造配置
- util:命名空间简化集合配置
1、使用p:命名空间简化配置
首先看一个我们常见的bean的配置:
<bean id="person" class="MyPackage.Person">
<property name="name" value="single"/>
<property name="age" value="22"/>
</bean>
这是一个再普通不过的bean的配置,它等效于:
<bean id="person" class="MyPackage.Person" p:name="single" p:age="22" />
但是这么做的前提是,在Spring配置文件的XML头部导入p的命名空间:
xmlns:p="http://www.springframework.org/schema/p"
无论你是使用IDE自动导入的,还是使用工具,或者自己手动导入的,想要使用p Schema,就必须该命名空间。p是property的缩写,除了可以注入普通的值类型之外,还可以注入引用类型,例如:
<bean id="person" class="MyPackage.Person" p:name-ref="stuName" p:age="22" />
2、使用c:命名空间简化配置
我们使用p命名空间简化了设置注入操作,c命名空间则是constructor的缩写,它用于简化构造注入的操作。例如:
<bean id="person" class="MyPackage.Person" c:name="single" c:age="22" />
Spring最后会调用构造注入,将name和age作为参数出入bean类的构造器中,构造实例返回。除此之外,还可以这么写:
<bean id="person" class="MyPackage.Person" c:_0="single" c:_1="22" />
下划线加上数字表示,这是构造器中的第几个参数,到时候会被Spring按序传入构造器中。
3、使用util命名空间简化配置
util给我们提供了以下几个元素:
- constant:对于在配置文件中获取指定类的静态Field的值的一个简化配置
- property-path:对于在配置文件中获取调用getter方法的一个简化配置
- list:简化list作为bean的配置
- map:简化map作为bean的配置
- set:简化set作为bean的配置
- properties:加载一份properties属性文件
^1、constant
首先看一段我们之前用于获取一个类的静态属性的配置:
<bean id="person" class="MyPackage.Person">
<property name="name" value="single"/>
<property name="age">
<bean class="org.springframework.beans.factory.config.FieldRetrievingFactoryBean">
<property name="targetClass" value="MyPackage.BeanStaticClass"/>
<property name="targetField" value="age"/>
</bean>
</property>
</bean>
这是一段我们之前用于在配置文件中获取类静态属性的代码,总体上来说还是挺繁琐的,下面我们使用util下的constant来简化这段配置。
<bean id="person" class="MyPackage.Person">
<property name="name" value="single"/>
<property name="age">
<util:constant static-field="MyPackage.BeanStaticClass.age"/>
</property>
</bean>
static-field属性的值指定了需要访问那个类下的那个静态属性。如果需要将该值单独定义在容器中,可以为其增加id属性以便其他bean实例获取。
^2、property-path
对于在配置文件中直接调用其他bean的getter方法,我们一般如是配置:
<bean id="student" class="MyPackage.Student">
<property name="age" value="22"/>
</bean>
<bean id="person" class="MyPackage.Person">
<property name="name" value="single"/>
<property name="age">
<bean class="org.springframework.beans.factory.config.PropertyPathFactoryBean">
<property name="targetBeanName" value="student"/>
<property name="propertyPath" value="age"/>
</bean>
</property>
</bean>
一般我们需要这么写来配置,下面我们通过util的property-path来简化配置:
<bean id="student" class="MyPackage.Student">
<property name="age" value="22"/>
</bean>
<bean id="person" class="MyPackage.Person">
<property name="name" value="single"/>
<property name="age">
<util:property-path path="student.age"/>
</property>
</bean>
property-path的值指定了需要调用那个bean实例的那个getter方法。如果需要单独将该值配置在容器中,可以为其指定id。
^3、list
通过util,Spring允许我们单独定义一个list bean在容器中。一个list bean给我们提供如下几个属性:
- id:容器中的唯一标识
- list-class:指定实现该list的实现类,默认为ArrayList
- scope:指定该list的作用域
下面我们定义一个list bean:
<util:list id="list" list-class="java.util.ArrayList">
<value>nanjing</value>
<value>nantong</value>
<value>yancheng</value>
</util:list>
^4、map和set
有关map和set的util使用,基本和list的使用情况类似,此处只给出创建bean的配置代码,其他的不再赘述。
//map
<util:map id="map" map-class="java.util.HashMap">
<entry key="中国银行" value="241241212" />
<entry key="建设银行" value="543534545"/>
</util:map>
//set
<util:set id="set" set-class="java.util.HashSet">
<value>single</value>
<value>cyy</value>
</util:set>
至此,有关XML Schema的基本内容已如上述所述,Spring中还有一些其他相关的Schema文件,它们各自有各自的作用,有用于简化AOP配置的,有用于简化事务配置的等等,我们将在后续文章中进行学习。
二、使用Spring的EL表达式语言
Spring的配置文件有一个非常明显的缺陷,大量的静态注入,动态性不强。而SpEL类似于jsp的EL,采用表达式的方式为属性注入值,当程序动态运行时,这些表达式的值才确定。SpEL可以单独使用,也可以在Spring配置文件中使用,我们此处主要介绍在配置文件中的SpEL的使用。
1、创建数组
有时我们的实例中有类型为数组的属性,那么我们就可以通过SpEL定义数组作为参数注入依赖给该属性。
<bean id="person" class="MyPackage.Person">
<property name="array" value="#{new int[]{12,2,5,7,8,6,8}}" />
</bean>
在Spring配置中使用SpEL中,基本的使用格式如下:
#{expression}
2、创建list集合
我们也可以使用SpEL定义list集合,例如:
<bean id="person" class="MyPackage.Person">
<property name="list" value="#{{'single','cyy','xijingping'}}"/>
</bean>
list集合的定义使用 "{....}",大括号中的每个元素都对应于list中的一个元素。
我们可以通过以下语法格式访问list中的元素:
listName[index]
访问容器中map集合中的元素:
mapName[key]
例如:
<bean id="person" class="MyPackage.Person">
<property name="name" value="#{list[0]}"/>
</bean>
这段配置会向person实例中的name属性注入容器中已经定义好的名为list的第一个元素的值。
3、调用方法
在SpEL中调用任意方法将会比我们之前介绍的那种纯配置形式简单很多,例如:
<bean id="person" class="MyPackage.Person">
<property name="name" value="#{'hello'.concat(' world!')}"/>
</bean>
我们这里调用了jdk中的方法为person实例的name属性注入依赖值,当然也可以是我们自己定义的方法,可以是任意的方法。
4、类运算符
SpEL提供了一种运算符:T()。该运算符告诉Spring将括号中的内容作为一类类型而不是作为字符串进行解析。例如:
<bean id="person" class="MyPackage.Person">
<property name="name" value="#{java.lang.Math.random()}"/>
</bean>
这样书写,Java会给我们报错,说java.lang.Math.random()并不是一个字符串,但是如果给他加上单引号,那么该函数就会以纯字符串作为参数注入给name属性,并不会被识别为正常函数。
正确书写格式如下:
<bean id="person" class="MyPackage.Person">
<property name="name" value="#{T(java.lang.Math).random()}"/>
</bean>
5、集合选择
使用SpEL集合选择的基本格式如下:
collection.?[condition_expr]
只有符合条件condition_expr的集合元素才会被选择出来,例如:
<bean id="person" class="MyPackage.Person">
<property name="list" value="#{list.?[length()>7]}"/>
</bean>
Spring会遍历整个list,每个元素都会调用他的length方法判断是否大于7,如果不是将舍弃该元素,否则该元素才会被帅选出来。
6、集合投影
集合投影可以让集合中的每个元素都去执行同一个方法,每个元素调用同一个方法,不同元素的该方法的返回值将构成最终的新集合。例如:
<bean id="person" class="MyPackage.Person">
<property name="list" value="#{list.![length()]}"/>
</bean>
最终新集合中的元素是原集合中每个元素的长度。
SpEL的用法远非如此,这里只是列举了常用的几种用法。
两篇文章加强了对bean配置的理解,有总结不到之处,望指出!
Spring框架学习之高级依赖关系配置(二)的更多相关文章
- Spring框架学习之高级依赖关系配置(一)
上篇文章我们对Spring做了初步的学习,了解了基本的依赖注入思想.学会简单的配置bean.能够使用Spring容器管理我们的bean实例等.但这还只是相对较浅显的内容,本篇将介绍bean的相关更高级 ...
- spring-第九篇之高级依赖关系配置
1.关于配置文件一些使用 组件与组件之间的耦合,采用依赖注入管理:基本类型的成员变量值,应该直接在代码中设置. 2.获取其他bean的属性值 PorpertyPathFactoryBean用来获取目标 ...
- Spring框架学习笔记(3)——配置bean
1.属性注入 (1)根据setter方法属性注入,这里使用的是property标签.需要bean属性提供对应的setter方法,比如笔记(1)里的 HelloWorld使用的就是这种方法. <! ...
- Spring框架学习笔记(4)——配置bean more
1.配置List属性 <!-- 配置List属性 --> <bean id="person4" class="com.broadtext.beans.c ...
- Spring框架学习之注解配置与AOP思想
上篇我们介绍了Spring中有关高级依赖关系配置的内容,也可以调用任意方法的返回值作为属性注入的值,它解决了Spring配置文件的动态性不足的缺点.而本篇,我们将介绍Spring的又一大核心 ...
- Spring框架学习一
Spring框架学习,转自http://blog.csdn.net/lishuangzhe7047/article/details/20740209 Spring框架学习(一) 1.什么是Spring ...
- Spring框架学习1
AnonymouL 兴之所至,心之所安;尽其在我,顺其自然 新随笔 管理 Spring框架学习(一) 阅读目录 一. spring概述 核心容器: Spring 上下文: Spring AOP ...
- Spring框架学习之IOC(一)
Spring框架学习之IOC(一) 先前粗浅地学过Spring框架,但当时忙于考试及后期实习未将其记录,于是趁着最近还有几天的空闲时间,将其稍微整理一下,以备后期查看. Spring相关知识 spri ...
- Spring框架学习笔记(5)——Spring Boot创建与使用
Spring Boot可以更为方便地搭建一个Web系统,之后服务器上部署也较为方便 创建Spring boot项目 1. 使用IDEA创建项目 2. 修改groupid和artifact 3. 一路n ...
随机推荐
- Download the Hibernate Tools
首先去官网上下载最新版本的Hibernate Tools JBoss Tools 4.5.0.Final Requirements: Java 8 and Eclipse Oxygen 4.7 有 4 ...
- vim下处理文档中的\r\n\t字符
问题复现 拿到的文档中包含了大量的\r.\n.\t等字符,形如: \r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\ ...
- SQL性能优化十条经验(转)
1.查询的模糊匹配 尽量避免在一个复杂查询里面使用 LIKE '%parm1%'-- 红色标识位置的百分号会导致相关列的索引无法使用,最好不要用. 解决办法: 其实只需要对该脚本略做改进,查询速度便会 ...
- C的函数指针与指针函数
1.函数指针 指向函数的指针.本质是一个指针. 指针变量可以指向变量的地址.数组.字符串.动态分配地址,同时也可指向一个函数,每个函数在编译的时候,系统会分配给该函数一个入口地址,函数名表示这个入口地 ...
- jsonp其实很简单【ajax跨域请求】
js便签笔记(13)——jsonp其实很简单[ajax跨域请求] 前两天被问到ajax跨域如何解决,还真被问住了,光知道有个什么jsonp,迷迷糊糊的没有说上来.抱着有问题必须解决的态度,我看了许多资 ...
- 集 降噪 美颜 虚化 增强 为一体的极速图像润色算法 附Demo程序
在2015年8月份的时候,决心学习图像算法. 几乎把当时市面上的图像算法相关书籍都看了一遍, 资金有限,采取淘宝买二手书,长期驻留深圳图书馆的做法, 进度总是很慢,学习算法不得其法. 虽然把手上所有书 ...
- 技术领导(Technical Leader)画像
程序员都讨厌被管理,而乐于被领导.管理的角色由PM(project manager)扮演,具体来说,PM负责提需求.改改改.大多数情况,PM是不懂技术的,这也是程序员觉得PM难以沟通的原因.而后者由技 ...
- “一切都是消息”--MSF(消息服务框架)之【请求-响应】模式
在前一篇, “一切都是消息”--MSF(消息服务框架)入门简介, 我们介绍了MSF基于异步通信,支持请求-响应通信模式和发布-订阅通信模式,并且介绍了如何获取MSF.今天,我们来看看如何使用MSF来做 ...
- HDU3336 Count the string
居然一A了,说明对朴素的KMP还是有一定理解. 主要就是要知道next数组的作用,然后就可以计算每个i结尾的满足题意的串个数. #include<cstdio> #include<c ...
- Kvm虚拟化的一种打包及部署方案(采用tar包,lvm方式)
Kvm虚拟化的一种打包部署方案(采用tar包,lvm方式) –-–-–-2016年终总结 一 毕业之后跟师兄学到的第一块主要内容,理解花了不少时间.期间经历了shell的入门.linux基础知识入门. ...