# 4.2 变量

我们之前提到`${...}`表达式实际上就是OGNL（对象导航图语言）表达式，只是它在上下文里的变量的映射关系上被执行。

```
关于OGNL语法和特性的细节，你应当阅读[OGNL语言指南](http://commons.apache.org/ognl/)

在启用Spring MVC的应用里，OGNL会被**SpringEL**代替，但是它的语法和OGNL非常相似（实际上，在大多数普通情况下，两者基本相同）。
```

从OGNL的语法来看，我们知道下面的表达式：

```markup
<p>Today is: <span th:text="${today}">13 february 2011</span>.</p>
```

实际上相当于：

```markup
ctx.getVariable("today");
```

但是OGNL允许我们创建相当强大的表达式，那就是为什么如下：

```markup
<p th:utext="#{home.welcome(${session.user.name})}">
  Welcome to our grocery store, Sebastian Pepper!
</p>
```

可以这样执行：

```java
((User) ctx.getVariable("session").get("user")).getName();
```

但是，getter方法导航只是OGNL的其中一个特性。让我们看看更多的特性：

```
/*
 * Access to properties using the point (.). Equivalent to calling property getters.
 */
${person.father.name}

/*
 * Access to properties can also be made by using brackets ([]) and writing 
 * the name of the property as a variable or between single quotes.
 */
${person['father']['name']}

/*
 * If the object is a map, both dot and bracket syntax will be equivalent to 
 * executing a call on its get(...) method.
 */
${countriesByCode.ES}
${personsByName['Stephen Zucchini'].age}

/*
 * Indexed access to arrays or collections is also performed with brackets, 
 * writing the index without quotes.
 */
${personsArray[0].name}

/*
 * Methods can be called, even with arguments.
 */
${person.createCompleteName()}
${person.createCompleteNameWithSeparator('-')}
```
