Spring3表达式语言(SpEL)学习笔记
最新地址请访问:http://leeyee.github.io/blog/2011/06/19/spring-expression-language
Spring Excpression Language (SpEL)语言支持在运行时操作和查询对象,其语法类似统一的EL语言,但是SpEL提供了额外的功能。
1、文本表达式
2、布尔类和关系操作
3、正则表达式
4、类表达式
5、访问属性、数组、集合和map
6、方法调用
7、关系操作
8、赋值操作
9、调用构造函数
10、Bean 引用
11、数组构造
12、内联list
13、三元操作
14、变量
15、用户自定义函数
16、集合投影
17、集合选择
18、模板表达式
使用SpEl进行表达式操作,基本操作如下:
第一步,构建解析
- ExpressionParser parser = new SpelExpressionParser();
第二步,使用表达式进行解析
- Expression exp = parser.parseExpression( SpEl);
第三步,获取结果
- exp.getValue()
2.1 文本表达式
文本表达式支持字符表达式、日期、数字(正数、实数及十六进制数)、布尔类型及null.其中字符表达式需要用单引号声明。
对数字支持负数、指数及小数。默认情况下实数使用Double.parseDouble() 进行表达式类型转换
2.2 属性、数组、列表、字典(map)及索引
在表达式中访问类属性时直接使用属性名,属性名首字母大小写均可。
访问数组时可以使用[index]进行元素对象范围。
访问列表时,可直接使用类表的方法,通过点操作符
2.3 内置列表
列表可以直接表示在表达式中使用{}符号表达。{}本身代表一个空的list
2.4 数组构造(spring3.0.3中会抛出异常)
可以通过熟悉的java语法在表达是语言中定义。但目前不支持定义一个初始化的多维数组
2.5 方法
表达式中的方法调用遵循java语法。
2.6 操作符
2.6.1 关系操作符
支持 eq("=="),ne("!="),le("<="),lt("<"),gt(">"),ge(">="),div("/"),mod("%"),not("!"),正则表达式及instanceof操作
2.6.2 逻辑操作符
逻辑操作符支持and,or,not
2.6.3 数学运算操作符
加法运算符可以用于数字,字符串和日期。减法可以用在数字和日期。乘法和除法只能用于对数字。其他受支持的数学运算是模数(%)和指数幂(^)。运行顺序按标准运算符优先级执行
2.7 赋值
通过赋值操作进行属性设置。通常是调用setValue方法,但也可以在调用getValue时设置。
2.8 类型
通过特殊的'T'操作符可以用来指定一个java.lang.Class的实例。在实例话对象的静态方法将会被调用。
2.9 构造器
构造器通过new操作被调用。在new操作时需要指明类的完全类名(包括包路径)
2.10 变量
变量可以通过 #变量名 在表达式中被引用。变量通过StandardEvaluationContext类的setVariable方法进行设置
2.10.1 #this变量
变量 #this 被定义为当前操作对象的引用。
2.11 函数
你可以扩展SpEL通过注册自定义函数。注册后的函数可以在表达式中通过其名称进行调用。函数的注册是通过StandardEvaluationContext类的registerFunction方法进行声明
2.12 三元操作
2.13 Elvis操作
Elvis操作是一个短的三元操作符语法,通常在Groovy语言中使用。
Note: Elvis操作在表达式中可以用来生成默认值,当被访问属性为空时。比如@Value
@Value("#systemPro['mail.port'] ? : 25}") //当mail.port为空时将默认为25
2.14 安全导航操作
该操作是为避免空指针异常。他是来自Groovy语言的。典型的当你有一个指向对象的引用,在你访问其方法或属性时,可能需要验证该对象的方法或属性是否为空,为了避免验证,使用安全导航操作将简单的返回null而不是空指针异常。
2.15 集合选择
选择是一个强大的表达式语言属性,可以使用选择表达式过滤源集合,从而生成一个新的符合选择条件的集合
选择的语法为 ?[selectionExpression] 。他将过滤集合并且返回一个新的集合(原集合的子集)。
选择语句也可用在Map中,过滤keySet及valueSet分别使用key和value关键字
另外:选择语法中,选择符合条件的结果集的第一个元素的语法为 ^[selectionExpression],选择最后一个元素的语法为$[selectionExpression]
2.16 集合投影
语法 ![projectionExpression] 判断集合中每个元素是否符合语法要求
2.17 表达式模板
表达式模板允许混合文字表达式,一个或多个值计算块。每一个值计算块被声明通过可被自定义的前缀和后缀,一般选择使用 #{}作为一个定界符。
------------ 以上就是SpEL的简单介绍。下面直接给出测试用例,这样比较直观,也易于理解。 ------------
pom.xml
- <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <groupId>study.spring3</groupId>
- <artifactId>study-spring3</artifactId>
- <version>0.0.1-SNAPSHOT</version>
- <dependencies>
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-context</artifactId>
- <version>3.0.5.RELEASE</version>
- <scope>runtime</scope>
- <exclusions>
- <exclusion>
- <groupId>commons-logging</groupId>
- <artifactId>commons-logging</artifactId>
- </exclusion>
- </exclusions>
- </dependency>
- <dependency>
- <groupId>org.slf4j</groupId>
- <artifactId>slf4j-api</artifactId>
- <version>1.5.8</version>
- <scope>runtime</scope>
- </dependency>
- <dependency>
- <groupId>org.slf4j</groupId>
- <artifactId>slf4j-log4j12</artifactId>
- <version>1.5.8</version>
- <scope>runtime</scope>
- </dependency>
- <dependency>
- <groupId>log4j</groupId>
- <artifactId>log4j</artifactId>
- <version>1.2.14</version>
- <scope>runtime</scope>
- </dependency>
- <dependency>
- <groupId>junit</groupId>
- <artifactId>junit</artifactId>
- <version>4.8.1</version>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>commons-logging</groupId>
- <artifactId>commons-logging</artifactId>
- <version>1.1.1</version>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>javax.inject</groupId>
- <artifactId>javax.inject</artifactId>
- <version>1</version>
- <scope>runtime</scope>
- </dependency>
- <dependency>
- <groupId>cglib</groupId>
- <artifactId>cglib</artifactId>
- <version>2.1_3</version>
- <scope>runtime</scope>
- </dependency>
- </dependencies>
- </project>
spring-beans.xml
- <?xml version="1.0" encoding="UTF-8"?>
- <beans xmlns="http://www.springframework.org/schema/beans"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
- xmlns:p="http://www.springframework.org/schema/p"
- xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
- http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">
- <!-- 容器注解扫描 -->
- <context:component-scan base-package="study.spring.beans" />
- <bean id="sputil" name="sputil" class="study.spring.beans.SpElUtil">
- <property name="time" value="#{ new java.util.Date()}" />
- <property name="name" value="#{'override'}" />
- <property name="maps">
- <map>
- <entry key="1" value="string1" />
- <entry key="2" value="string2" />
- <entry key="3" value="string3" />
- <entry key="4" value="String4" />
- </map>
- </property>
- </bean>
- </beans>
ApplicationContextFactory.java
- package study.spring.context.factory;
- import org.springframework.context.ApplicationContext;
- import org.springframework.context.support.ClassPathXmlApplicationContext;
- public class ApplicationContextFactory {
- private static ApplicationContext ctx;
- private ApplicationContextFactory() {
- }
- public static ApplicationContext createInstance() {
- if (ctx == null) {
- ctx = new ClassPathXmlApplicationContext(
- new String[] { "spring-beans.xml" });
- }
- return ctx;
- }
- }
SpElUtil.java
- package study.spring.beans;
- import java.util.Date;
- import java.util.List;
- import java.util.Map;
- import org.springframework.expression.Expression;
- import org.springframework.expression.ExpressionParser;
- import org.springframework.expression.spel.standard.SpelExpressionParser;
- public class SpElUtil {
- private Date time;
- private String name;
- private SpelTestInnerClass innerClass = new SpelTestInnerClass(
- "innerClass", 29);
- private List<Integer> numbers;
- private Map<Integer, String> maps;
- public static Object sayHelloForSpEl(String express) {
- ExpressionParser exp = new SpelExpressionParser();
- Expression ex = exp.parseExpression(express);
- return ex.getValue();
- }
- /**
- * 自定义方法
- *
- * @param string
- * @return
- */
- public static int len(String string) {
- return string.length();
- }
- public Map<Integer, String> getMaps() {
- return maps;
- }
- public void setMaps(Map<Integer, String> maps) {
- this.maps = maps;
- }
- public List<Integer> getNumbers() {
- return numbers;
- }
- public void setNumbers(List<Integer> numbers) {
- this.numbers = numbers;
- }
- public Date getTime() {
- return time;
- }
- public void setTime(Date time) {
- this.time = time;
- }
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- public SpelTestInnerClass getInnerClass() {
- return innerClass;
- }
- public void setInnerClass(SpelTestInnerClass innerClass) {
- this.innerClass = innerClass;
- }
- }
- class SpelTestInnerClass {
- private String name;
- private int age;
- public SpelTestInnerClass(String name, int age) {
- this.name = name;
- this.age = age;
- }
- public boolean isGt30ForAge() {
- return this.age > 30 ? true : false;
- }
- public String getName() {
- return name;
- }
- public int getAge() {
- return age;
- }
- public void setAge(int age) {
- this.age = age;
- }
- }
SpElUtilTest.java
- package study.spring.beans;
- import static org.junit.Assert.*;
- import java.util.ArrayList;
- import java.util.Arrays;
- import java.util.Date;
- import java.util.HashMap;
- import java.util.List;
- import java.util.Map;
- import org.junit.After;
- import org.junit.Before;
- import org.junit.Test;
- import org.springframework.context.ApplicationContext;
- import org.springframework.expression.Expression;
- import org.springframework.expression.ExpressionParser;
- import org.springframework.expression.common.TemplateParserContext;
- import org.springframework.expression.spel.standard.SpelExpressionParser;
- import org.springframework.expression.spel.support.StandardEvaluationContext;
- import study.spring.context.factory.ApplicationContextFactory;
- public class SpElUtilTest {
- // spring配置文件上下文
- ApplicationContext context = null;
- // spring el测试辅助类
- SpElUtil spel = null;
- // 表达式解析对象
- ExpressionParser exp = null;
- // 标准赋值上下文
- StandardEvaluationContext secontext;
- @Before
- public void setUp() throws Exception {
- context = ApplicationContextFactory.createInstance();
- spel = context.getBean(SpElUtil.class);
- secontext = new StandardEvaluationContext(spel);
- exp = new SpelExpressionParser();
- }
- @After
- public void tearDown() throws Exception {
- context = null;
- spel = null;
- secontext = null;
- exp = null;
- }
- /**
- * 文字表达式测试用例
- *
- * @throws Exception
- */
- @Test
- public void testSpELLiteralExpression() throws Exception {
- // 定义各种文字表达式
- String[] lELs = { "'hello SpEL'", "1.028E+7", "0x12EF", "true", "null" };
- assertEquals("hello SpEL",
- exp.parseExpression(lELs[0]).getValue(String.class));
- assertEquals(new Double(10280000), exp.parseExpression(lELs[1])
- .getValue(Double.class));
- assertEquals(new Integer(4847),
- exp.parseExpression(lELs[2]).getValue(Integer.class));
- assertTrue(exp.parseExpression(lELs[3]).getValue(Boolean.class));
- assertNull(exp.parseExpression(lELs[4]).getValue());
- }
- /**
- * 访问属性、数组、集合和 map 测试
- *
- * @throws Exception
- */
- @Test
- public void testSpELProOrArrayOrIndexEtcExpression() throws Exception {
- // 属性测试。time为SpElUtil类Date型数据,这里调用Date的属性Year
- assertEquals(new Integer(2011), exp.parseExpression("time.Year + 1900")
- .getValue(secontext, Integer.class));
- // 属性测试。innerClass为SpElUtil类中引入的其他类。
- assertEquals(29,
- exp.parseExpression("innerClass.age").getValue(secontext));
- // 设置SpElUtil类的numbers属性
- spel.setNumbers(Arrays.asList(2, 3, 4, 5, 6, 7, 9));
- // 访问对象属性数组通过索引
- assertEquals(2, exp.parseExpression("numbers[0]").getValue(secontext));
- // 访问map
- assertEquals("string1",
- exp.parseExpression("maps[1]")
- .getValue(secontext, String.class));
- }
- /**
- * 内联list测试
- *
- * @throws Exception
- */
- @SuppressWarnings({ "unchecked", "rawtypes" })
- @Test
- public void testSpELInnerListExpression() throws Exception {
- // 构造list
- List<String> nums = (List<String>) exp.parseExpression(
- "{'a','b','c','d'}").getValue();
- assertEquals(Arrays.asList("a", "b", "c", "d"), nums);
- // 构造List<List<>>
- List listOfLists = (List) exp.parseExpression("{{1,2},{3,4}}")
- .getValue(secontext);
- assertEquals(Arrays.asList(1, 2), listOfLists.get(0));
- }
- /**
- * Array 构造测试
- *
- * @throws Exception
- */
- @Test
- public void testSpELArrayConstructionExcpression() throws Exception {
- // 创建没有初始值的数组
- int[] a = (int[]) exp.parseExpression("new int[4]").getValue();
- assertEquals(4, a.length);
- // 创建带有初始值的数组
- int[] b = (int[]) exp.parseExpression("new int[4]{1,2,3,4}").getValue();
- assertEquals(3, b[2]);
- // 创建二维数组
- int[][] c = (int[][]) exp.parseExpression("new int[4][5]").getValue();
- assertEquals(4, c.length);
- assertEquals(5, c[0].length);
- }
- /**
- * 方法表达式测试
- *
- * @throws Exception
- */
- @Test
- public void testSpELMethodExcpression() throws Exception {
- // String.replace方法测试
- assertEquals(
- "abC2def",
- exp.parseExpression("'abcdef'.replace('c','C2')").getValue(
- String.class));
- // 自定义类方法测试
- assertFalse(exp.parseExpression("innerClass.isGt30ForAge()").getValue(
- secontext, Boolean.class));
- spel.getInnerClass().setAge(34);
- assertTrue(exp.parseExpression("innerClass.isGt30ForAge()").getValue(
- secontext, Boolean.class));
- }
- /**
- * 操作符、正则表达式测试
- *
- * @throws Exception
- */
- @Test
- public void testSpElOperatorAndRegExpression() throws Exception {
- // 关系操作
- assertTrue(exp.parseExpression("1 == 1").getValue(Boolean.class));
- assertTrue(exp.parseExpression("1 eq 1").getValue(Boolean.class));
- assertTrue(exp.parseExpression("1 > -1").getValue(Boolean.class));
- assertTrue(exp.parseExpression("1 gt -1").getValue(Boolean.class));
- assertTrue(exp.parseExpression("'a' < 'b'").getValue(Boolean.class));
- assertTrue(exp.parseExpression("'a' lt 'b'").getValue(Boolean.class));
- assertTrue(exp.parseExpression(
- " new Integer(123) instanceof T(Integer) ").getValue(
- Boolean.class));
- assertTrue(exp.parseExpression("'5.00' matches '^-?//d+(//.//d{2})?$'")
- .getValue(Boolean.class));
- // 逻辑操作
- assertTrue(exp.parseExpression("true and true").getValue(Boolean.class));
- assertTrue(exp.parseExpression("true or false").getValue(Boolean.class));
- assertFalse(exp.parseExpression("innerClass.isGt30ForAge() and false ")
- .getValue(secontext, Boolean.class));
- assertFalse(exp.parseExpression("!innerClass.isGt30ForAge() and true ")
- .getValue(secontext, Boolean.class));
- assertTrue(exp.parseExpression("!false").getValue(Boolean.class));
- // 运算操作
- assertEquals(2, exp.parseExpression("1 + 1").getValue());
- assertEquals("ABab",
- exp.parseExpression("'AB' + 'ab'").getValue(String.class));
- assertEquals(25.0,
- exp.parseExpression("1 + 2 * 8 div 4 mod 2 + 2 ^ 3 * 3e0")
- .getValue());
- assertEquals(exp.parseExpression("1 + 2 * 8 / 4 % 2 + 2 ^ 3 ")
- .getValue(),
- exp.parseExpression("1 + 2 * 8 div 4 mod 2 + 2 ^ 3 ")
- .getValue());
- }
- /**
- * 赋值表达式测试
- *
- * @throws Exception
- */
- @SuppressWarnings("deprecation")
- @Test
- public void testSpelAssignmentExpression() throws Exception {
- Date oldDate = spel.getTime();// 获取当前time属性值
- exp.parseExpression("time").setValue(secontext, new Date(113, 2, 25)); // 为time属性重新赋值
- Date newDate = spel.getTime();// 获取赋值后的time属性值
- assertEquals(2013,
- exp.parseExpression("time.Year + 1900").getValue(secontext));
- assertNotSame(oldDate, newDate);
- // 或者使用下属方法赋值
- assertEquals("abc",
- exp.parseExpression("Name = 'abc'").getValue(secontext));
- // 还原time默认,避免后续测试错误
- spel.setTime(oldDate);
- spel.setName("override");
- }
- /**
- * 类型操作表达式测试
- *
- * @throws Exception
- */
- @SuppressWarnings("rawtypes")
- @Test
- public void testSpelTypesExpression() throws Exception {
- Class dateClass = exp.parseExpression("T(java.util.Date)").getValue(
- Class.class);
- assertEquals("java.util.Date", dateClass.getName());
- assertTrue(exp
- .parseExpression(
- "T(java.math.RoundingMode).CEILING < T(java.math.RoundingMode).FLOOR")
- .getValue(Boolean.class));
- }
- /**
- * 构造函数调用测试
- *
- * @throws Exception
- */
- @Test
- public void testSpelConstructorsExpression() throws Exception {
- SpelTestInnerClass spt = exp
- .parseExpression(
- "new study.spring.beans.SpelTestInnerClass('constructTest',23)")
- .getValue(SpelTestInnerClass.class);
- assertEquals(23, spt.getAge());
- assertEquals("constructTest", spt.getName());
- }
- /**
- * 设置变量测试
- *
- * @throws Exception
- */
- @SuppressWarnings("unchecked")
- @Test
- public void testSpelVariablesExpression() throws Exception {
- List<Integer> list = new ArrayList<Integer>();
- list.addAll(Arrays.asList(2, 3, 4, 5, 6, 7, 9));
- secontext.setVariable("list", list);
- List<Integer> vList = (List<Integer>) exp.parseExpression("#list")
- .getValue(secontext);
- assertEquals(vList, list);
- List<Integer> nums = (List<Integer>) exp.parseExpression(
- "#list.?[#this >5]").getValue(secontext); // 获取值大于5的元素集合
- assertEquals(nums, Arrays.asList(6, 7, 9));
- }
- /**
- * 自定义函数表达式测试
- *
- * @throws Exception
- */
- @Test
- public void testSpelFunctionExpression() throws Exception {
- StandardEvaluationContext context = new StandardEvaluationContext();
- context.registerFunction("len", SpElUtil.class.getDeclaredMethod("len",
- new Class[] { String.class }));
- assertEquals(3, exp.parseExpression("#len('abc')").getValue(context));
- }
- @Test
- public void testSpelBeanExpression() throws Exception {
- }
- /**
- * 三元操作测试
- *
- * @throws Exception
- */
- @Test
- public void testSpelTernaryOperatorExpression() throws Exception {
- assertTrue(exp.parseExpression(" true ? true :false").getValue(
- Boolean.class));
- assertEquals("is true",
- exp.parseExpression(" 1 == 1 ? 'is true' :'is false'")
- .getValue(String.class));
- }
- /**
- * Elvis 操作测试
- *
- * @throws Exception
- */
- @Test
- public void testSpeleElvisOperatorExpression() throws Exception {
- Expression ex = exp.parseExpression("name?:'name is null'");
- assertEquals("override", ex.getValue(secontext, String.class));
- spel.setName(null);
- assertEquals("name is null", ex.getValue(secontext, String.class));
- spel.setName("override");
- }
- /**
- * 安全导航操作测试
- *
- * @throws Exception
- */
- @Test
- public void testSpelSafeNavOperatorExpression() throws Exception {
- assertEquals("innerClass", exp.parseExpression("innerClass?.name")
- .getValue(secontext, String.class));
- spel.setInnerClass(null);
- // 使用这种表达式可以避免抛出空指针异常
- assertNull(exp.parseExpression("innerClass?.name").getValue(secontext,
- String.class));
- }
- /**
- * 集合选择表达式测试
- *
- * @throws Exception
- */
- @SuppressWarnings("unchecked")
- @Test
- public void testSpelCollectionSelectExpression() throws Exception {
- spel.setNumbers(Arrays.asList(2, 3, 4, 5, 6, 7, 9));
- List<Integer> nums = (List<Integer>) exp.parseExpression(
- "numbers.?[#this >5]").getValue(secontext);
- assertEquals(nums, Arrays.asList(6, 7, 9));
- // 获取第一个元素
- assertEquals(6,
- exp.parseExpression("numbers.^[#this > 5]").getValue(secontext));
- // 获取最后一个元素
- assertEquals(9,
- exp.parseExpression("numbers.$[#this > 5]").getValue(secontext));
- Map<Integer, String> maps = (Map<Integer, String>) exp.parseExpression(
- "maps.?[value == 'string3' ]").getValue(secontext);
- Map<Integer, String> tmap = new HashMap<Integer, String>();
- tmap.put(3, "string3");
- assertEquals(maps, tmap);
- Map<Integer, String> mapk = (Map<Integer, String>) exp.parseExpression(
- "maps.?[key > 2 and key < 4 ]").getValue(secontext);
- assertEquals(mapk, tmap);
- }
- /**
- * 投影表达式测试
- *
- * @throws Exception
- */
- @SuppressWarnings("unchecked")
- @Test
- public void testSpelProjectionExpression() throws Exception {
- spel.setNumbers(Arrays.asList(2, 3, 4, 5, 6));
- assertEquals(Arrays.asList(5, 6, 7, 8, 9),
- exp.parseExpression("numbers.![#this+3]").getValue(secontext));
- List<Integer> keys = (List<Integer>) exp.parseExpression("maps.![key]")
- .getValue(secontext);
- assertEquals(keys, Arrays.asList(1, 2, 3, 4));
- List<String> mapv = (List<String>) exp.parseExpression("maps.![value]")
- .getValue(secontext);
- assertEquals(mapv,
- Arrays.asList("string1", "string2", "string3", "String4"));
- List<Boolean> mapK = (List<Boolean>) exp.parseExpression(
- "maps.![key > 2 and value !='String4']").getValue(secontext);
- assertEquals(mapK, Arrays.asList(false, false, true, false));
- }
- /**
- * 模板语言测试
- *
- * @throws Exception
- */
- @Test
- public void testSpelTemplate() throws Exception {
- assertEquals(
- " this is a test 4",
- exp.parseExpression(" this is a test #{ maps.![key].get(3)}",
- new TemplateParserContext()).getValue(secontext,
- String.class));
- }
- }
Spring3表达式语言(SpEL)学习笔记的更多相关文章
- spring3表达式语言(SpEL)
使用SpEl进行表达式操作,基本操作如下: <!--第一步,构建解析 --> ExpressionParser parser = new SpelExpressionParser(); & ...
- Spring3 表达式语言(SpEL)介绍
转载自:http://iyiguo.net/blog/2011/06/19/spring-expression-language/ 下一版本 项目需要使用到SpEL ,做一个保存.
- Sping表达式语言--SpEL
Spring表达式语言---SpEL 是一个支持运行时查询和操作对象的强大的表达式语言 语法类似于EL:SpEL使用#{...}作为定界符,所有在大括号中的字符都将被认为是SpEL SpEL为bean ...
- 7 -- Spring的基本用法 -- 12... Spring 3.0 提供的表达式语言(SpEL)
7.12 Spring 3.0 提供的表达式语言(SpEL) Spring表达式语言(简称SpEL)是一种与JSP 2 的EL功能类似的表达式语言,它可以在运行时查询和操作对象图.支持方法调用和基本字 ...
- # C语言假期学习笔记——6
C语言假期学习笔记--6 数组 主要学习了一位数组和二维数组. 数组是一组具有相同类型的变量的集合.C语言程序通过元素的下标来访问数组中的元素.(下标从0开始) 一位数组 类型 数组名[元素个数] 二 ...
- R语言可视化学习笔记之添加p-value和显著性标记
R语言可视化学习笔记之添加p-value和显著性标记 http://www.jianshu.com/p/b7274afff14f?from=timeline 上篇文章中提了一下如何通过ggpubr ...
- Spring学习笔记--Spring表达式语言SpEL
Spring3引入了Spring表达式语言(Spring Expression Language,SpEL).SpEL是一种强大的.简洁的装配Bean的方式,它通过运行期执行的表达式将值装配到Bean ...
- Spring学习记录(七)---表达式语言-SpEL
SpEL---Spring Expression Language:是一个支持运行时查询和操作对象图表达式语言.使用#{...}作为定界符,为bean属性动态赋值提供了便利. ①对于普通的赋值,用Sp ...
- Spring表达式语言SpEL简单介绍
Spring3引入了Spring表达式语言(Spring Expression Language,SpEL). SpEL有非常多特性.比較经常使用的包含: 1.使用bean的id来引用bean, 以下 ...
随机推荐
- 最全的LBS手机定位技术说明
随着手机技术的发展定位方式也发生了非常大的变化.获取手机位置有非常多种方式. 第一种:CELL-ID定位原理 通过移动网络获取设备当前所在的Cell信息来获取设备当前位置.当设备位置更新设备会向当前服 ...
- Failed to load the JNI shared library
解决Eclipse无法打开"Failed to load the JNI shared library" 这是由于JDK配置错误所导致的现象. 一般说来,新购笔记本会预装64位的w ...
- VC问题 IntelliSense:“没有可用的附加信息”,[请参见“C++项目 IntelliSense 疑难解答”,获得进一步的帮助]
当出现以上的问题时,若按照网上所说的解决方法: 1.安装VA(Visual_AssistX) 2.安装Microsoft SQL Server Compact 3.5 3.更改设置“工具-选项-文本编 ...
- ThinkPHP - Widget 工具
提出问题:widget能实现什么功能? 显示右侧博文: 1.首先在Home目录下新建Widget文件夹,之后建立对应文件 2.拿最热Hot新闻来举例: 在Tpl目录下Common公共文件夹里的righ ...
- [POJ 1521]--Entropy(哈夫曼树)
题目链接:http://poj.org/problem?id=1521 Entropy Time Limit: 1000MS Memory Limit: 10000K Description A ...
- Android 开发 AirPlay Server
安卓上开发 AirPlay Server 主要是参考了和修改了 DroidAirPlay项目 , 和Airplay 协议 1, 将DroidAirPlay 下载下来 2, Eclipse 新建一个 ...
- Android 应用内HttpClient 与 WebView 共享 Cookie
DefaultHttpClient httpclient=....; String toUrl="https://cap.cityu.edu.hk/studentlan/details.as ...
- Linux 开放服务端口
CentOS 6.5上安装Tomcat 服务器,需要开放服务端口,供其他计算机访问部署在Tomcat中的Web应用.下面是开放端口的方法. 我知道的方法有两种.下面以开放8080端口为例. 方法一:命 ...
- Web Application的目录结构
Java web工程下的webapp或WebContent就是工程的发布文件夹,发布时会把该文件夹发布到tomcat的webapps里. 一个web应用必须要有的目录文件如下: webapp/WebC ...
- 为什么要用BASE64
BASE64和其他相似的编码算法通常用于转换二进制数据为文本数据,其目的是为了简化存储或传输.更具体地说,BASE64算法主要用于转换二进 制数据为ASCII字符串格式.Java语言提供了一个非常好的 ...