Saturday, April 14, 2012

Spring Expression Language (SpEL).

Getting properties file

<util:properties id="settings" location="classpath:settings.properties"/>

Accesing a value in properties

<property name="accessToken" value="#{settings['twitter.accessToken']}"/>

systemEnvironment and systemProperties

In addition to reading properties from a <util:properties>-declared collection, Spring makes two special selections of properties available to SpEL:  systemEnvironment and systemProperties.
systemEnvironment contains all of the environment variables on the machine running the application. It’s just a java.util.Properties collection, so the square braces can be used to access its members by their key. For example, we can inject the user’s region into a bean property like this:

<property name="userRegion" value="#{ systemProperties['user.region'] }"/>

Selecting Collection Members

Let’s say that you want to narrow the list of cities down to only those whose population is greater than 100,000. One way to do this is to wire the entire cities bean into a property and place the burden of sifting out the smaller cities on the receiving bean. But with SpEL, it’s a simple matter of using a selection operator (.?[]) when doing the wiring:

<property name="bigCities" value="#{cities.?[population gt 100000]}"/>

SpEL also offers two other selection operators, .^[] and .$[] , for selecting the first and last matching items (respectively) from a collection. For example, to select the first big city from cities:

<property name="aBigCity" value="#{cities.^[population gt 100000]}"/>

No ordering is done on the collection prior to selection, so the City representing Chicago would be wired into the aBigCity property. Likewise, the City object representing El Paso could be selected as follows:

<property name="aBigCity" value="#{cities.$[population gt 100000]}"/>

Projecting Collections

Collection projection involves collecting a particular property from each of the members of a collection into a new collection. SpEL’s projection operator (.![]) can do exactly that.
For example, suppose that instead of a list of City objects, what you want is just a list of String objects containing the names of the cities. To get a list of just the city names, you could wire a cityNames property like this:

<property name="cityNames" value="#{cities.![name]}"/>

But projection isn’t limited to projecting a single property. With a slight change to the previous example, you can get a list of city and state names:

<property name="cityNames" value="#{cities.![name + ', ' + state]}"/>

To bring collection selection and projection together. Here’s how you might wire a list of only big city names into the cityNames property:

<property name="cityNames" value="#{cities.?[population gt 100000].![name + ', ' + state]}"/>

Autowiring

Spring 3 supports a few different annotations for autowiring:

Spring’s own @Autowired annotation
The @Inject annotation from JSR-330
The @Resource annotation from JSR-250

Using expressions with annotation injection

As long as you’re using annotations to autowire bean references into your Spring beans, you may want to also use annotations to wire simpler values. Spring 3.0 introduced @Value, a new wiring annotation that lets you wire primitive values such as int, boolean, and String using annotations.

The @Value annotation is simple to use but, as you’ll soon see, is also powerful. To use it, annotate a property, method, or method parameter with @Value and pass in a String expression to be wired into the property. For example:

@Value("Eruption")
private String song;

Here we’re wiring a String value into a String property. But the String parameter passed into @Value is just an expression—it can evaluate down to any type and thus @Value can be applied to just about any kind of property.

As it turns out, simple values aren’t where @Value shines. Instead, @Value finds its power with SpEL expressions. Recall that SpEL lets you dynamically evaluate complex expressions, at runtime, into values to be wired into bean properties. That makes @Value a powerful wiring option. For example, rather than hardcoding a static value into the song property, let’s use SpEL to pull a value from a system property:

@Value("#{systemProperties.myFavoriteSong}")
private String song;

0 comments:

Post a Comment