Edit the core content reference documentation
I edited for the usual stuff: spelling, punctuation, grammar, formatting, usage, and voice.
This commit is contained in:
parent
d0ada5653f
commit
395e3d008c
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
|
@ -1,6 +1,7 @@
|
||||||
[[beans]]
|
[[beans]]
|
||||||
= The IoC container
|
= The IoC Container
|
||||||
|
|
||||||
|
This chapter covers Spring's Inversion of Control (IoC) container.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -2136,6 +2137,7 @@ modes:
|
||||||
|
|
||||||
[[beans-factory-autowiring-modes-tbl]]
|
[[beans-factory-autowiring-modes-tbl]]
|
||||||
.Autowiring modes
|
.Autowiring modes
|
||||||
|
[cols="20%,80%"]
|
||||||
|===
|
|===
|
||||||
| Mode| Explanation
|
| Mode| Explanation
|
||||||
|
|
||||||
|
|
@ -2568,6 +2570,7 @@ The following table describes the supported scopes:
|
||||||
|
|
||||||
[[beans-factory-scopes-tbl]]
|
[[beans-factory-scopes-tbl]]
|
||||||
.Bean scopes
|
.Bean scopes
|
||||||
|
[cols="20%,80%"]
|
||||||
|===
|
|===
|
||||||
| Scope| Description
|
| Scope| Description
|
||||||
|
|
||||||
|
|
@ -4565,7 +4568,7 @@ references and values even when you use the class outside of a container.
|
||||||
|
|
||||||
|
|
||||||
[[beans-autowired-annotation]]
|
[[beans-autowired-annotation]]
|
||||||
=== @Autowired
|
=== Using `@Autowired`
|
||||||
|
|
||||||
NOTE: JSR 330's `@Inject` annotation can be used in place of Spring's `@Autowired` annotation
|
NOTE: JSR 330's `@Inject` annotation can be used in place of Spring's `@Autowired` annotation
|
||||||
in the examples included in this section. See <<beans-standard-annotations,here>> for more details.
|
in the examples included in this section. See <<beans-standard-annotations,here>> for more details.
|
||||||
|
|
@ -8191,7 +8194,7 @@ the following example shows:
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean("dataSource")
|
@Bean("dataSource")
|
||||||
**@Profile("production")**
|
@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");
|
||||||
|
|
@ -8199,6 +8202,7 @@ the following example shows:
|
||||||
}
|
}
|
||||||
----
|
----
|
||||||
<1> The `standaloneDataSource` method is available only in the `development` profile.
|
<1> The `standaloneDataSource` method is available only in the `development` profile.
|
||||||
|
<2> The `jndiDataSource` method is available only in the `production` profile.
|
||||||
====
|
====
|
||||||
|
|
||||||
[NOTE]
|
[NOTE]
|
||||||
|
|
@ -8895,6 +8899,7 @@ The following table describes the standard events that Spring provides:
|
||||||
|
|
||||||
[[beans-ctx-events-tbl]]
|
[[beans-ctx-events-tbl]]
|
||||||
.Built-in Events
|
.Built-in Events
|
||||||
|
[cols="30%,70%"]
|
||||||
|===
|
|===
|
||||||
| Event| Explanation
|
| Event| Explanation
|
||||||
|
|
||||||
|
|
@ -9460,6 +9465,7 @@ The following table lists features provided by the `BeanFactory` and
|
||||||
|
|
||||||
[[context-introduction-ctx-vs-beanfactory-feature-matrix]]
|
[[context-introduction-ctx-vs-beanfactory-feature-matrix]]
|
||||||
.Feature Matrix
|
.Feature Matrix
|
||||||
|
[cols="50%,25%,25%"]
|
||||||
|===
|
|===
|
||||||
| Feature | `BeanFactory` | `ApplicationContext`
|
| Feature | `BeanFactory` | `ApplicationContext`
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,69 +1,64 @@
|
||||||
[[databuffers]]
|
[[databuffers]]
|
||||||
= Data Buffers and Codecs
|
= Data Buffers and Codecs
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
== Introduction
|
|
||||||
|
|
||||||
The `DataBuffer` interface defines an abstraction over byte buffers.
|
The `DataBuffer` interface defines an abstraction over byte buffers.
|
||||||
The main reason for introducing it, and not use the standard `java.nio.ByteBuffer` instead, is Netty.
|
The main reason for introducing it (and not using the standard `java.nio.ByteBuffer` instead) is Netty.
|
||||||
Netty does not use `ByteBuffer`, but instead offers `ByteBuf` as an alternative.
|
Netty does not use `ByteBuffer` but instead offers `ByteBuf` as an alternative.
|
||||||
Spring's `DataBuffer` is a simple abstraction over `ByteBuf` that can also be used on non-Netty
|
Spring's `DataBuffer` is a simple abstraction over `ByteBuf` that can also be used on non-Netty
|
||||||
platforms (i.e. Servlet 3.1+).
|
platforms (that is, Servlet 3.1+).
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
== `DataBufferFactory`
|
== `DataBufferFactory`
|
||||||
|
|
||||||
The `DataBufferFactory` offers functionality to allocate new data buffers, as well as to wrap
|
The `DataBufferFactory` offers functionality to allocate new data buffers as well as to wrap
|
||||||
existing data.
|
existing data.
|
||||||
The `allocate` methods allocate a new data buffer, with a default or given capacity.
|
The `allocateBuffer` methods allocate a new data buffer with a default or given capacity.
|
||||||
Though `DataBuffer` implementation grow and shrink on demand, it is more efficient to give the
|
Though `DataBuffer` implementations grow and shrink on demand, it is more efficient to give the
|
||||||
capacity upfront, if known.
|
capacity upfront, if known.
|
||||||
The `wrap` methods decorate an existing `ByteBuffer` or byte array.
|
The `wrap` methods decorate an existing `ByteBuffer` or byte array.
|
||||||
Wrapping does not involve allocation: it simply decorates the given data with a `DataBuffer`
|
Wrapping does not involve allocation. It decorates the given data with a `DataBuffer`
|
||||||
implementation.
|
implementation.
|
||||||
|
|
||||||
There are two implementation of `DataBufferFactory`: the `NettyDataBufferFactory` which is meant
|
There are two implementation of `DataBufferFactory`: the `NettyDataBufferFactory`
|
||||||
to be used on Netty platforms, such as Reactor Netty.
|
(for Netty platforms, such as Reactor Netty) and
|
||||||
The other implementation, the `DefaultDataBufferFactory`, is used on other platforms, such as
|
`DefaultDataBufferFactory` (for other platforms, such as
|
||||||
Servlet 3.1+ servers.
|
Servlet 3.1+ servers).
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
== The `DataBuffer` Interface
|
||||||
|
|
||||||
== The `DataBuffer` interface
|
The `DataBuffer` interface is similar to `ByteBuffer` but offers a number of advantages.
|
||||||
|
|
||||||
The `DataBuffer` interface is similar to `ByteBuffer`, but offers a number of advantages.
|
|
||||||
Similar to Netty's `ByteBuf`, the `DataBuffer` abstraction offers independent read and write
|
Similar to Netty's `ByteBuf`, the `DataBuffer` abstraction offers independent read and write
|
||||||
positions.
|
positions.
|
||||||
This is different from the JDK's `ByteBuffer`, which only exposes one position for both reading and
|
This is different from the JDK's `ByteBuffer`, which exposes only one position for both reading and
|
||||||
writing, and a separate `flip()` operation to switch between the two I/O operations.
|
writing and a separate `flip()` operation to switch between the two I/O operations.
|
||||||
In general, the following invariant holds for the read position, write position, and the capacity:
|
In general, the following invariant holds for the read position, write position, and the capacity:
|
||||||
|
|
||||||
|
====
|
||||||
[literal]
|
[literal]
|
||||||
[subs="verbatim,quotes"]
|
[subs="verbatim,quotes"]
|
||||||
--
|
--
|
||||||
0 <= read position <= write position <= capacity
|
0 <= read position <= write position <= capacity
|
||||||
--
|
--
|
||||||
|
====
|
||||||
|
|
||||||
When reading bytes from the `DataBuffer`, the read position is automatically updated in accordance with
|
When reading bytes from the `DataBuffer`, the read position is automatically updated in accordance with
|
||||||
the amount of data read from the buffer.
|
the amount of data read from the buffer.
|
||||||
Similarly, when writing bytes to the `DataBuffer`, the write position is updated with the amount of
|
Similarly, when writing bytes to the `DataBuffer`, the write position is updated with the amount of
|
||||||
data written to the buffer.
|
data written to the buffer.
|
||||||
Also, when writing data, the capacity of a `DataBuffer` is automatically expanded, just like `StringBuilder`,
|
Also, when writing data, the capacity of a `DataBuffer` is automatically expanded, in the same fashion as `StringBuilder`,
|
||||||
`ArrayList`, and similar types.
|
`ArrayList`, and similar types.
|
||||||
|
|
||||||
Besides the reading and writing functionality mentioned above, the `DataBuffer` also has methods to
|
Besides the reading and writing functionality mentioned above, the `DataBuffer` also has methods to
|
||||||
view a (slice of a) buffer as `ByteBuffer`, `InputStream`, or `OutputStream`.
|
view a (slice of a) buffer as a `ByteBuffer`, an `InputStream`, or an `OutputStream`.
|
||||||
Additionally, it offers methods to determine the index of a given byte.
|
Additionally, it offers methods to determine the index of a given byte.
|
||||||
|
|
||||||
There are two implementation of `DataBuffer`: the `NettyDataBuffer` which is meant to be used on
|
As mentioned earlier, there are two implementation of `DataBufferFactory`: the `NettyDataBufferFactory`
|
||||||
Netty platforms, such as Reactor Netty.
|
(for Netty platforms, such as Reactor Netty) and
|
||||||
The other implementation, the `DefaultDataBuffer`, is used on other platforms, such as Servlet 3.1+
|
`DefaultDataBufferFactory` (for other platforms, such as
|
||||||
servers.
|
Servlet 3.1+ servers).
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -71,41 +66,42 @@ servers.
|
||||||
|
|
||||||
The `PooledDataBuffer` is an extension to `DataBuffer` that adds methods for reference counting.
|
The `PooledDataBuffer` is an extension to `DataBuffer` that adds methods for reference counting.
|
||||||
The `retain` method increases the reference count by one.
|
The `retain` method increases the reference count by one.
|
||||||
The `release` method decreases the count by one, and releases the buffer's memory when the count
|
The `release` method decreases the count by one and releases the buffer's memory when the count
|
||||||
reaches 0.
|
reaches 0.
|
||||||
Both of these methods are related to _reference counting_, a mechanism that is explained below.
|
Both of these methods are related to reference counting, a mechanism that we explain <<databuffer-reference-counting,later>>.
|
||||||
|
|
||||||
Note that `DataBufferUtils` offers useful utility methods for releasing and retaining pooled data
|
Note that `DataBufferUtils` offers useful utility methods for releasing and retaining pooled data
|
||||||
buffers.
|
buffers.
|
||||||
These methods take a plain `DataBuffer` as parameter, but only call `retain` or `release` if the
|
These methods take a plain `DataBuffer` as a parameter but only call `retain` or `release` if the
|
||||||
passed data buffer is an instance of `PooledDataBuffer`.
|
passed data buffer is an instance of `PooledDataBuffer`.
|
||||||
|
|
||||||
|
|
||||||
[[databuffer-reference-counting]]
|
[[databuffer-reference-counting]]
|
||||||
==== Reference Counting
|
==== Reference Counting
|
||||||
|
|
||||||
Reference counting is not a common technique in Java; it is much more common in other programming
|
Reference counting is not a common technique in Java. It is much more common in other programming
|
||||||
languages such as Object C and C++.
|
languages, such as Object C and C++.
|
||||||
In and of itself, reference counting is not complex: it basically involves tracking the number of
|
In and of itself, reference counting is not complex. It basically involves tracking the number of
|
||||||
references that apply to an object.
|
references that apply to an object.
|
||||||
The reference count of a `PooledDataBuffer` starts at 1, is incremented by calling `retain`,
|
The reference count of a `PooledDataBuffer` starts at 1, is incremented by calling `retain`,
|
||||||
and decremented by calling `release`.
|
and is decremented by calling `release`.
|
||||||
As long as the buffer's reference count is larger than 0 the buffer will not be released.
|
As long as the buffer's reference count is larger than 0, the buffer is not released.
|
||||||
When the number decreases to 0, the instance will be released.
|
When the number decreases to 0, the instance is released.
|
||||||
In practice, this means that the reserved memory captured by the buffer will be returned back to
|
In practice, this means that the reserved memory captured by the buffer is returned back to
|
||||||
the memory pool, ready to be used for future allocations.
|
the memory pool, ready to be used for future allocations.
|
||||||
|
|
||||||
In general, _the last component to access a `DataBuffer` is responsible for releasing it_.
|
In general, the last component to access a `DataBuffer` is responsible for releasing it.
|
||||||
Within Spring, there are two sorts of components that release buffers: decoders and transports.
|
Within Spring, there are two sorts of components that release buffers: decoders and transports.
|
||||||
Decoders are responsible for transforming a stream of buffers into other types (see <<codecs>> below),
|
Decoders are responsible for transforming a stream of buffers into other types (see <<codecs>>),
|
||||||
and transports are responsible for sending buffers across a network boundary, typically as an HTTP message.
|
and transports are responsible for sending buffers across a network boundary, typically as an HTTP message.
|
||||||
This means that if you allocate data buffers for the purpose of putting them into an outbound HTTP
|
This means that, if you allocate data buffers for the purpose of putting them into an outbound HTTP
|
||||||
message (i.e. client-side request or server-side response), they do not have to be released.
|
message (that is, a client-side request or server-side response), they do not have to be released.
|
||||||
The other consequence of this rule is that if you allocate data buffers that do not end up in the
|
The other consequence of this rule is that if you allocate data buffers that do not end up in the
|
||||||
body, for instance because of a thrown exception, you will have to release them yourself.
|
body (for instance, because of a thrown exception), you have to release them yourself.
|
||||||
The following snippet shows a typical `DataBuffer` usage scenario when dealing with methods that
|
The following snippet shows a typical `DataBuffer` usage scenario when dealing with methods that
|
||||||
throw exceptions:
|
throw exceptions:
|
||||||
|
|
||||||
|
====
|
||||||
[source,java,indent=0]
|
[source,java,indent=0]
|
||||||
[subs="verbatim,quotes"]
|
[subs="verbatim,quotes"]
|
||||||
----
|
----
|
||||||
|
|
@ -130,46 +126,49 @@ throw exceptions:
|
||||||
|
|
||||||
<1> A new buffer is allocated.
|
<1> A new buffer is allocated.
|
||||||
<2> A boolean flag indicates whether the allocated buffer should be released.
|
<2> A boolean flag indicates whether the allocated buffer should be released.
|
||||||
<3> This example method loads data into the buffer. Note that the method can throw an `IOException`,
|
<3> This example method loads data into the buffer. Note that the method can throw an `IOException`.
|
||||||
and therefore a `finally` block to release the buffer is required.
|
Therefore, a `finally` block to release the buffer is required.
|
||||||
<4> If no exception occurred, we switch the `release` flag to `false` as the buffer will now be
|
<4> If no exception occurred, we switch the `release` flag to `false` as the buffer is now
|
||||||
released as part of sending the HTTP body across the wire.
|
released as part of sending the HTTP body across the wire.
|
||||||
<5> If an exception did occur, the flag is still set to `true`, and the buffer will be released
|
<5> If an exception did occur, the flag is still set to `true`, and the buffer is released
|
||||||
here.
|
here.
|
||||||
|
====
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
=== DataBufferUtils
|
=== `DataBufferUtils`
|
||||||
|
|
||||||
`DataBufferUtils` contains various utility methods that operate on data buffers.
|
The `DataBufferUtils` class contains various utility methods that operate on data buffers.
|
||||||
It contains methods for reading a `Flux` of `DataBuffer` objects from an `InputStream` or NIO
|
It contains methods for reading a `Flux` of `DataBuffer` objects from an `InputStream` or NIO
|
||||||
`Channel`, and methods for writing a data buffer `Flux` to an `OutputStream` or `Channel`.
|
`Channel` and methods for writing a data buffer `Flux` to an `OutputStream` or `Channel`.
|
||||||
`DataBufferUtils` also exposes `retain` and `release` methods that operate on plain `DataBuffer`
|
`DataBufferUtils` also exposes `retain` and `release` methods that operate on plain `DataBuffer`
|
||||||
instances (so that casting to a `PooledDataBuffer` is not required).
|
instances (so that casting to a `PooledDataBuffer` is not required).
|
||||||
|
|
||||||
Additionally, `DataBufferUtils` exposes `compose`, which merges a stream of data buffers into one.
|
Additionally, `DataBufferUtils` exposes `compose`, which merges a stream of data buffers into one.
|
||||||
For instance, this method can be used to convert the entire HTTP body into a single buffer (and
|
For instance, this method can be used to convert the entire HTTP body into a single buffer (and
|
||||||
from that, a `String`, or `InputStream`).
|
from that, a `String` or `InputStream`).
|
||||||
This is particularly useful when dealing with older, blocking APIs.
|
This is particularly useful when dealing with older, blocking APIs.
|
||||||
Note, however, that this puts the entire body in memory, and therefore uses more memory than a pure
|
Note, however, that this puts the entire body in memory, and therefore uses more memory than a pure
|
||||||
streaming solution would.
|
streaming solution would.
|
||||||
|
|
||||||
[codecs]
|
|
||||||
|
|
||||||
|
[[codecs]]
|
||||||
== Codecs
|
== Codecs
|
||||||
|
|
||||||
The `org.springframework.core.codec` package contains the two main abstractions for converting a
|
The `org.springframework.core.codec` package contains the two main abstractions for converting a
|
||||||
stream of bytes into a stream of objects, or vice-versa.
|
stream of bytes into a stream of objects or vice-versa.
|
||||||
The `Encoder` is a strategy interface that encodes a stream of objects into an output stream of
|
The `Encoder` is a strategy interface that encodes a stream of objects into an output stream of
|
||||||
data buffers.
|
data buffers.
|
||||||
The `Decoder` does the reverse: it turns a stream of data buffers into a stream of objects.
|
The `Decoder` does the reverse: It turns a stream of data buffers into a stream of objects.
|
||||||
Note that a decoder instance needs to consider <<databuffer-reference-counting, reference counting>>.
|
Note that a decoder instance needs to consider <<databuffer-reference-counting,reference counting>>.
|
||||||
|
|
||||||
Spring comes with a wide array of default codecs, capable of converting from/to `String`,
|
Spring comes with a wide array of default codecs (to convert from and to `String`,
|
||||||
`ByteBuffer`, byte arrays, and also codecs that support marshalling libraries such as JAXB and
|
`ByteBuffer`, and byte arrays) and codecs that support marshalling libraries such as JAXB and
|
||||||
Jackson (with https://github.com/FasterXML/jackson-core/issues/57[Jackson 2.9+ support for non-blocking parsing]).
|
Jackson (with https://github.com/FasterXML/jackson-core/issues/57[Jackson 2.9+ support for non-blocking parsing]).
|
||||||
Within the context of Spring WebFlux, codecs are used to convert the request body into a
|
Within the context of Spring WebFlux, codecs are used to convert the request body into a
|
||||||
`@RequestMapping` parameter, or to convert the return type into the response body that is sent back
|
`@RequestMapping` parameter or to convert the return type into the response body that is sent back
|
||||||
to the client.
|
to the client.
|
||||||
The default codecs are configured in the `WebFluxConfigurationSupport` class, and can easily be
|
The default codecs are configured in the `WebFluxConfigurationSupport` class. You can
|
||||||
changed by overriding the `configureHttpMessageCodecs` when inheriting from that class.
|
change them by overriding the `configureHttpMessageCodecs` when you inherit from that class.
|
||||||
For more information about using codecs in WebFlux, see <<web-reactive#webflux-codecs, this section>>.
|
For more information about using codecs in WebFlux, see <<web-reactive#webflux-codecs>>.
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,19 +1,19 @@
|
||||||
[[null-safety]]
|
[[null-safety]]
|
||||||
= Null-safety
|
= Null-safety
|
||||||
|
|
||||||
Although Java does not allow to express null-safety with its type system, Spring Framework
|
Although Java does not let you express null-safety with its type system, Spring Framework
|
||||||
now provides following annotations in the `org.springframework.lang` package to declare
|
now provides the following annotations in the `org.springframework.lang` package to let you declare
|
||||||
nullability of APIs and fields:
|
nullability of APIs and fields:
|
||||||
|
|
||||||
* {api-spring-framework}/lang/NonNull.html[`@NonNull`] annotation where specific parameter,
|
* {api-spring-framework}/lang/NonNull.html[`@NonNull`]: Annotation to indicate that a specific parameter,
|
||||||
return value or field cannot be `null` (not needed on parameter and return value
|
return value, or field cannot be `null` (not needed on parameter and return value
|
||||||
where `@NonNullApi` and `@NonNullFields` apply) .
|
where `@NonNullApi` and `@NonNullFields` apply) .
|
||||||
* {api-spring-framework}/lang/Nullable.html[`@Nullable`] annotation where specific
|
* {api-spring-framework}/lang/Nullable.html[`@Nullable`]: Annotation to indicate that a specific
|
||||||
parameter, return value or field can be `null`.
|
parameter, return value, or field can be `null`.
|
||||||
* {api-spring-framework}/lang/NonNullApi.html[`@NonNullApi`] annotation at package level
|
* {api-spring-framework}/lang/NonNullApi.html[`@NonNullApi`]: Annotation at the package level
|
||||||
declares non-null as the default behavior for parameters and return values.
|
that declares non-null as the default behavior for parameters and return values.
|
||||||
* {api-spring-framework}/lang/NonNullFields.html[`@NonNullFields`] annotation at package
|
* {api-spring-framework}/lang/NonNullFields.html[`@NonNullFields`]: Annotation at the package
|
||||||
level declares non-null as the default behavior for fields.
|
level that declares non-null as the default behavior for fields.
|
||||||
|
|
||||||
Spring Framework leverages itself these annotations, but they can also be used in any Spring based
|
Spring Framework leverages itself these annotations, but they can also be used in any Spring based
|
||||||
Java project to declare null-safe APIs and optionally null-safe fields. Generic type arguments,
|
Java project to declare null-safe APIs and optionally null-safe fields. Generic type arguments,
|
||||||
|
|
@ -23,34 +23,30 @@ Nullability declaration are expected to be fine-tuned between Spring Framework r
|
||||||
including minor ones. Nullability of types used inside method bodies is outside of the
|
including minor ones. Nullability of types used inside method bodies is outside of the
|
||||||
scope of this feature.
|
scope of this feature.
|
||||||
|
|
||||||
[NOTE]
|
NOTE: Libraries like Reactor or Spring Data provide null-safe APIs that use this feature.
|
||||||
====
|
|
||||||
Libraries like Reactor or Spring Data provide null-safe APIs leveraging this feature.
|
|
||||||
====
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
== Use cases
|
== Use cases
|
||||||
|
|
||||||
In addition to providing an explicit declaration for Spring Framework API nullability,
|
In addition to providing an explicit declaration for Spring Framework API nullability,
|
||||||
these annotation can be used by IDE (such as IDEA or Eclipse) to provide useful
|
these annotations can be used by an IDE (such as IDEA or Eclipse) to provide useful
|
||||||
warnings to Java developers related to null-safety in order to avoid `NullPointerException`
|
warnings related to null-safety in order to avoid `NullPointerException`
|
||||||
at runtime.
|
at runtime.
|
||||||
|
|
||||||
They are also used to make Spring API null-safe in Kotlin projects since Kotlin natively
|
They are also used to make Spring API null-safe in Kotlin projects, since Kotlin natively
|
||||||
supports https://kotlinlang.org/docs/reference/null-safety.html[null-safety]. More details
|
supports https://kotlinlang.org/docs/reference/null-safety.html[null-safety]. More details
|
||||||
are available in <<languages#kotlin-null-safety,Kotlin support documentation>>.
|
are available in the <<languages#kotlin-null-safety,Kotlin support documentation>>.
|
||||||
|
|
||||||
== JSR 305 meta-annotations
|
== JSR 305 meta-annotations
|
||||||
|
|
||||||
Spring annotations are meta-annotated with https://jcp.org/en/jsr/detail?id=305[JSR 305]
|
Spring annotations are meta-annotated with https://jcp.org/en/jsr/detail?id=305[JSR 305]
|
||||||
annotations (a dormant but widely spread JSR). JSR 305 meta-annotations allows tooling vendors
|
annotations (a dormant but widely spread JSR). JSR 305 meta-annotations let tooling vendors
|
||||||
like IDEA or Kotlin to provide null-safety support in a generic way, without having to hard-code
|
like IDEA or Kotlin provide null-safety support in a generic way, without having to hard-code
|
||||||
support for Spring annotations.
|
support for Spring annotations.
|
||||||
|
|
||||||
It is not necessary nor recommended to add JSR 305 dependency in project classpath to
|
It is not necessary nor recommended to add JSR 305 dependency in the project classpath to
|
||||||
take advantage of Spring null-safe API. Only projects like
|
take advantage of Spring null-safe API. Only projects such as
|
||||||
Spring-based libraries using null-safety annotations in their codebase should add
|
Spring-based libraries that use null-safety annotations in their codebase should add
|
||||||
`com.google.code.findbugs:jsr305:3.0.2` with `compileOnly` Gradle configuration or Maven
|
`com.google.code.findbugs:jsr305:3.0.2` with `compileOnly` Gradle configuration or Maven
|
||||||
`provided` scope to avoid compile warnings.
|
`provided` scope to avoid compile warnings.
|
||||||
|
|
|
||||||
|
|
@ -1,16 +1,26 @@
|
||||||
[[resources]]
|
[[resources]]
|
||||||
= Resources
|
= Resources
|
||||||
|
|
||||||
|
This chapter covers how Spring handles resources and how you can work with resources in
|
||||||
|
Spring. It includes the following topics:
|
||||||
|
|
||||||
|
* <<resources-introduction>>
|
||||||
|
* <<resources-resource>>
|
||||||
|
* <<resources-implementations>>
|
||||||
|
* <<resources-resourceloader>>
|
||||||
|
* <<resources-resourceloaderaware>>
|
||||||
|
* <<resources-as-dependencies>>
|
||||||
|
* <<resources-app-ctx>>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[[resources-introduction]]
|
[[resources-introduction]]
|
||||||
== Introduction
|
== Introduction
|
||||||
|
|
||||||
Java's standard `java.net.URL` class and standard handlers for various URL prefixes
|
Java's standard `java.net.URL` class and standard handlers for various URL prefixes,
|
||||||
unfortunately are not quite adequate enough for all access to low-level resources. For
|
unfortunately, are not quite adequate enough for all access to low-level resources. For
|
||||||
example, there is no standardized `URL` implementation that may be used to access a
|
example, there is no standardized `URL` implementation that may be used to access a
|
||||||
resource that needs to be obtained from the classpath, or relative to a
|
resource that needs to be obtained from the classpath or relative to a
|
||||||
`ServletContext`. While it is possible to register new handlers for specialized `URL`
|
`ServletContext`. While it is possible to register new handlers for specialized `URL`
|
||||||
prefixes (similar to existing handlers for prefixes such as `http:`), this is generally
|
prefixes (similar to existing handlers for prefixes such as `http:`), this is generally
|
||||||
quite complicated, and the `URL` interface still lacks some desirable functionality,
|
quite complicated, and the `URL` interface still lacks some desirable functionality,
|
||||||
|
|
@ -18,13 +28,14 @@ such as a method to check for the existence of the resource being pointed to.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[[resources-resource]]
|
[[resources-resource]]
|
||||||
== The Resource interface
|
== The Resource Interface
|
||||||
|
|
||||||
Spring's `Resource` interface is meant to be a more capable interface for abstracting
|
Spring's `Resource` interface is meant to be a more capable interface for abstracting
|
||||||
access to low-level resources.
|
access to low-level resources. The following listing shows the `Resource` interface
|
||||||
|
definition:
|
||||||
|
|
||||||
|
====
|
||||||
[source,java,indent=0]
|
[source,java,indent=0]
|
||||||
[subs="verbatim,quotes"]
|
[subs="verbatim,quotes"]
|
||||||
----
|
----
|
||||||
|
|
@ -46,7 +57,13 @@ access to low-level resources.
|
||||||
|
|
||||||
}
|
}
|
||||||
----
|
----
|
||||||
|
====
|
||||||
|
|
||||||
|
As the definition of the `Resource` interface shows, it extends the `InputStreamSource`
|
||||||
|
interface. The following listing shows the definition of the `InputStreamSource`
|
||||||
|
interface:
|
||||||
|
|
||||||
|
====
|
||||||
[source,java,indent=0]
|
[source,java,indent=0]
|
||||||
[subs="verbatim,quotes"]
|
[subs="verbatim,quotes"]
|
||||||
----
|
----
|
||||||
|
|
@ -56,151 +73,158 @@ access to low-level resources.
|
||||||
|
|
||||||
}
|
}
|
||||||
----
|
----
|
||||||
|
====
|
||||||
|
|
||||||
Some of the most important methods from the `Resource` interface are:
|
Some of the most important methods from the `Resource` interface are:
|
||||||
|
|
||||||
* `getInputStream()`: locates and opens the resource, returning an `InputStream` for
|
* `getInputStream()`: Locates and opens the resource, returning an `InputStream` for
|
||||||
reading from the resource. It is expected that each invocation returns a fresh
|
reading from the resource. It is expected that each invocation returns a fresh
|
||||||
`InputStream`. It is the responsibility of the caller to close the stream.
|
`InputStream`. It is the responsibility of the caller to close the stream.
|
||||||
* `exists()`: returns a `boolean` indicating whether this resource actually exists in
|
* `exists()`: Returns a `boolean` indicating whether this resource actually exists in
|
||||||
physical form.
|
physical form.
|
||||||
* `isOpen()`: returns a `boolean` indicating whether this resource represents a handle
|
* `isOpen()`: Returns a `boolean` indicating whether this resource represents a handle
|
||||||
with an open stream. If `true`, the `InputStream` cannot be read multiple times, and
|
with an open stream. If `true`, the `InputStream` cannot be read multiple times and
|
||||||
must be read once only and then closed to avoid resource leaks. Will be `false` for
|
must be read once only and then closed to avoid resource leaks. Returns `false` for
|
||||||
all usual resource implementations, with the exception of `InputStreamResource`.
|
all usual resource implementations, with the exception of `InputStreamResource`.
|
||||||
* `getDescription()`: returns a description for this resource, to be used for error
|
* `getDescription()`: Returns a description for this resource, to be used for error
|
||||||
output when working with the resource. This is often the fully qualified file name or
|
output when working with the resource. This is often the fully qualified file name or
|
||||||
the actual URL of the resource.
|
the actual URL of the resource.
|
||||||
|
|
||||||
Other methods allow you to obtain an actual `URL` or `File` object representing the
|
Other methods let you obtain an actual `URL` or `File` object representing the
|
||||||
resource (if the underlying implementation is compatible, and supports that
|
resource (if the underlying implementation is compatible and supports that
|
||||||
functionality).
|
functionality).
|
||||||
|
|
||||||
The `Resource` abstraction is used extensively in Spring itself, as an argument type in
|
Spring itself uses the `Resource` abstraction extensively, as an argument type in
|
||||||
many method signatures when a resource is needed. Other methods in some Spring APIs
|
many method signatures when a resource is needed. Other methods in some Spring APIs
|
||||||
(such as the constructors to various `ApplicationContext` implementations), take a
|
(such as the constructors to various `ApplicationContext` implementations) take a
|
||||||
`String` which in unadorned or simple form is used to create a `Resource` appropriate to
|
`String` which in unadorned or simple form is used to create a `Resource` appropriate to
|
||||||
that context implementation, or via special prefixes on the `String` path, allow the
|
that context implementation or, via special prefixes on the `String` path, let the
|
||||||
caller to specify that a specific `Resource` implementation must be created and used.
|
caller specify that a specific `Resource` implementation must be created and used.
|
||||||
|
|
||||||
While the `Resource` interface is used a lot with Spring and by Spring, it's actually
|
While the `Resource` interface is used a lot with Spring and by Spring, it is actually
|
||||||
very useful to use as a general utility class by itself in your own code, for access to
|
very useful to use as a general utility class by itself in your own code, for access to
|
||||||
resources, even when your code doesn't know or care about any other parts of Spring.
|
resources, even when your code does not know or care about any other parts of Spring.
|
||||||
While this couples your code to Spring, it really only couples it to this small set of
|
While this couples your code to Spring, it really only couples it to this small set of
|
||||||
utility classes, which are serving as a more capable replacement for `URL`, and can be
|
utility classes, which serve as a more capable replacement for `URL` and can be
|
||||||
considered equivalent to any other library you would use for this purpose.
|
considered equivalent to any other library you would use for this purpose.
|
||||||
|
|
||||||
It is important to note that the `Resource` abstraction does not replace functionality:
|
NOTE: The `Resource` abstraction does not replace functionality.
|
||||||
it wraps it where possible. For example, a `UrlResource` wraps a URL, and uses the
|
It wraps it where possible. For example, a `UrlResource` wraps a URL and uses the
|
||||||
wrapped `URL` to do its work.
|
wrapped `URL` to do its work.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[[resources-implementations]]
|
[[resources-implementations]]
|
||||||
== Built-in Resource implementations
|
== Built-in Resource Implementations
|
||||||
|
|
||||||
There are a number of `Resource` implementations that come supplied straight out of the
|
Spring includes the following `Resource` implementations:
|
||||||
box in Spring:
|
|
||||||
|
* <<resources-implementations-urlresource>>
|
||||||
|
* <<resources-implementations-classpathresource>>
|
||||||
|
* <<resources-implementations-filesystemresource>>
|
||||||
|
* <<resources-implementations-servletcontextresource>>
|
||||||
|
* <<resources-implementations-inputstreamresource>>
|
||||||
|
* <<resources-implementations-bytearrayresource>>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[[resources-implementations-urlresource]]
|
[[resources-implementations-urlresource]]
|
||||||
=== UrlResource
|
=== `UrlResource`
|
||||||
|
|
||||||
The `UrlResource` wraps a `java.net.URL`, and may be used to access any object that is
|
`UrlResource` wraps a `java.net.URL` and can be used to access any object that is
|
||||||
normally accessible via a URL, such as files, an HTTP target, an FTP target, etc. All
|
normally accessible with a URL, such as files, an HTTP target, an FTP target, and others. All
|
||||||
URLs have a standardized `String` representation, such that appropriate standardized
|
URLs have a standardized `String` representation, such that appropriate standardized
|
||||||
prefixes are used to indicate one URL type from another. This includes `file:` for
|
prefixes are used to indicate one URL type from another. This includes `file:` for
|
||||||
accessing filesystem paths, `http:` for accessing resources via the HTTP protocol,
|
accessing filesystem paths, `http:` for accessing resources through the HTTP protocol,
|
||||||
`ftp:` for accessing resources via FTP, etc.
|
`ftp:` for accessing resources through FTP, and others.
|
||||||
|
|
||||||
A `UrlResource` is created by Java code explicitly using the `UrlResource` constructor,
|
A `UrlResource` is created by Java code by explicitly using the `UrlResource` constructor
|
||||||
but will often be created implicitly when you call an API method which takes a `String`
|
but is often created implicitly when you call an API method that takes a `String`
|
||||||
argument which is meant to represent a path. For the latter case, a JavaBeans
|
argument meant to represent a path. For the latter case, a JavaBeans
|
||||||
`PropertyEditor` will ultimately decide which type of `Resource` to create. If the path
|
`PropertyEditor` ultimately decides which type of `Resource` to create. If the path
|
||||||
string contains a few well-known (to it, that is) prefixes such as `classpath:`, it will
|
string contains well-known (to it, that is) prefix (such as `classpath:`), it
|
||||||
create an appropriate specialized `Resource` for that prefix. However, if it doesn't
|
creates an appropriate specialized `Resource` for that prefix. However, if it does not
|
||||||
recognize the prefix, it will assume the this is just a standard URL string, and will
|
recognize the prefix, it assume the string is a standard URL string and
|
||||||
create a `UrlResource`.
|
creates a `UrlResource`.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[[resources-implementations-classpathresource]]
|
[[resources-implementations-classpathresource]]
|
||||||
=== ClassPathResource
|
=== `ClassPathResource`
|
||||||
|
|
||||||
This class represents a resource which should be obtained from the classpath. This uses
|
This class represents a resource that should be obtained from the classpath. It uses
|
||||||
either the thread context class loader, a given class loader, or a given class for
|
either the thread context class loader, a given class loader, or a given class for
|
||||||
loading resources.
|
loading resources.
|
||||||
|
|
||||||
This `Resource` implementation supports resolution as `java.io.File` if the class path
|
This `Resource` implementation supports resolution as `java.io.File` if the class path
|
||||||
resource resides in the file system, but not for classpath resources which reside in a
|
resource resides in the file system but not for classpath resources that reside in a
|
||||||
jar and have not been expanded (by the servlet engine, or whatever the environment is)
|
jar and have not been expanded (by the servlet engine or whatever the environment is)
|
||||||
to the filesystem. To address this the various `Resource` implementations always support
|
to the filesystem. To address this, the various `Resource` implementations always support
|
||||||
resolution as a `java.net.URL`.
|
resolution as a `java.net.URL`.
|
||||||
|
|
||||||
A `ClassPathResource` is created by Java code explicitly using the `ClassPathResource`
|
A `ClassPathResource` is created by Java code by explicitly using the `ClassPathResource`
|
||||||
constructor, but will often be created implicitly when you call an API method which
|
constructor but is often created implicitly when you call an API method that
|
||||||
takes a `String` argument which is meant to represent a path. For the latter case, a
|
takes a `String` argument meant to represent a path. For the latter case, a
|
||||||
JavaBeans `PropertyEditor` will recognize the special prefix `classpath:` on the string
|
JavaBeans `PropertyEditor` recognizes the special prefix, `classpath:`, on the string
|
||||||
path, and create a `ClassPathResource` in that case.
|
path and creates a `ClassPathResource` in that case.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[[resources-implementations-filesystemresource]]
|
[[resources-implementations-filesystemresource]]
|
||||||
=== FileSystemResource
|
=== `FileSystemResource`
|
||||||
|
|
||||||
This is a `Resource` implementation for `java.io.File` handles. It obviously supports
|
This is a `Resource` implementation for `java.io.File` handles. It supports
|
||||||
resolution as a `File`, and as a `URL`.
|
resolution as a `File` and as a `URL`.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[[resources-implementations-servletcontextresource]]
|
[[resources-implementations-servletcontextresource]]
|
||||||
=== ServletContextResource
|
=== `ServletContextResource`
|
||||||
|
|
||||||
This is a `Resource` implementation for `ServletContext` resources, interpreting
|
This is a `Resource` implementation for `ServletContext` resources that interprets
|
||||||
relative paths within the relevant web application's root directory.
|
relative paths within the relevant web application's root directory.
|
||||||
|
|
||||||
This always supports stream access and URL access, but only allows `java.io.File` access
|
It always supports stream access and URL access but allows `java.io.File` access only
|
||||||
when the web application archive is expanded and the resource is physically on the
|
when the web application archive is expanded and the resource is physically on the
|
||||||
filesystem. Whether or not it's expanded and on the filesystem like this, or accessed
|
filesystem. Whether or not it is expanded and on the filesystem or accessed
|
||||||
directly from the JAR or somewhere else like a DB (it's conceivable) is actually
|
directly from the JAR or somewhere else like a database (which is conceivable) is actually
|
||||||
dependent on the Servlet container.
|
dependent on the Servlet container.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[[resources-implementations-inputstreamresource]]
|
[[resources-implementations-inputstreamresource]]
|
||||||
=== InputStreamResource
|
=== `InputStreamResource`
|
||||||
|
|
||||||
A `Resource` implementation for a given `InputStream`. This should only be used if no
|
An `InputStreamResource` is a `Resource` implementation for a given `InputStream`. It should be used only if no
|
||||||
specific `Resource` implementation is applicable. In particular, prefer
|
specific `Resource` implementation is applicable. In particular, prefer
|
||||||
`ByteArrayResource` or any of the file-based `Resource` implementations where possible.
|
`ByteArrayResource` or any of the file-based `Resource` implementations where possible.
|
||||||
|
|
||||||
In contrast to other `Resource` implementations, this is a descriptor for an __already__
|
In contrast to other `Resource` implementations, this is a descriptor for an already-opened
|
||||||
opened resource - therefore returning `true` from `isOpen()`. Do not use it if you need
|
resource. Therefore, it returns `true` from `isOpen()`. Do not use it if you need
|
||||||
to keep the resource descriptor somewhere, or if you need to read a stream multiple
|
to keep the resource descriptor somewhere or if you need to read a stream multiple
|
||||||
times.
|
times.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[[resources-implementations-bytearrayresource]]
|
[[resources-implementations-bytearrayresource]]
|
||||||
=== ByteArrayResource
|
=== `ByteArrayResource`
|
||||||
|
|
||||||
This is a `Resource` implementation for a given byte array. It creates a
|
This is a `Resource` implementation for a given byte array. It creates a
|
||||||
`ByteArrayInputStream` for the given byte array.
|
`ByteArrayInputStream` for the given byte array.
|
||||||
|
|
||||||
It's useful for loading content from any given byte array, without having to resort to a
|
It is useful for loading content from any given byte array without having to resort to a
|
||||||
single-use `InputStreamResource`.
|
single-use `InputStreamResource`.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[[resources-resourceloader]]
|
[[resources-resourceloader]]
|
||||||
== The ResourceLoader
|
== The `ResourceLoader`
|
||||||
|
|
||||||
The `ResourceLoader` interface is meant to be implemented by objects that can return
|
The `ResourceLoader` interface is meant to be implemented by objects that can return
|
||||||
(i.e. load) `Resource` instances.
|
(that is, load) `Resource` instances. The following listing shows the `ResourceLoader`
|
||||||
|
interface definition:
|
||||||
|
|
||||||
|
====
|
||||||
[source,java,indent=0]
|
[source,java,indent=0]
|
||||||
[subs="verbatim,quotes"]
|
[subs="verbatim,quotes"]
|
||||||
----
|
----
|
||||||
|
|
@ -210,41 +234,49 @@ The `ResourceLoader` interface is meant to be implemented by objects that can re
|
||||||
|
|
||||||
}
|
}
|
||||||
----
|
----
|
||||||
|
====
|
||||||
|
|
||||||
All application contexts implement the `ResourceLoader` interface, and therefore all
|
All application contexts implement the `ResourceLoader` interface. Therefore, all
|
||||||
application contexts may be used to obtain `Resource` instances.
|
application contexts may be used to obtain `Resource` instances.
|
||||||
|
|
||||||
When you call `getResource()` on a specific application context, and the location path
|
When you call `getResource()` on a specific application context, and the location path
|
||||||
specified doesn't have a specific prefix, you will get back a `Resource` type that is
|
specified doesn't have a specific prefix, you get back a `Resource` type that is
|
||||||
appropriate to that particular application context. For example, assume the following
|
appropriate to that particular application context. For example, assume the following
|
||||||
snippet of code was executed against a `ClassPathXmlApplicationContext` instance:
|
snippet of code was executed against a `ClassPathXmlApplicationContext` instance:
|
||||||
|
|
||||||
|
====
|
||||||
[source,java,indent=0]
|
[source,java,indent=0]
|
||||||
[subs="verbatim,quotes"]
|
[subs="verbatim,quotes"]
|
||||||
----
|
----
|
||||||
Resource template = ctx.getResource("some/resource/path/myTemplate.txt");
|
Resource template = ctx.getResource("some/resource/path/myTemplate.txt");
|
||||||
----
|
----
|
||||||
|
====
|
||||||
|
|
||||||
What would be returned would be a `ClassPathResource`; if the same method was executed
|
Against a `ClassPathXmlApplicationContext`, that code returns a `ClassPathResource`. If the same method were executed
|
||||||
against a `FileSystemXmlApplicationContext` instance, you'd get back a
|
against a `FileSystemXmlApplicationContext` instance, it would return a
|
||||||
`FileSystemResource`. For a `WebApplicationContext`, you'd get back a
|
`FileSystemResource`. For a `WebApplicationContext`, it would return a
|
||||||
`ServletContextResource`, and so on.
|
`ServletContextResource`. It would similarly return appropriate objects for each context.
|
||||||
|
|
||||||
As such, you can load resources in a fashion appropriate to the particular application
|
As a result, you can load resources in a fashion appropriate to the particular application
|
||||||
context.
|
context.
|
||||||
|
|
||||||
On the other hand, you may also force `ClassPathResource` to be used, regardless of the
|
On the other hand, you may also force `ClassPathResource` to be used, regardless of the
|
||||||
application context type, by specifying the special `classpath:` prefix:
|
application context type, by specifying the special `classpath:` prefix, as the following
|
||||||
|
example shows:
|
||||||
|
|
||||||
|
====
|
||||||
[source,java,indent=0]
|
[source,java,indent=0]
|
||||||
[subs="verbatim,quotes"]
|
[subs="verbatim,quotes"]
|
||||||
----
|
----
|
||||||
Resource template = ctx.getResource("classpath:some/resource/path/myTemplate.txt");
|
Resource template = ctx.getResource("classpath:some/resource/path/myTemplate.txt");
|
||||||
----
|
----
|
||||||
|
====
|
||||||
|
|
||||||
Similarly, one can force a `UrlResource` to be used by specifying any of the standard
|
Similarly, you can force a `UrlResource` to be used by specifying any of the standard
|
||||||
`java.net.URL` prefixes:
|
`java.net.URL` prefixes. The following pair of examples use the `file` and `http`
|
||||||
|
prefixes:
|
||||||
|
|
||||||
|
====
|
||||||
[source,java,indent=0]
|
[source,java,indent=0]
|
||||||
[subs="verbatim,quotes"]
|
[subs="verbatim,quotes"]
|
||||||
----
|
----
|
||||||
|
|
@ -256,8 +288,9 @@ Similarly, one can force a `UrlResource` to be used by specifying any of the sta
|
||||||
----
|
----
|
||||||
Resource template = ctx.getResource("http://myhost.com/resource/path/myTemplate.txt");
|
Resource template = ctx.getResource("http://myhost.com/resource/path/myTemplate.txt");
|
||||||
----
|
----
|
||||||
|
====
|
||||||
|
|
||||||
The following table summarizes the strategy for converting ``String``s to ``Resource``s:
|
The following table summarizes the strategy for converting `String` objects to `Resource` objects:
|
||||||
|
|
||||||
[[resources-resource-strings]]
|
[[resources-resource-strings]]
|
||||||
.Resource strings
|
.Resource strings
|
||||||
|
|
@ -270,8 +303,7 @@ The following table summarizes the strategy for converting ``String``s to ``Reso
|
||||||
|
|
||||||
| file:
|
| file:
|
||||||
| `file:///data/config.xml`
|
| `file:///data/config.xml`
|
||||||
| Loaded as a `URL`, from the filesystem. footnote:[But see also
|
| Loaded as a `URL` from the filesystem. See also <<resources-filesystemresource-caveats>>.
|
||||||
pass:specialcharacters,macros[<<resources-filesystemresource-caveats>>].]
|
|
||||||
|
|
||||||
| http:
|
| http:
|
||||||
| `http://myserver/logo.png`
|
| `http://myserver/logo.png`
|
||||||
|
|
@ -284,13 +316,14 @@ The following table summarizes the strategy for converting ``String``s to ``Reso
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[[resources-resourceloaderaware]]
|
[[resources-resourceloaderaware]]
|
||||||
== The ResourceLoaderAware interface
|
== The `ResourceLoaderAware` interface
|
||||||
|
|
||||||
The `ResourceLoaderAware` interface is a special marker interface, identifying objects
|
The `ResourceLoaderAware` interface is a special marker interface that identifies objects
|
||||||
that expect to be provided with a `ResourceLoader` reference.
|
that expect to be provided with a `ResourceLoader` reference. The following listing shows
|
||||||
|
the definition of the `ResourceLoaderAware` interface:
|
||||||
|
|
||||||
|
====
|
||||||
[source,java,indent=0]
|
[source,java,indent=0]
|
||||||
[subs="verbatim,quotes"]
|
[subs="verbatim,quotes"]
|
||||||
----
|
----
|
||||||
|
|
@ -299,50 +332,51 @@ that expect to be provided with a `ResourceLoader` reference.
|
||||||
void setResourceLoader(ResourceLoader resourceLoader);
|
void setResourceLoader(ResourceLoader resourceLoader);
|
||||||
}
|
}
|
||||||
----
|
----
|
||||||
|
====
|
||||||
|
|
||||||
When a class implements `ResourceLoaderAware` and is deployed into an application
|
When a class implements `ResourceLoaderAware` and is deployed into an application
|
||||||
context (as a Spring-managed bean), it is recognized as `ResourceLoaderAware` by the
|
context (as a Spring-managed bean), it is recognized as `ResourceLoaderAware` by the
|
||||||
application context. The application context will then invoke the
|
application context. The application context then invokes
|
||||||
`setResourceLoader(ResourceLoader)`, supplying itself as the argument (remember, all
|
`setResourceLoader(ResourceLoader)`, supplying itself as the argument (remember, all
|
||||||
application contexts in Spring implement the `ResourceLoader` interface).
|
application contexts in Spring implement the `ResourceLoader` interface).
|
||||||
|
|
||||||
Of course, since an `ApplicationContext` is a `ResourceLoader`, the bean could also
|
Since an `ApplicationContext` is a `ResourceLoader`, the bean could also
|
||||||
implement the `ApplicationContextAware` interface and use the supplied application
|
implement the `ApplicationContextAware` interface and use the supplied application
|
||||||
context directly to load resources, but in general, it's better to use the specialized
|
context directly to load resources. However, in general, it is better to use the specialized
|
||||||
`ResourceLoader` interface if that's all that's needed. The code would just be coupled
|
`ResourceLoader` interface if that is all you need. The code would be coupled only
|
||||||
to the resource loading interface, which can be considered a utility interface, and not
|
to the resource loading interface (which can be considered a utility interface) and not to
|
||||||
the whole Spring `ApplicationContext` interface.
|
the whole Spring `ApplicationContext` interface.
|
||||||
|
|
||||||
As of Spring 2.5, you can rely upon autowiring of the `ResourceLoader` as an alternative
|
As of Spring 2.5, you can rely upon autowiring of the `ResourceLoader` as an alternative
|
||||||
to implementing the `ResourceLoaderAware` interface. The "traditional" `constructor` and
|
to implementing the `ResourceLoaderAware` interface. The "`traditional`" `constructor` and
|
||||||
`byType` autowiring modes (as described in <<beans-factory-autowire>>) are now capable
|
`byType` autowiring modes (as described in <<beans-factory-autowire>>) are now capable
|
||||||
of providing a dependency of type `ResourceLoader` for either a constructor argument or
|
of providing a dependency of type `ResourceLoader` for either a constructor argument or a
|
||||||
setter method parameter respectively. For more flexibility (including the ability to
|
setter method parameter, respectively. For more flexibility (including the ability to
|
||||||
autowire fields and multiple parameter methods), consider using the new annotation-based
|
autowire fields and multiple parameter methods), consider using the annotation-based
|
||||||
autowiring features. In that case, the `ResourceLoader` will be autowired into a field,
|
autowiring features. In that case, the `ResourceLoader` is autowired into a field,
|
||||||
constructor argument, or method parameter that is expecting the `ResourceLoader` type as
|
constructor argument, or method parameter that expects the `ResourceLoader` type as
|
||||||
long as the field, constructor, or method in question carries the `@Autowired`
|
long as the field, constructor, or method in question carries the `@Autowired`
|
||||||
annotation. For more information, see <<beans-autowired-annotation>>.
|
annotation. For more information, see <<beans-autowired-annotation>>.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[[resources-as-dependencies]]
|
[[resources-as-dependencies]]
|
||||||
== Resources as dependencies
|
== Resources as Dependencies
|
||||||
|
|
||||||
If the bean itself is going to determine and supply the resource path through some sort
|
If the bean itself is going to determine and supply the resource path through some sort
|
||||||
of dynamic process, it probably makes sense for the bean to use the `ResourceLoader`
|
of dynamic process, it probably makes sense for the bean to use the `ResourceLoader`
|
||||||
interface to load resources. Consider as an example the loading of a template of some
|
interface to load resources. For example, consider the loading of a template of some
|
||||||
sort, where the specific resource that is needed depends on the role of the user. If the
|
sort, where the specific resource that is needed depends on the role of the user. If the
|
||||||
resources are static, it makes sense to eliminate the use of the `ResourceLoader`
|
resources are static, it makes sense to eliminate the use of the `ResourceLoader`
|
||||||
interface completely, and just have the bean expose the `Resource` properties it needs,
|
interface completely, have the bean expose the `Resource` properties it needs,
|
||||||
and expect that they will be injected into it.
|
and expect them to be injected into it.
|
||||||
|
|
||||||
What makes it trivial to then inject these properties, is that all application contexts
|
What makes it trivial to then inject these properties is that all application contexts
|
||||||
register and use a special JavaBeans `PropertyEditor` which can convert `String` paths
|
register and use a special JavaBeans `PropertyEditor`, which can convert `String` paths
|
||||||
to `Resource` objects. So if `myBean` has a template property of type `Resource`, it can
|
to `Resource` objects. So, if `myBean` has a template property of type `Resource`, it can
|
||||||
be configured with a simple string for that resource, as follows:
|
be configured with a simple string for that resource, as the following example shows:
|
||||||
|
|
||||||
|
====
|
||||||
[source,xml,indent=0]
|
[source,xml,indent=0]
|
||||||
[subs="verbatim,quotes"]
|
[subs="verbatim,quotes"]
|
||||||
----
|
----
|
||||||
|
|
@ -350,16 +384,18 @@ be configured with a simple string for that resource, as follows:
|
||||||
<property name="template" value="some/resource/path/myTemplate.txt"/>
|
<property name="template" value="some/resource/path/myTemplate.txt"/>
|
||||||
</bean>
|
</bean>
|
||||||
----
|
----
|
||||||
|
====
|
||||||
|
|
||||||
Note that the resource path has no prefix, so because the application context itself is
|
Note that the resource path has no prefix. Consequetly, because the application context itself is
|
||||||
going to be used as the `ResourceLoader`, the resource itself will be loaded via a
|
going to be used as the `ResourceLoader`, the resource itself is loaded through a
|
||||||
`ClassPathResource`, `FileSystemResource`, or `ServletContextResource` (as appropriate)
|
`ClassPathResource`, a `FileSystemResource`, or a `ServletContextResource`,
|
||||||
depending on the exact type of the context.
|
depending on the exact type of the context.
|
||||||
|
|
||||||
If there is a need to force a specific `Resource` type to be used, then a prefix may be
|
If you need to force a specific `Resource` type to be used, you can use a prefix.
|
||||||
used. The following two examples show how to force a `ClassPathResource` and a
|
The following two examples show how to force a `ClassPathResource` and a
|
||||||
`UrlResource` (the latter being used to access a filesystem file).
|
`UrlResource` (the latter being used to access a filesystem file):
|
||||||
|
|
||||||
|
====
|
||||||
[source,xml,indent=0]
|
[source,xml,indent=0]
|
||||||
[subs="verbatim,quotes"]
|
[subs="verbatim,quotes"]
|
||||||
----
|
----
|
||||||
|
|
@ -371,49 +407,56 @@ used. The following two examples show how to force a `ClassPathResource` and a
|
||||||
----
|
----
|
||||||
<property name="template" value="file:///some/resource/path/myTemplate.txt"/>
|
<property name="template" value="file:///some/resource/path/myTemplate.txt"/>
|
||||||
----
|
----
|
||||||
|
====
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[[resources-app-ctx]]
|
[[resources-app-ctx]]
|
||||||
== Application contexts and Resource paths
|
== Application Contexts and Resource Paths
|
||||||
|
|
||||||
|
This section covers how to create application contexts with resources, including shortcuts
|
||||||
|
that work with XML, how to use wildcards, and other details.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[[resources-app-ctx-construction]]
|
[[resources-app-ctx-construction]]
|
||||||
=== Constructing application contexts
|
=== Constructing Application Contexts
|
||||||
|
|
||||||
An application context constructor (for a specific application context type) generally
|
An application context constructor (for a specific application context type) generally
|
||||||
takes a string or array of strings as the location path(s) of the resource(s) such as
|
takes a string or array of strings as the location paths of the resources, such as
|
||||||
XML files that make up the definition of the context.
|
XML files that make up the definition of the context.
|
||||||
|
|
||||||
When such a location path doesn't have a prefix, the specific `Resource` type built from
|
When such a location path does not have a prefix, the specific `Resource` type built from
|
||||||
that path and used to load the bean definitions, depends on and is appropriate to the
|
that path and used to load the bean definitions depends on and is appropriate to the
|
||||||
specific application context. For example, if you create a
|
specific application context. For example, consider the following example, which creates a
|
||||||
`ClassPathXmlApplicationContext` as follows:
|
`ClassPathXmlApplicationContext`:
|
||||||
|
|
||||||
|
====
|
||||||
[source,java,indent=0]
|
[source,java,indent=0]
|
||||||
[subs="verbatim,quotes"]
|
[subs="verbatim,quotes"]
|
||||||
----
|
----
|
||||||
ApplicationContext ctx = new ClassPathXmlApplicationContext("conf/appContext.xml");
|
ApplicationContext ctx = new ClassPathXmlApplicationContext("conf/appContext.xml");
|
||||||
----
|
----
|
||||||
|
====
|
||||||
|
|
||||||
The bean definitions will be loaded from the classpath, as a `ClassPathResource` will be
|
The bean definitions are loaded from the classpath, because a `ClassPathResource` is
|
||||||
used. But if you create a `FileSystemXmlApplicationContext` as follows:
|
used. However, consider the following example, which creates a `FileSystemXmlApplicationContext`:
|
||||||
|
|
||||||
|
====
|
||||||
[source,java,indent=0]
|
[source,java,indent=0]
|
||||||
[subs="verbatim,quotes"]
|
[subs="verbatim,quotes"]
|
||||||
----
|
----
|
||||||
ApplicationContext ctx =
|
ApplicationContext ctx =
|
||||||
new FileSystemXmlApplicationContext("conf/appContext.xml");
|
new FileSystemXmlApplicationContext("conf/appContext.xml");
|
||||||
----
|
----
|
||||||
|
====
|
||||||
|
|
||||||
The bean definition will be loaded from a filesystem location, in this case relative to
|
Now the bean definition is loaded from a filesystem location (in this case, relative to
|
||||||
the current working directory.
|
the current working directory).
|
||||||
|
|
||||||
Note that the use of the special classpath prefix or a standard URL prefix on the
|
Note that the use of the special classpath prefix or a standard URL prefix on the
|
||||||
location path will override the default type of `Resource` created to load the
|
location path overrides the default type of `Resource` created to load the
|
||||||
definition. So this `FileSystemXmlApplicationContext`...
|
definition. Consider the folowing example:
|
||||||
|
|
||||||
[source,java,indent=0]
|
[source,java,indent=0]
|
||||||
[subs="verbatim,quotes"]
|
[subs="verbatim,quotes"]
|
||||||
|
|
@ -422,23 +465,24 @@ definition. So this `FileSystemXmlApplicationContext`...
|
||||||
new FileSystemXmlApplicationContext("classpath:conf/appContext.xml");
|
new FileSystemXmlApplicationContext("classpath:conf/appContext.xml");
|
||||||
----
|
----
|
||||||
|
|
||||||
... will actually load its bean definitions from the classpath. However, it is still a
|
Using `FileSystemXmlApplicationContext` loads the bean definitions from the classpath. However, it is still a
|
||||||
`FileSystemXmlApplicationContext`. If it is subsequently used as a `ResourceLoader`, any
|
`FileSystemXmlApplicationContext`. If it is subsequently used as a `ResourceLoader`, any
|
||||||
unprefixed paths will still be treated as filesystem paths.
|
unprefixed paths are still treated as filesystem paths.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[[resources-app-ctx-classpathxml]]
|
[[resources-app-ctx-classpathxml]]
|
||||||
==== Constructing ClassPathXmlApplicationContext instances - shortcuts
|
==== Constructing `ClassPathXmlApplicationContext` Instances -- Shortcuts
|
||||||
|
|
||||||
The `ClassPathXmlApplicationContext` exposes a number of constructors to enable
|
The `ClassPathXmlApplicationContext` exposes a number of constructors to enable
|
||||||
convenient instantiation. The basic idea is that one supplies merely a string array
|
convenient instantiation. The basic idea is that you can supply merely a string array
|
||||||
containing just the filenames of the XML files themselves (without the leading path
|
that contains only the filenames of the XML files themselves (without the leading path
|
||||||
information), and one __also__ supplies a `Class`; the `ClassPathXmlApplicationContext`
|
information) and also supplies a `Class`. The `ClassPathXmlApplicationContext`
|
||||||
will derive the path information from the supplied class.
|
then derives the path information from the supplied class.
|
||||||
|
|
||||||
An example will hopefully make this clear. Consider a directory layout that looks like
|
Consider the following directory layout:
|
||||||
this:
|
|
||||||
|
|
||||||
|
====
|
||||||
[literal]
|
[literal]
|
||||||
[subs="verbatim,quotes"]
|
[subs="verbatim,quotes"]
|
||||||
----
|
----
|
||||||
|
|
@ -448,48 +492,53 @@ com/
|
||||||
daos.xml
|
daos.xml
|
||||||
MessengerService.class
|
MessengerService.class
|
||||||
----
|
----
|
||||||
|
====
|
||||||
|
|
||||||
A `ClassPathXmlApplicationContext` instance composed of the beans defined in the
|
The following example shows how a `ClassPathXmlApplicationContext` instance composed of the beans defined in
|
||||||
`'services.xml'` and `'daos.xml'` could be instantiated like so...
|
files named `services.xml` and `daos.xml` (which are on the classpath) can be instantiated:
|
||||||
|
|
||||||
|
====
|
||||||
[source,java,indent=0]
|
[source,java,indent=0]
|
||||||
[subs="verbatim,quotes"]
|
[subs="verbatim,quotes"]
|
||||||
----
|
----
|
||||||
ApplicationContext ctx = new ClassPathXmlApplicationContext(
|
ApplicationContext ctx = new ClassPathXmlApplicationContext(
|
||||||
new String[] {"services.xml", "daos.xml"}, MessengerService.class);
|
new String[] {"services.xml", "daos.xml"}, MessengerService.class);
|
||||||
----
|
----
|
||||||
|
====
|
||||||
|
|
||||||
Please do consult the `ClassPathXmlApplicationContext` javadocs for details
|
See the {api-spring-framework}/jca/context/SpringContextResourceAdapter.html[`ClassPathXmlApplicationContext` Javadoc] for details
|
||||||
on the various constructors.
|
on the various constructors.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[[resources-app-ctx-wildcards-in-resource-paths]]
|
[[resources-app-ctx-wildcards-in-resource-paths]]
|
||||||
=== Wildcards in application context constructor resource paths
|
=== Wildcards in Application Context Constructor Resource Paths
|
||||||
|
|
||||||
The resource paths in application context constructor values may be a simple path (as
|
The resource paths in application context constructor values may be simple paths (as
|
||||||
shown above) which has a one-to-one mapping to a target Resource, or alternately may
|
shown earlier), each of which has a one-to-one mapping to a target `Resource` or, alternately, may
|
||||||
contain the special "classpath*:" prefix and/or internal Ant-style regular expressions
|
contain the special "classpath*:" prefix or internal Ant-style regular expressions
|
||||||
(matched using Spring's `PathMatcher` utility). Both of the latter are effectively
|
(matched by using Spring's `PathMatcher` utility). Both of the latter are effectively
|
||||||
wildcards
|
wildcards.
|
||||||
|
|
||||||
One use for this mechanism is when doing component-style application assembly. All
|
One use for this mechanism is when you need to do component-style application assembly. All
|
||||||
components can 'publish' context definition fragments to a well-known location path, and
|
components can 'publish' context definition fragments to a well-known location path, and,
|
||||||
when the final application context is created using the same path prefixed via
|
when the final application context is created using the same path prefixed with
|
||||||
`classpath*:`, all component fragments will be picked up automatically.
|
`classpath*:`, all component fragments are automatically picked up.
|
||||||
|
|
||||||
Note that this wildcarding is specific to use of resource paths in application context
|
Note that this wildcarding is specific to the use of resource paths in application context
|
||||||
constructors (or when using the `PathMatcher` utility class hierarchy directly), and is
|
constructors (or when you use the `PathMatcher` utility class hierarchy directly) and is
|
||||||
resolved at construction time. It has nothing to do with the `Resource` type itself.
|
resolved at construction time. It has nothing to do with the `Resource` type itself.
|
||||||
It's not possible to use the `classpath*:` prefix to construct an actual `Resource`, as
|
You cannot use the `classpath*:` prefix to construct an actual `Resource`, as
|
||||||
a resource points to just one resource at a time.
|
a resource points to just one resource at a time.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[[resources-app-ctx-ant-patterns-in-paths]]
|
[[resources-app-ctx-ant-patterns-in-paths]]
|
||||||
==== Ant-style Patterns
|
==== Ant-style Patterns
|
||||||
|
|
||||||
When the path location contains an Ant-style pattern, for example:
|
Path locations can contain Ant-style patterns, as the following example shows:
|
||||||
|
|
||||||
|
====
|
||||||
[literal]
|
[literal]
|
||||||
[subs="verbatim"]
|
[subs="verbatim"]
|
||||||
----
|
----
|
||||||
|
|
@ -498,101 +547,103 @@ com/mycompany/**/applicationContext.xml
|
||||||
file:C:/some/path/*-context.xml
|
file:C:/some/path/*-context.xml
|
||||||
classpath:com/mycompany/**/applicationContext.xml
|
classpath:com/mycompany/**/applicationContext.xml
|
||||||
----
|
----
|
||||||
|
====
|
||||||
|
|
||||||
The resolver follows a more complex but defined procedure to try to resolve the
|
When the path location contains an Ant-style pattern, the resolver follows a more complex procedure to try to resolve the
|
||||||
wildcard. It produces a Resource for the path up to the last non-wildcard segment and
|
wildcard. It produces a `Resource` for the path up to the last non-wildcard segment and
|
||||||
obtains a URL from it. If this URL is not a `jar:` URL or container-specific variant
|
obtains a URL from it. If this URL is not a `jar:` URL or container-specific variant
|
||||||
(e.g. `zip:` in WebLogic, `wsjar` in WebSphere, etc.), then a `java.io.File` is
|
(such as `zip:` in WebLogic, `wsjar` in WebSphere, and so on), a `java.io.File` is
|
||||||
obtained from it and used to resolve the wildcard by traversing the filesystem. In the
|
obtained from it and used to resolve the wildcard by traversing the filesystem. In the
|
||||||
case of a jar URL, the resolver either gets a `java.net.JarURLConnection` from it or
|
case of a jar URL, the resolver either gets a `java.net.JarURLConnection` from it or
|
||||||
manually parses the jar URL and then traverses the contents of the jar file to resolve
|
manually parses the jar URL and then traverses the contents of the jar file to resolve
|
||||||
the wildcards.
|
the wildcards.
|
||||||
|
|
||||||
[[resources-app-ctx-portability]]
|
[[resources-app-ctx-portability]]
|
||||||
===== Implications on portability
|
===== Implications on Portability
|
||||||
|
|
||||||
If the specified path is already a file URL (either explicitly, or implicitly because
|
If the specified path is already a file URL (either implicitly because
|
||||||
the base `ResourceLoader` is a filesystem one), then wildcarding is guaranteed to work in
|
the base `ResourceLoader` is a filesystem one or explicitly), wildcarding is guaranteed to work in
|
||||||
a completely portable fashion.
|
a completely portable fashion.
|
||||||
|
|
||||||
If the specified path is a classpath location, then the resolver must obtain the last
|
If the specified path is a classpath location, the resolver must obtain the last
|
||||||
non-wildcard path segment URL via a `Classloader.getResource()` call. Since this is just
|
non-wildcard path segment URL by making a `Classloader.getResource()` call. Since this is just
|
||||||
a node of the path (not the file at the end) it is actually undefined (in the
|
a node of the path (not the file at the end), it is actually undefined (in the
|
||||||
`ClassLoader` javadocs) exactly what sort of a URL is returned in this case. In
|
`ClassLoader` Javadoc) exactly what sort of a URL is returned in this case. In
|
||||||
practice, it is always a `java.io.File` representing the directory, where the classpath
|
practice, it is always a `java.io.File` representing the directory (where the classpath
|
||||||
resource resolves to a filesystem location, or a jar URL of some sort, where the
|
resource resolves to a filesystem location) or a jar URL of some sort w(here the
|
||||||
classpath resource resolves to a jar location. Still, there is a portability concern on
|
classpath resource resolves to a jar location). Still, there is a portability concern on
|
||||||
this operation.
|
this operation.
|
||||||
|
|
||||||
If a jar URL is obtained for the last non-wildcard segment, the resolver must be able to
|
If a jar URL is obtained for the last non-wildcard segment, the resolver must be able to
|
||||||
get a `java.net.JarURLConnection` from it, or manually parse the jar URL, to be able to
|
get a `java.net.JarURLConnection` from it or manually parse the jar URL, to be able to
|
||||||
walk the contents of the jar, and resolve the wildcard. This will work in most
|
walk the contents of the jar and resolve the wildcard. This does work in most
|
||||||
environments, but will fail in others, and it is strongly recommended that the wildcard
|
environments but fails in others, and we strongly recommend that the wildcard
|
||||||
resolution of resources coming from jars be thoroughly tested in your specific
|
resolution of resources coming from jars be thoroughly tested in your specific
|
||||||
environment before you rely on it.
|
environment before you rely on it.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[[resources-classpath-wildcards]]
|
[[resources-classpath-wildcards]]
|
||||||
==== The classpath*: prefix
|
==== The `classpath*:` Prefix
|
||||||
|
|
||||||
When constructing an XML-based application context, a location string may use the
|
When constructing an XML-based application context, a location string may use the
|
||||||
special `classpath*:` prefix:
|
special `classpath*:` prefix, as the following example shows:
|
||||||
|
|
||||||
|
====
|
||||||
[source,java,indent=0]
|
[source,java,indent=0]
|
||||||
[subs="verbatim,quotes"]
|
[subs="verbatim,quotes"]
|
||||||
----
|
----
|
||||||
ApplicationContext ctx =
|
ApplicationContext ctx =
|
||||||
new ClassPathXmlApplicationContext("classpath*:conf/appContext.xml");
|
new ClassPathXmlApplicationContext("classpath*:conf/appContext.xml");
|
||||||
----
|
----
|
||||||
|
====
|
||||||
|
|
||||||
This special prefix specifies that all classpath resources that match the given name
|
This special prefix specifies that all classpath resources that match the given name
|
||||||
must be obtained (internally, this essentially happens via a
|
must be obtained (internally, this essentially happens through a call to
|
||||||
`ClassLoader.getResources(...)` call), and then merged to form the final application
|
`ClassLoader.getResources(...)`) and then merged to form the final application
|
||||||
context definition.
|
context definition.
|
||||||
|
|
||||||
[NOTE]
|
NOTE: The wildcard classpath relies on the `getResources()` method of the underlying
|
||||||
====
|
|
||||||
The wildcard classpath relies on the `getResources()` method of the underlying
|
|
||||||
classloader. As most application servers nowadays supply their own classloader
|
classloader. As most application servers nowadays supply their own classloader
|
||||||
implementation, the behavior might differ especially when dealing with jar files. A
|
implementation, the behavior might differ, especially when dealing with jar files. A
|
||||||
simple test to check if `classpath*` works is to use the classloader to load a file from
|
simple test to check if `classpath*` works is to use the classloader to load a file from
|
||||||
within a jar on the classpath:
|
within a jar on the classpath:
|
||||||
`getClass().getClassLoader().getResources("<someFileInsideTheJar>")`. Try this test with
|
`getClass().getClassLoader().getResources("<someFileInsideTheJar>")`. Try this test with
|
||||||
files that have the same name but are placed inside two different locations. In case an
|
files that have the same name but are placed inside two different locations. In case an
|
||||||
inappropriate result is returned, check the application server documentation for
|
inappropriate result is returned, check the application server documentation for
|
||||||
settings that might affect the classloader behavior.
|
settings that might affect the classloader behavior.
|
||||||
====
|
|
||||||
|
|
||||||
The `classpath*:` prefix can also be combined with a `PathMatcher` pattern in the
|
You can also combine the `classpath*:` prefix with a `PathMatcher` pattern in the
|
||||||
rest of the location path, for example `classpath*:META-INF/*-beans.xml`. In this
|
rest of the location path (for example, `classpath*:META-INF/*-beans.xml`). In this
|
||||||
case, the resolution strategy is fairly simple: a `ClassLoader.getResources()` call is
|
case, the resolution strategy is fairly simple: A `ClassLoader.getResources()` call is
|
||||||
used on the last non-wildcard path segment to get all the matching resources in the
|
used on the last non-wildcard path segment to get all the matching resources in the
|
||||||
class loader hierarchy, and then off each resource the same PathMatcher resolution
|
class loader hierarchy and then, off each resource, the same `PathMatcher` resolution
|
||||||
strategy described above is used for the wildcard subpath.
|
strategy described earlier is used for the wildcard subpath.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[[resources-wildcards-in-path-other-stuff]]
|
[[resources-wildcards-in-path-other-stuff]]
|
||||||
==== Other notes relating to wildcards
|
==== Other Notes Relating to Wildcards
|
||||||
|
|
||||||
Please note that `classpath*:` when combined with Ant-style patterns will only work
|
Note that `classpath*:`, when combined with Ant-style patterns, only works
|
||||||
reliably with at least one root directory before the pattern starts, unless the actual
|
reliably with at least one root directory before the pattern starts, unless the actual
|
||||||
target files reside in the file system. This means that a pattern like
|
target files reside in the file system. This means that a pattern such as
|
||||||
`classpath*:*.xml` might not retrieve files from the root of jar files but rather only
|
`classpath*:*.xml` might not retrieve files from the root of jar files but rather only
|
||||||
from the root of expanded directories.
|
from the root of expanded directories.
|
||||||
|
|
||||||
Spring's ability to retrieve classpath entries originates from the JDK's
|
Spring's ability to retrieve classpath entries originates from the JDK's
|
||||||
`ClassLoader.getResources()` method which only returns file system locations for a
|
`ClassLoader.getResources()` method, which only returns file system locations for an
|
||||||
passed-in empty string (indicating potential roots to search). Spring evaluates
|
empty string (indicating potential roots to search). Spring evaluates
|
||||||
`URLClassLoader` runtime configuration and the "java.class.path" manifest in jar files
|
`URLClassLoader` runtime configuration and the `java.class.path` manifest in jar files
|
||||||
as well but this is not guaranteed to lead to portable behavior.
|
as well, but this is not guaranteed to lead to portable behavior.
|
||||||
|
|
||||||
[NOTE]
|
[NOTE]
|
||||||
====
|
====
|
||||||
The scanning of classpath packages requires the presence of corresponding directory
|
The scanning of classpath packages requires the presence of corresponding directory
|
||||||
entries in the classpath. When you build JARs with Ant, make sure that you do __not__
|
entries in the classpath. When you build JARs with Ant, do not
|
||||||
activate the files-only switch of the JAR task. Also, classpath directories may not
|
activate the files-only switch of the JAR task. Also, classpath directories may not
|
||||||
get exposed based on security policies in some environments, e.g. standalone apps on
|
get exposed based on security policies in some environments -- for example, stand-alone applications on
|
||||||
JDK 1.7.0_45 and higher (which requires 'Trusted-Library' setup in your manifests; see
|
JDK 1.7.0_45 and higher (which requires 'Trusted-Library' to be set up in your manifests. See
|
||||||
http://stackoverflow.com/questions/19394570/java-jre-7u45-breaks-classloader-getresources).
|
http://stackoverflow.com/questions/19394570/java-jre-7u45-breaks-classloader-getresources).
|
||||||
|
|
||||||
On JDK 9's module path (Jigsaw), Spring's classpath scanning generally works as expected.
|
On JDK 9's module path (Jigsaw), Spring's classpath scanning generally works as expected.
|
||||||
|
|
@ -602,15 +653,17 @@ avoiding the aforementioned portability problems with searching the jar file roo
|
||||||
|
|
||||||
Ant-style patterns with `classpath:` resources are not guaranteed to find matching
|
Ant-style patterns with `classpath:` resources are not guaranteed to find matching
|
||||||
resources if the root package to search is available in multiple class path locations.
|
resources if the root package to search is available in multiple class path locations.
|
||||||
This is because a resource such as
|
Consider the following example of a resource location:
|
||||||
|
|
||||||
|
====
|
||||||
[literal]
|
[literal]
|
||||||
[subs="verbatim,quotes"]
|
[subs="verbatim,quotes"]
|
||||||
----
|
----
|
||||||
com/mycompany/package1/service-context.xml
|
com/mycompany/package1/service-context.xml
|
||||||
----
|
----
|
||||||
|
====
|
||||||
|
|
||||||
may be in only one location, but when a path such as
|
Now consider an Ant-style path that someone might use to try to find that file:
|
||||||
|
|
||||||
[literal]
|
[literal]
|
||||||
[subs="verbatim,quotes"]
|
[subs="verbatim,quotes"]
|
||||||
|
|
@ -618,29 +671,31 @@ may be in only one location, but when a path such as
|
||||||
classpath:com/mycompany/**/service-context.xml
|
classpath:com/mycompany/**/service-context.xml
|
||||||
----
|
----
|
||||||
|
|
||||||
is used to try to resolve it, the resolver will work off the (first) URL returned by
|
Such a resource may be in only one location, but when a path such as the preceding example
|
||||||
`getResource("com/mycompany")`;. If this base package node exists in multiple
|
is used to try to resolve it, the resolver works off the (first) URL returned by
|
||||||
classloader locations, the actual end resource may not be underneath. Therefore,
|
`getResource("com/mycompany");`. If this base package node exists in multiple
|
||||||
preferably, use " `classpath*:`" with the same Ant-style pattern in such a case, which
|
classloader locations, the actual end resource may not be there. Therefore, in such a case
|
||||||
will search all class path locations that contain the root package.
|
you should prefer using `classpath*:` with the same Ant-style pattern, which
|
||||||
|
searches all class path locations that contain the root package.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[[resources-filesystemresource-caveats]]
|
[[resources-filesystemresource-caveats]]
|
||||||
=== FileSystemResource caveats
|
=== `FileSystemResource` Caveats
|
||||||
|
|
||||||
A `FileSystemResource` that is not attached to a `FileSystemApplicationContext` (that
|
A `FileSystemResource` that is not attached to a `FileSystemApplicationContext` (that
|
||||||
is, a `FileSystemApplicationContext` is not the actual `ResourceLoader`) will treat
|
is, when a `FileSystemApplicationContext` is not the actual `ResourceLoader`) treats
|
||||||
absolute vs. relative paths as you would expect. Relative paths are relative to the
|
absolute and relative paths as you would expect. Relative paths are relative to the
|
||||||
current working directory, while absolute paths are relative to the root of the
|
current working directory, while absolute paths are relative to the root of the
|
||||||
filesystem.
|
filesystem.
|
||||||
|
|
||||||
For backwards compatibility (historical) reasons however, this changes when the
|
For backwards compatibility (historical) reasons however, this changes when the
|
||||||
`FileSystemApplicationContext` is the `ResourceLoader`. The
|
`FileSystemApplicationContext` is the `ResourceLoader`. The
|
||||||
`FileSystemApplicationContext` simply forces all attached `FileSystemResource` instances
|
`FileSystemApplicationContext` forces all attached `FileSystemResource` instances
|
||||||
to treat all location paths as relative, whether they start with a leading slash or not.
|
to treat all location paths as relative, whether they start with a leading slash or not.
|
||||||
In practice, this means the following are equivalent:
|
In practice, this means the following examples are equivalent:
|
||||||
|
|
||||||
|
====
|
||||||
[source,java,indent=0]
|
[source,java,indent=0]
|
||||||
[subs="verbatim,quotes"]
|
[subs="verbatim,quotes"]
|
||||||
----
|
----
|
||||||
|
|
@ -654,10 +709,12 @@ In practice, this means the following are equivalent:
|
||||||
ApplicationContext ctx =
|
ApplicationContext ctx =
|
||||||
new FileSystemXmlApplicationContext("/conf/context.xml");
|
new FileSystemXmlApplicationContext("/conf/context.xml");
|
||||||
----
|
----
|
||||||
|
====
|
||||||
|
|
||||||
As are the following: (Even though it would make sense for them to be different, as one
|
The following exmaples are also equivalent (even though it would make sense for them to be different, as one
|
||||||
case is relative and the other absolute.)
|
case is relative and the other absolute):
|
||||||
|
|
||||||
|
====
|
||||||
[source,java,indent=0]
|
[source,java,indent=0]
|
||||||
[subs="verbatim,quotes"]
|
[subs="verbatim,quotes"]
|
||||||
----
|
----
|
||||||
|
|
@ -671,11 +728,14 @@ case is relative and the other absolute.)
|
||||||
FileSystemXmlApplicationContext ctx = ...;
|
FileSystemXmlApplicationContext ctx = ...;
|
||||||
ctx.getResource("/some/resource/path/myTemplate.txt");
|
ctx.getResource("/some/resource/path/myTemplate.txt");
|
||||||
----
|
----
|
||||||
|
====
|
||||||
|
|
||||||
In practice, if true absolute filesystem paths are needed, it is better to forgo the use
|
In practice, if you need true absolute filesystem paths, you should avoid using
|
||||||
of absolute paths with `FileSystemResource` / `FileSystemXmlApplicationContext`, and
|
absolute paths with `FileSystemResource` or `FileSystemXmlApplicationContext` and
|
||||||
just force the use of a `UrlResource`, by using the `file:` URL prefix.
|
force the use of a `UrlResource` by using the `file:` URL prefix. The following examples
|
||||||
|
show how to do so:
|
||||||
|
|
||||||
|
====
|
||||||
[source,java,indent=0]
|
[source,java,indent=0]
|
||||||
[subs="verbatim,quotes"]
|
[subs="verbatim,quotes"]
|
||||||
----
|
----
|
||||||
|
|
@ -690,3 +750,4 @@ just force the use of a `UrlResource`, by using the `file:` URL prefix.
|
||||||
ApplicationContext ctx =
|
ApplicationContext ctx =
|
||||||
new FileSystemXmlApplicationContext("file:///conf/context.xml");
|
new FileSystemXmlApplicationContext("file:///conf/context.xml");
|
||||||
----
|
----
|
||||||
|
====
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue