parent
ec740559ed
commit
db02d38c89
|
@ -481,33 +481,38 @@ pointcut expressions by name. The following example shows three pointcut express
|
||||||
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
|
[source,java,indent=0,subs="verbatim,quotes",role="primary"]
|
||||||
.Java
|
.Java
|
||||||
----
|
----
|
||||||
// matches if a method execution join point represents the execution of any public method
|
|
||||||
@Pointcut("execution(public * *(..))")
|
@Pointcut("execution(public * *(..))")
|
||||||
private void anyPublicOperation() {}
|
private void anyPublicOperation() {} // <1>
|
||||||
|
|
||||||
// matches if a method execution is in the trading module
|
|
||||||
@Pointcut("within(com.xyz.someapp.trading..*)")
|
@Pointcut("within(com.xyz.someapp.trading..*)")
|
||||||
private void inTrading() {}
|
private void inTrading() {} // <2>
|
||||||
|
|
||||||
// matches if a method execution represents any public method in the trading module
|
|
||||||
@Pointcut("anyPublicOperation() && inTrading()")
|
@Pointcut("anyPublicOperation() && inTrading()")
|
||||||
private void tradingOperation() {}
|
private void tradingOperation() {} // <3>
|
||||||
----
|
----
|
||||||
|
<1> `anyPublicOperation` matches if a method execution join point represents the execution
|
||||||
|
of any public method.
|
||||||
|
<2> `inTrading` matches if a method execution is in the trading module.
|
||||||
|
<3> `tradingOperation` matches if a method execution represents any public method in the
|
||||||
|
trading module.
|
||||||
|
|
||||||
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
|
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
|
||||||
.Kotlin
|
.Kotlin
|
||||||
----
|
----
|
||||||
// matches if a method execution join point represents the execution of any public method.
|
|
||||||
@Pointcut("execution(public * *(..))")
|
@Pointcut("execution(public * *(..))")
|
||||||
private fun anyPublicOperation() {}
|
private fun anyPublicOperation() {} // <1>
|
||||||
|
|
||||||
// matches if a method execution is in the trading module
|
|
||||||
@Pointcut("within(com.xyz.someapp.trading..*)")
|
@Pointcut("within(com.xyz.someapp.trading..*)")
|
||||||
private fun inTrading() {}
|
private fun inTrading() {} // <2>
|
||||||
|
|
||||||
// matches if a method execution represents any public method in the trading module
|
|
||||||
@Pointcut("anyPublicOperation() && inTrading()")
|
@Pointcut("anyPublicOperation() && inTrading()")
|
||||||
private fun tradingOperation() {}
|
private fun tradingOperation() {} // <3>
|
||||||
----
|
----
|
||||||
|
<1> `anyPublicOperation` matches if a method execution join point represents the execution
|
||||||
|
of any public method.
|
||||||
|
<2> `inTrading` matches if a method execution is in the trading module.
|
||||||
|
<3> `tradingOperation` matches if a method execution represents any public method in the
|
||||||
|
trading module.
|
||||||
|
|
||||||
It is a best practice to build more complex pointcut expressions out of smaller named
|
It is a best practice to build more complex pointcut expressions out of smaller named
|
||||||
components, as shown earlier. When referring to pointcuts by name, normal Java visibility
|
components, as shown earlier. When referring to pointcuts by name, normal Java visibility
|
||||||
|
|
|
@ -860,14 +860,10 @@ we can parse our custom XML content, as you can see in the following example:
|
||||||
|
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
|
|
||||||
// We use the Spring-provided AbstractSingleBeanDefinitionParser to handle a lot of
|
public class SimpleDateFormatBeanDefinitionParser extends AbstractSingleBeanDefinitionParser { // <1>
|
||||||
// the basic grunt work of creating a single BeanDefinition.
|
|
||||||
public class SimpleDateFormatBeanDefinitionParser extends AbstractSingleBeanDefinitionParser {
|
|
||||||
|
|
||||||
protected Class getBeanClass(Element element) {
|
protected Class getBeanClass(Element element) {
|
||||||
// We supply the AbstractSingleBeanDefinitionParser superclass with the type that our
|
return SimpleDateFormat.class; // <2>
|
||||||
// single BeanDefinition represents.
|
|
||||||
return SimpleDateFormat.class;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void doParse(Element element, BeanDefinitionBuilder bean) {
|
protected void doParse(Element element, BeanDefinitionBuilder bean) {
|
||||||
|
@ -884,6 +880,11 @@ we can parse our custom XML content, as you can see in the following example:
|
||||||
|
|
||||||
}
|
}
|
||||||
----
|
----
|
||||||
|
<1> We use the Spring-provided `AbstractSingleBeanDefinitionParser` to handle a lot of
|
||||||
|
the basic grunt work of creating a single `BeanDefinition`.
|
||||||
|
<2> We supply the `AbstractSingleBeanDefinitionParser` superclass with the type that our
|
||||||
|
single `BeanDefinition` represents.
|
||||||
|
|
||||||
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
|
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
|
||||||
.Kotlin
|
.Kotlin
|
||||||
----
|
----
|
||||||
|
@ -896,13 +897,9 @@ we can parse our custom XML content, as you can see in the following example:
|
||||||
|
|
||||||
import java.text.SimpleDateFormat
|
import java.text.SimpleDateFormat
|
||||||
|
|
||||||
// We use the Spring-provided AbstractSingleBeanDefinitionParser to handle a lot of
|
class SimpleDateFormatBeanDefinitionParser : AbstractSingleBeanDefinitionParser() { // <1>
|
||||||
// the basic grunt work of creating a single BeanDefinition.
|
|
||||||
class SimpleDateFormatBeanDefinitionParser : AbstractSingleBeanDefinitionParser() {
|
|
||||||
|
|
||||||
override fun getBeanClass(element: Element): Class<*>? {
|
override fun getBeanClass(element: Element): Class<*>? { // <2>
|
||||||
// We supply the AbstractSingleBeanDefinitionParser superclass with the type that our
|
|
||||||
// single BeanDefinition represents.
|
|
||||||
return SimpleDateFormat::class.java
|
return SimpleDateFormat::class.java
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -919,6 +916,11 @@ we can parse our custom XML content, as you can see in the following example:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
----
|
----
|
||||||
|
<1> We use the Spring-provided `AbstractSingleBeanDefinitionParser` to handle a lot of
|
||||||
|
the basic grunt work of creating a single `BeanDefinition`.
|
||||||
|
<2> We supply the `AbstractSingleBeanDefinitionParser` superclass with the type that our
|
||||||
|
single `BeanDefinition` represents.
|
||||||
|
|
||||||
|
|
||||||
In this simple case, this is all that we need to do. The creation of our single
|
In this simple case, this is all that we need to do. The creation of our single
|
||||||
`BeanDefinition` is handled by the `AbstractSingleBeanDefinitionParser` superclass, as
|
`BeanDefinition` is handled by the `AbstractSingleBeanDefinitionParser` superclass, as
|
||||||
|
|
|
@ -5599,24 +5599,27 @@ following example:
|
||||||
public class MovieRecommender {
|
public class MovieRecommender {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
@Offline
|
@Offline // <1>
|
||||||
private MovieCatalog offlineCatalog;
|
private MovieCatalog offlineCatalog;
|
||||||
|
|
||||||
// ...
|
// ...
|
||||||
}
|
}
|
||||||
----
|
----
|
||||||
|
<1> This line adds the `@Offline` annotation.
|
||||||
|
|
||||||
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
|
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
|
||||||
.Kotlin
|
.Kotlin
|
||||||
----
|
----
|
||||||
class MovieRecommender {
|
class MovieRecommender {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
@Offline
|
@Offline // <1>
|
||||||
private lateinit var offlineCatalog: MovieCatalog
|
private lateinit var offlineCatalog: MovieCatalog
|
||||||
|
|
||||||
// ...
|
// ...
|
||||||
}
|
}
|
||||||
----
|
----
|
||||||
|
<1> This line adds the `@Offline` annotation.
|
||||||
|
|
||||||
Now the bean definition only needs a qualifier `type`, as shown in the following example:
|
Now the bean definition only needs a qualifier `type`, as shown in the following example:
|
||||||
|
|
||||||
|
@ -5915,21 +5918,24 @@ as demonstrated in the following example:
|
||||||
|
|
||||||
private MovieFinder movieFinder;
|
private MovieFinder movieFinder;
|
||||||
|
|
||||||
@Resource(name="myMovieFinder") // This line injects a @Resource
|
@Resource(name="myMovieFinder") // <1>
|
||||||
public void setMovieFinder(MovieFinder movieFinder) {
|
public void setMovieFinder(MovieFinder movieFinder) {
|
||||||
this.movieFinder = movieFinder;
|
this.movieFinder = movieFinder;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
----
|
----
|
||||||
|
<1> This line injects a `@Resource`.
|
||||||
|
|
||||||
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
|
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
|
||||||
.Kotlin
|
.Kotlin
|
||||||
----
|
----
|
||||||
class SimpleMovieLister {
|
class SimpleMovieLister {
|
||||||
|
|
||||||
@Resource(name="myMovieFinder") // This line injects a @Resource
|
@Resource(name="myMovieFinder") // <1>
|
||||||
private lateinit var movieFinder:MovieFinder
|
private lateinit var movieFinder:MovieFinder
|
||||||
}
|
}
|
||||||
----
|
----
|
||||||
|
<1> This line injects a `@Resource`.
|
||||||
|
|
||||||
|
|
||||||
If no name is explicitly specified, the default name is derived from the field name or
|
If no name is explicitly specified, the default name is derived from the field name or
|
||||||
|
@ -5986,10 +5992,8 @@ named "customerPreferenceDao" and then falls back to a primary type match for th
|
||||||
@Resource
|
@Resource
|
||||||
private CustomerPreferenceDao customerPreferenceDao;
|
private CustomerPreferenceDao customerPreferenceDao;
|
||||||
|
|
||||||
// The context field is injected based on the known resolvable dependency
|
|
||||||
// type: ApplicationContext
|
|
||||||
@Resource
|
@Resource
|
||||||
private ApplicationContext context;
|
private ApplicationContext context; // <1>
|
||||||
|
|
||||||
public MovieRecommender() {
|
public MovieRecommender() {
|
||||||
}
|
}
|
||||||
|
@ -5997,6 +6001,9 @@ named "customerPreferenceDao" and then falls back to a primary type match for th
|
||||||
// ...
|
// ...
|
||||||
}
|
}
|
||||||
----
|
----
|
||||||
|
<1> The `context` field is injected based on the known resolvable dependency type:
|
||||||
|
`ApplicationContext`.
|
||||||
|
|
||||||
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
|
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
|
||||||
.Kotlin
|
.Kotlin
|
||||||
----
|
----
|
||||||
|
@ -6005,14 +6012,15 @@ named "customerPreferenceDao" and then falls back to a primary type match for th
|
||||||
@Resource
|
@Resource
|
||||||
private lateinit var customerPreferenceDao: CustomerPreferenceDao
|
private lateinit var customerPreferenceDao: CustomerPreferenceDao
|
||||||
|
|
||||||
// The context field is injected based on the known resolvable dependency
|
|
||||||
// type: ApplicationContext
|
|
||||||
@Resource
|
@Resource
|
||||||
private lateinit var context: ApplicationContext
|
private lateinit var context: ApplicationContext // <1>
|
||||||
|
|
||||||
// ...
|
// ...
|
||||||
}
|
}
|
||||||
----
|
----
|
||||||
|
<1> The `context` field is injected based on the known resolvable dependency type:
|
||||||
|
`ApplicationContext`.
|
||||||
|
|
||||||
[[beans-value-annotations]]
|
[[beans-value-annotations]]
|
||||||
=== Using `@Value`
|
=== Using `@Value`
|
||||||
|
@ -6341,24 +6349,27 @@ is meta-annotated with `@Component`, as the following example shows:
|
||||||
@Target(ElementType.TYPE)
|
@Target(ElementType.TYPE)
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
@Documented
|
@Documented
|
||||||
@Component // Causes @Service to be treated in the same way as @Component
|
@Component // <1>
|
||||||
public @interface Service {
|
public @interface Service {
|
||||||
|
|
||||||
// ...
|
// ...
|
||||||
}
|
}
|
||||||
----
|
----
|
||||||
|
<1> The `Component` causes `@Service` to be treated in the same way as `@Component`.
|
||||||
|
|
||||||
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
|
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
|
||||||
.Kotlin
|
.Kotlin
|
||||||
----
|
----
|
||||||
@Target(AnnotationTarget.TYPE)
|
@Target(AnnotationTarget.TYPE)
|
||||||
@Retention(AnnotationRetention.RUNTIME)
|
@Retention(AnnotationRetention.RUNTIME)
|
||||||
@MustBeDocumented
|
@MustBeDocumented
|
||||||
@Component // Causes @Service to be treated in the same way as @Component
|
@Component // <1>
|
||||||
annotation class Service {
|
annotation class Service {
|
||||||
|
|
||||||
// ...
|
// ...
|
||||||
}
|
}
|
||||||
----
|
----
|
||||||
|
<1> The `Component` causes `@Service` to be treated in the same way as `@Component`.
|
||||||
|
|
||||||
You can also combine meta-annotations to create "`composed annotations`". For example,
|
You can also combine meta-annotations to create "`composed annotations`". For example,
|
||||||
the `@RestController` annotation from Spring MVC is composed of `@Controller` and
|
the `@RestController` annotation from Spring MVC is composed of `@Controller` and
|
||||||
|
@ -7779,20 +7790,23 @@ To enable component scanning, you can annotate your `@Configuration` class as fo
|
||||||
.Java
|
.Java
|
||||||
----
|
----
|
||||||
@Configuration
|
@Configuration
|
||||||
@ComponentScan(basePackages = "com.acme") // This annotation enables component scanning
|
@ComponentScan(basePackages = "com.acme") // <1>
|
||||||
public class AppConfig {
|
public class AppConfig {
|
||||||
...
|
...
|
||||||
}
|
}
|
||||||
----
|
----
|
||||||
|
<1> This annotation enables component scanning.
|
||||||
|
|
||||||
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
|
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
|
||||||
.Kotlin
|
.Kotlin
|
||||||
----
|
----
|
||||||
@Configuration
|
@Configuration
|
||||||
@ComponentScan(basePackages = ["com.acme"]) // This annotation enables component scanning
|
@ComponentScan(basePackages = ["com.acme"]) // <1>
|
||||||
class AppConfig {
|
class AppConfig {
|
||||||
// ...
|
// ...
|
||||||
}
|
}
|
||||||
----
|
----
|
||||||
|
<1> This annotation enables component scanning.
|
||||||
|
|
||||||
|
|
||||||
[TIP]
|
[TIP]
|
||||||
|
@ -9655,7 +9669,7 @@ the following example shows:
|
||||||
public class AppConfig {
|
public class AppConfig {
|
||||||
|
|
||||||
@Bean("dataSource")
|
@Bean("dataSource")
|
||||||
@Profile("development") // The standaloneDataSource method is available only in the development profile
|
@Profile("development") // <1>
|
||||||
public DataSource standaloneDataSource() {
|
public DataSource standaloneDataSource() {
|
||||||
return new EmbeddedDatabaseBuilder()
|
return new EmbeddedDatabaseBuilder()
|
||||||
.setType(EmbeddedDatabaseType.HSQL)
|
.setType(EmbeddedDatabaseType.HSQL)
|
||||||
|
@ -9665,13 +9679,16 @@ the following example shows:
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean("dataSource")
|
@Bean("dataSource")
|
||||||
@Profile("production") // The jndiDataSource method is available only in the production profile
|
@Profile("production") // <2>
|
||||||
public DataSource jndiDataSource() throws Exception {
|
public DataSource jndiDataSource() throws Exception {
|
||||||
Context ctx = new InitialContext();
|
Context ctx = new InitialContext();
|
||||||
return (DataSource) ctx.lookup("java:comp/env/jdbc/datasource");
|
return (DataSource) ctx.lookup("java:comp/env/jdbc/datasource");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
----
|
----
|
||||||
|
<1> The `standaloneDataSource` method is available only in the `development` profile.
|
||||||
|
<2> The `jndiDataSource` method is available only in the `production` profile.
|
||||||
|
|
||||||
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
|
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
|
||||||
.Kotlin
|
.Kotlin
|
||||||
----
|
----
|
||||||
|
@ -9679,7 +9696,7 @@ the following example shows:
|
||||||
class AppConfig {
|
class AppConfig {
|
||||||
|
|
||||||
@Bean("dataSource")
|
@Bean("dataSource")
|
||||||
@Profile("development") // The standaloneDataSource method is available only in the development profile
|
@Profile("development") // <1>
|
||||||
fun standaloneDataSource(): DataSource {
|
fun standaloneDataSource(): DataSource {
|
||||||
return EmbeddedDatabaseBuilder()
|
return EmbeddedDatabaseBuilder()
|
||||||
.setType(EmbeddedDatabaseType.HSQL)
|
.setType(EmbeddedDatabaseType.HSQL)
|
||||||
|
@ -9689,11 +9706,13 @@ the following example shows:
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean("dataSource")
|
@Bean("dataSource")
|
||||||
@Profile("production") // The jndiDataSource method is available only in the production profile
|
@Profile("production") // <2>
|
||||||
fun jndiDataSource() =
|
fun jndiDataSource() =
|
||||||
InitialContext().lookup("java:comp/env/jdbc/datasource") as DataSource
|
InitialContext().lookup("java:comp/env/jdbc/datasource") as DataSource
|
||||||
}
|
}
|
||||||
----
|
----
|
||||||
|
<1> The `standaloneDataSource` method is available only in the `development` profile.
|
||||||
|
<2> The `jndiDataSource` method is available only in the `production` profile.
|
||||||
|
|
||||||
[NOTE]
|
[NOTE]
|
||||||
====
|
====
|
||||||
|
|
|
@ -69,16 +69,19 @@ The following code introduces the SpEL API to evaluate the literal string expres
|
||||||
.Java
|
.Java
|
||||||
----
|
----
|
||||||
ExpressionParser parser = new SpelExpressionParser();
|
ExpressionParser parser = new SpelExpressionParser();
|
||||||
Expression exp = parser.parseExpression("'Hello World'"); // The value of the message variable is 'Hello World'
|
Expression exp = parser.parseExpression("'Hello World'"); // <1>
|
||||||
String message = (String) exp.getValue();
|
String message = (String) exp.getValue();
|
||||||
----
|
----
|
||||||
|
<1> The value of the message variable is `'Hello World'`.
|
||||||
|
|
||||||
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
|
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
|
||||||
.Kotlin
|
.Kotlin
|
||||||
----
|
----
|
||||||
val parser = SpelExpressionParser()
|
val parser = SpelExpressionParser()
|
||||||
val exp = parser.parseExpression("'Hello World'") // The value of the message variable is 'Hello World'
|
val exp = parser.parseExpression("'Hello World'") // <1>
|
||||||
val message = exp.value as String
|
val message = exp.value as String
|
||||||
----
|
----
|
||||||
|
<1> The value of the message variable is `'Hello World'`.
|
||||||
|
|
||||||
|
|
||||||
The SpEL classes and interfaces you are most likely to use are located in the
|
The SpEL classes and interfaces you are most likely to use are located in the
|
||||||
|
@ -100,18 +103,19 @@ In the following example of method invocation, we call the `concat` method on th
|
||||||
.Java
|
.Java
|
||||||
----
|
----
|
||||||
ExpressionParser parser = new SpelExpressionParser();
|
ExpressionParser parser = new SpelExpressionParser();
|
||||||
Expression exp = parser.parseExpression("'Hello World'.concat('!')");
|
Expression exp = parser.parseExpression("'Hello World'.concat('!')"); // <1>
|
||||||
// The value of message is now 'Hello World!'
|
|
||||||
String message = (String) exp.getValue();
|
String message = (String) exp.getValue();
|
||||||
----
|
----
|
||||||
|
<1> The value of `message` is now 'Hello World!'.
|
||||||
|
|
||||||
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
|
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
|
||||||
.Kotlin
|
.Kotlin
|
||||||
----
|
----
|
||||||
val parser = SpelExpressionParser()
|
val parser = SpelExpressionParser()
|
||||||
val exp = parser.parseExpression("'Hello World'.concat('!')")
|
val exp = parser.parseExpression("'Hello World'.concat('!')") // <1>
|
||||||
// The value of message is now 'Hello World!'
|
|
||||||
val message = exp.value as String
|
val message = exp.value as String
|
||||||
----
|
----
|
||||||
|
<1> The value of `message` is now 'Hello World!'.
|
||||||
|
|
||||||
The following example of calling a JavaBean property calls the `String` property `Bytes`:
|
The following example of calling a JavaBean property calls the `String` property `Bytes`:
|
||||||
|
|
||||||
|
@ -121,18 +125,21 @@ The following example of calling a JavaBean property calls the `String` property
|
||||||
ExpressionParser parser = new SpelExpressionParser();
|
ExpressionParser parser = new SpelExpressionParser();
|
||||||
|
|
||||||
// invokes 'getBytes()'
|
// invokes 'getBytes()'
|
||||||
Expression exp = parser.parseExpression("'Hello World'.bytes"); // This line converts the literal to a byte array
|
Expression exp = parser.parseExpression("'Hello World'.bytes"); // <1>
|
||||||
byte[] bytes = (byte[]) exp.getValue();
|
byte[] bytes = (byte[]) exp.getValue();
|
||||||
----
|
----
|
||||||
|
<1> This line converts the literal to a byte array.
|
||||||
|
|
||||||
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
|
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
|
||||||
.Kotlin
|
.Kotlin
|
||||||
----
|
----
|
||||||
val parser = SpelExpressionParser()
|
val parser = SpelExpressionParser()
|
||||||
|
|
||||||
// invokes 'getBytes()'
|
// invokes 'getBytes()'
|
||||||
val exp = parser.parseExpression("'Hello World'.bytes") // This line converts the literal to a byte array
|
val exp = parser.parseExpression("'Hello World'.bytes") // <1>
|
||||||
val bytes = exp.value as ByteArray
|
val bytes = exp.value as ByteArray
|
||||||
----
|
----
|
||||||
|
<1> This line converts the literal to a byte array.
|
||||||
|
|
||||||
SpEL also supports nested properties by using the standard dot notation (such as
|
SpEL also supports nested properties by using the standard dot notation (such as
|
||||||
`prop1.prop2.prop3`) and also the corresponding setting of property values.
|
`prop1.prop2.prop3`) and also the corresponding setting of property values.
|
||||||
|
@ -146,18 +153,21 @@ The following example shows how to use dot notation to get the length of a liter
|
||||||
ExpressionParser parser = new SpelExpressionParser();
|
ExpressionParser parser = new SpelExpressionParser();
|
||||||
|
|
||||||
// invokes 'getBytes().length'
|
// invokes 'getBytes().length'
|
||||||
Expression exp = parser.parseExpression("'Hello World'.bytes.length"); // 'Hello World'.bytes.length gives the length of the literal.
|
Expression exp = parser.parseExpression("'Hello World'.bytes.length"); // <1>
|
||||||
int length = (Integer) exp.getValue();
|
int length = (Integer) exp.getValue();
|
||||||
----
|
----
|
||||||
|
<1> `'Hello World'.bytes.length` gives the length of the literal.
|
||||||
|
|
||||||
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
|
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
|
||||||
.Kotlin
|
.Kotlin
|
||||||
----
|
----
|
||||||
val parser = SpelExpressionParser()
|
val parser = SpelExpressionParser()
|
||||||
|
|
||||||
// invokes 'getBytes().length'
|
// invokes 'getBytes().length'
|
||||||
val exp = parser.parseExpression("'Hello World'.bytes.length") // 'Hello World'.bytes.length gives the length of the literal.
|
val exp = parser.parseExpression("'Hello World'.bytes.length") // <1>
|
||||||
val length = exp.value as Int
|
val length = exp.value as Int
|
||||||
----
|
----
|
||||||
|
<1> `'Hello World'.bytes.length` gives the length of the literal.
|
||||||
|
|
||||||
The String's constructor can be called instead of using a string literal, as the following
|
The String's constructor can be called instead of using a string literal, as the following
|
||||||
example shows:
|
example shows:
|
||||||
|
@ -166,18 +176,19 @@ example shows:
|
||||||
.Java
|
.Java
|
||||||
----
|
----
|
||||||
ExpressionParser parser = new SpelExpressionParser();
|
ExpressionParser parser = new SpelExpressionParser();
|
||||||
// Construct a new String from the literal and make it be upper case
|
|
||||||
Expression exp = parser.parseExpression("new String('hello world').toUpperCase()");
|
Expression exp = parser.parseExpression("new String('hello world').toUpperCase()");
|
||||||
String message = exp.getValue(String.class);
|
String message = exp.getValue(String.class);
|
||||||
----
|
----
|
||||||
|
<1> Construct a new `String` from the literal and make it be upper case.
|
||||||
|
|
||||||
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
|
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"]
|
||||||
.Kotlin
|
.Kotlin
|
||||||
----
|
----
|
||||||
val parser = SpelExpressionParser()
|
val parser = SpelExpressionParser()
|
||||||
// Construct a new String from the literal and make it be upper case
|
|
||||||
val exp = parser.parseExpression("new String('hello world').toUpperCase()")
|
val exp = parser.parseExpression("new String('hello world').toUpperCase()")
|
||||||
val message = exp.getValue(String::class.java)
|
val message = exp.getValue(String::class.java)
|
||||||
----
|
----
|
||||||
|
<1> Construct a new `String` from the literal and make it be upper case.
|
||||||
|
|
||||||
|
|
||||||
Note the use of the generic method: `public <T> T getValue(Class<T> desiredResultType)`.
|
Note the use of the generic method: `public <T> T getValue(Class<T> desiredResultType)`.
|
||||||
|
|
Loading…
Reference in New Issue