Edit the core content reference documentation
I edited for the usual stuff: spelling, punctuation, grammar, formatting, usage, and voice.
This commit is contained in:
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]]
|
||||
= The IoC container
|
||||
= The IoC Container
|
||||
|
||||
This chapter covers Spring's Inversion of Control (IoC) container.
|
||||
|
||||
|
||||
|
||||
@@ -143,7 +144,7 @@ The following example shows the basic structure of XML-based configuration metad
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans.xsd">
|
||||
|
||||
<bean id="..." class="..."> <1> <2>
|
||||
<bean id="..." class="..."> <1> <2>
|
||||
<!-- collaborators and configuration for this bean go here -->
|
||||
</bean>
|
||||
|
||||
@@ -2136,6 +2137,7 @@ modes:
|
||||
|
||||
[[beans-factory-autowiring-modes-tbl]]
|
||||
.Autowiring modes
|
||||
[cols="20%,80%"]
|
||||
|===
|
||||
| Mode| Explanation
|
||||
|
||||
@@ -2568,6 +2570,7 @@ The following table describes the supported scopes:
|
||||
|
||||
[[beans-factory-scopes-tbl]]
|
||||
.Bean scopes
|
||||
[cols="20%,80%"]
|
||||
|===
|
||||
| Scope| Description
|
||||
|
||||
@@ -2957,7 +2960,7 @@ understand the "`why`" as well as the "`how`" behind it:
|
||||
<!-- an HTTP Session-scoped bean exposed as a proxy -->
|
||||
<bean id="userPreferences" class="com.something.UserPreferences" scope="session">
|
||||
<!-- instructs the container to proxy the surrounding bean -->
|
||||
<aop:scoped-proxy/> <1>
|
||||
<aop:scoped-proxy/> <1>
|
||||
</bean>
|
||||
|
||||
<!-- a singleton-scoped bean injected with a proxy to the above bean -->
|
||||
@@ -4565,7 +4568,7 @@ references and values even when you use the class outside of a container.
|
||||
|
||||
|
||||
[[beans-autowired-annotation]]
|
||||
=== @Autowired
|
||||
=== Using `@Autowired`
|
||||
|
||||
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.
|
||||
@@ -5007,13 +5010,13 @@ The following example shows corresponding bean definitions.
|
||||
<context:annotation-config/>
|
||||
|
||||
<bean class="example.SimpleMovieCatalog">
|
||||
<qualifier value="main"/> <1>
|
||||
<qualifier value="main"/> <1>
|
||||
|
||||
<!-- inject any dependencies required by this bean -->
|
||||
</bean>
|
||||
|
||||
<bean class="example.SimpleMovieCatalog">
|
||||
<qualifier value="action"/> <2>
|
||||
<qualifier value="action"/> <2>
|
||||
|
||||
<!-- inject any dependencies required by this bean -->
|
||||
</bean>
|
||||
@@ -5201,7 +5204,7 @@ following example:
|
||||
public class MovieRecommender {
|
||||
|
||||
@Autowired
|
||||
@Offline <1>
|
||||
@Offline <1>
|
||||
private MovieCatalog offlineCatalog;
|
||||
|
||||
// ...
|
||||
@@ -5217,7 +5220,7 @@ Now the bean definition only needs a qualifier `type`, as shown in the following
|
||||
[subs="verbatim,quotes"]
|
||||
----
|
||||
<bean class="example.SimpleMovieCatalog">
|
||||
<qualifier type="Offline"/> <1>
|
||||
<qualifier type="Offline"/> <1>
|
||||
<!-- inject any dependencies required by this bean -->
|
||||
</bean>
|
||||
----
|
||||
@@ -5459,7 +5462,7 @@ demonstrated in the following example:
|
||||
|
||||
private MovieFinder movieFinder;
|
||||
|
||||
@Resource(name="myMovieFinder") <1>
|
||||
@Resource(name="myMovieFinder") <1>
|
||||
public void setMovieFinder(MovieFinder movieFinder) {
|
||||
this.movieFinder = movieFinder;
|
||||
}
|
||||
@@ -5516,7 +5519,7 @@ named customerPreferenceDao and then falls back to a primary type match for the
|
||||
private CustomerPreferenceDao customerPreferenceDao;
|
||||
|
||||
@Resource
|
||||
private ApplicationContext context; <1>
|
||||
private ApplicationContext context; <1>
|
||||
|
||||
public MovieRecommender() {
|
||||
}
|
||||
@@ -5630,7 +5633,7 @@ annotation. For example, the `@Service` annotation mentioned <<beans-stereotype-
|
||||
@Target(ElementType.TYPE)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
@Component <1>
|
||||
@Component <1>
|
||||
public @interface Service {
|
||||
|
||||
// ....
|
||||
@@ -8181,7 +8184,7 @@ the following example shows:
|
||||
public class AppConfig {
|
||||
|
||||
@Bean("dataSource")
|
||||
@Profile("development") <1>
|
||||
@Profile("development") <1>
|
||||
public DataSource standaloneDataSource() {
|
||||
return new EmbeddedDatabaseBuilder()
|
||||
.setType(EmbeddedDatabaseType.HSQL)
|
||||
@@ -8191,7 +8194,7 @@ the following example shows:
|
||||
}
|
||||
|
||||
@Bean("dataSource")
|
||||
**@Profile("production")**
|
||||
@Profile("production") <2>
|
||||
public DataSource jndiDataSource() throws Exception {
|
||||
Context ctx = new InitialContext();
|
||||
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.
|
||||
<2> The `jndiDataSource` method is available only in the `production` profile.
|
||||
====
|
||||
|
||||
[NOTE]
|
||||
@@ -8895,6 +8899,7 @@ The following table describes the standard events that Spring provides:
|
||||
|
||||
[[beans-ctx-events-tbl]]
|
||||
.Built-in Events
|
||||
[cols="30%,70%"]
|
||||
|===
|
||||
| Event| Explanation
|
||||
|
||||
@@ -9460,6 +9465,7 @@ The following table lists features provided by the `BeanFactory` and
|
||||
|
||||
[[context-introduction-ctx-vs-beanfactory-feature-matrix]]
|
||||
.Feature Matrix
|
||||
[cols="50%,25%,25%"]
|
||||
|===
|
||||
| Feature | `BeanFactory` | `ApplicationContext`
|
||||
|
||||
|
||||
@@ -1,69 +1,64 @@
|
||||
[[databuffers]]
|
||||
= Data Buffers and Codecs
|
||||
|
||||
|
||||
|
||||
|
||||
== Introduction
|
||||
|
||||
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.
|
||||
Netty does not use `ByteBuffer`, but instead offers `ByteBuf` as an alternative.
|
||||
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.
|
||||
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`
|
||||
|
||||
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.
|
||||
The `allocate` 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
|
||||
The `allocateBuffer` methods allocate a new data buffer with a default or given capacity.
|
||||
Though `DataBuffer` implementations grow and shrink on demand, it is more efficient to give the
|
||||
capacity upfront, if known.
|
||||
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.
|
||||
|
||||
There are two implementation of `DataBufferFactory`: the `NettyDataBufferFactory` which is meant
|
||||
to be used on Netty platforms, such as Reactor Netty.
|
||||
The other implementation, the `DefaultDataBufferFactory`, is used on other platforms, such as
|
||||
Servlet 3.1+ servers.
|
||||
There are two implementation of `DataBufferFactory`: the `NettyDataBufferFactory`
|
||||
(for Netty platforms, such as Reactor Netty) and
|
||||
`DefaultDataBufferFactory` (for other platforms, such as
|
||||
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
|
||||
positions.
|
||||
This is different from the JDK's `ByteBuffer`, which only exposes one position for both reading and
|
||||
writing, and a separate `flip()` operation to switch between the two I/O operations.
|
||||
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.
|
||||
In general, the following invariant holds for the read position, write position, and the capacity:
|
||||
|
||||
====
|
||||
[literal]
|
||||
[subs="verbatim,quotes"]
|
||||
--
|
||||
0 <= read position <= write position <= capacity
|
||||
--
|
||||
====
|
||||
|
||||
When reading bytes from the `DataBuffer`, the read position is automatically updated in accordance with
|
||||
the amount of data read from the buffer.
|
||||
Similarly, when writing bytes to the `DataBuffer`, the write position is updated with the amount of
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
There are two implementation of `DataBuffer`: the `NettyDataBuffer` which is meant to be used on
|
||||
Netty platforms, such as Reactor Netty.
|
||||
The other implementation, the `DefaultDataBuffer`, is used on other platforms, such as Servlet 3.1+
|
||||
servers.
|
||||
As mentioned earlier, there are two implementation of `DataBufferFactory`: the `NettyDataBufferFactory`
|
||||
(for Netty platforms, such as Reactor Netty) and
|
||||
`DefaultDataBufferFactory` (for other platforms, such as
|
||||
Servlet 3.1+ servers).
|
||||
|
||||
|
||||
|
||||
@@ -71,41 +66,42 @@ servers.
|
||||
|
||||
The `PooledDataBuffer` is an extension to `DataBuffer` that adds methods for reference counting.
|
||||
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.
|
||||
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
|
||||
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`.
|
||||
|
||||
|
||||
[[databuffer-reference-counting]]
|
||||
==== Reference Counting
|
||||
|
||||
Reference counting is not a common technique in Java; it is much more common in other programming
|
||||
languages such as Object C and C++.
|
||||
In and of itself, reference counting is not complex: it basically involves tracking the number of
|
||||
Reference counting is not a common technique in Java. It is much more common in other programming
|
||||
languages, such as Object C and C++.
|
||||
In and of itself, reference counting is not complex. It basically involves tracking the number of
|
||||
references that apply to an object.
|
||||
The reference count of a `PooledDataBuffer` starts at 1, is incremented by calling `retain`,
|
||||
and decremented by calling `release`.
|
||||
As long as the buffer's reference count is larger than 0 the buffer will not be released.
|
||||
When the number decreases to 0, the instance will be released.
|
||||
In practice, this means that the reserved memory captured by the buffer will be returned back to
|
||||
and is decremented by calling `release`.
|
||||
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 is released.
|
||||
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.
|
||||
|
||||
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.
|
||||
Decoders are responsible for transforming a stream of buffers into other types (see <<codecs>> below),
|
||||
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
|
||||
message (i.e. client-side request or server-side response), they do not have to be released.
|
||||
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.
|
||||
This means that, if you allocate data buffers for the purpose of putting them into an outbound HTTP
|
||||
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
|
||||
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
|
||||
throw exceptions:
|
||||
|
||||
====
|
||||
[source,java,indent=0]
|
||||
[subs="verbatim,quotes"]
|
||||
----
|
||||
@@ -130,46 +126,49 @@ throw exceptions:
|
||||
|
||||
<1> A new buffer is allocated.
|
||||
<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`,
|
||||
and 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
|
||||
<3> This example method loads data into the buffer. Note that the method can throw an `IOException`.
|
||||
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 is now
|
||||
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.
|
||||
====
|
||||
|
||||
|
||||
|
||||
=== 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
|
||||
`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`
|
||||
instances (so that casting to a `PooledDataBuffer` is not required).
|
||||
|
||||
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
|
||||
from that, a `String`, or `InputStream`).
|
||||
from that, a `String` or `InputStream`).
|
||||
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
|
||||
streaming solution would.
|
||||
|
||||
[codecs]
|
||||
|
||||
|
||||
[[codecs]]
|
||||
== Codecs
|
||||
|
||||
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
|
||||
data buffers.
|
||||
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>>.
|
||||
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>>.
|
||||
|
||||
Spring comes with a wide array of default codecs, capable of converting from/to `String`,
|
||||
`ByteBuffer`, byte arrays, and also codecs that support marshalling libraries such as JAXB and
|
||||
Spring comes with a wide array of default codecs (to convert from and to `String`,
|
||||
`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]).
|
||||
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.
|
||||
The default codecs are configured in the `WebFluxConfigurationSupport` class, and can easily be
|
||||
changed by overriding the `configureHttpMessageCodecs` when inheriting from that class.
|
||||
For more information about using codecs in WebFlux, see <<web-reactive#webflux-codecs, this section>>.
|
||||
The default codecs are configured in the `WebFluxConfigurationSupport` class. You can
|
||||
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>>.
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,19 +1,19 @@
|
||||
[[null-safety]]
|
||||
= Null-safety
|
||||
|
||||
Although Java does not allow to express null-safety with its type system, Spring Framework
|
||||
now provides following annotations in the `org.springframework.lang` package to declare
|
||||
Although Java does not let you express null-safety with its type system, Spring Framework
|
||||
now provides the following annotations in the `org.springframework.lang` package to let you declare
|
||||
nullability of APIs and fields:
|
||||
|
||||
* {api-spring-framework}/lang/NonNull.html[`@NonNull`] annotation where specific parameter,
|
||||
return value or field cannot be `null` (not needed on parameter and return value
|
||||
where `@NonNullApi` and `@NonNullFields` apply) .
|
||||
* {api-spring-framework}/lang/Nullable.html[`@Nullable`] annotation where specific
|
||||
parameter, return value or field can be `null`.
|
||||
* {api-spring-framework}/lang/NonNullApi.html[`@NonNullApi`] annotation at package level
|
||||
declares non-null as the default behavior for parameters and return values.
|
||||
* {api-spring-framework}/lang/NonNullFields.html[`@NonNullFields`] annotation at package
|
||||
level declares non-null as the default behavior for fields.
|
||||
* {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
|
||||
where `@NonNullApi` and `@NonNullFields` apply) .
|
||||
* {api-spring-framework}/lang/Nullable.html[`@Nullable`]: Annotation to indicate that a specific
|
||||
parameter, return value, or field can be `null`.
|
||||
* {api-spring-framework}/lang/NonNullApi.html[`@NonNullApi`]: Annotation at the package level
|
||||
that declares non-null as the default behavior for parameters and return values.
|
||||
* {api-spring-framework}/lang/NonNullFields.html[`@NonNullFields`]: Annotation at the package
|
||||
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
|
||||
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
|
||||
scope of this feature.
|
||||
|
||||
[NOTE]
|
||||
====
|
||||
Libraries like Reactor or Spring Data provide null-safe APIs leveraging this feature.
|
||||
====
|
||||
|
||||
NOTE: Libraries like Reactor or Spring Data provide null-safe APIs that use this feature.
|
||||
|
||||
|
||||
|
||||
== Use cases
|
||||
|
||||
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
|
||||
warnings to Java developers related to null-safety in order to avoid `NullPointerException`
|
||||
these annotations can be used by an IDE (such as IDEA or Eclipse) to provide useful
|
||||
warnings related to null-safety in order to avoid `NullPointerException`
|
||||
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
|
||||
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
|
||||
|
||||
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
|
||||
like IDEA or Kotlin to provide null-safety support in a generic way, without having to hard-code
|
||||
annotations (a dormant but widely spread JSR). JSR 305 meta-annotations let tooling vendors
|
||||
like IDEA or Kotlin provide null-safety support in a generic way, without having to hard-code
|
||||
support for Spring annotations.
|
||||
|
||||
It is not necessary nor recommended to add JSR 305 dependency in project classpath to
|
||||
take advantage of Spring null-safe API. Only projects like
|
||||
Spring-based libraries using null-safety annotations in their codebase should add
|
||||
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 such as
|
||||
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
|
||||
`provided` scope to avoid compile warnings.
|
||||
|
||||
@@ -1,16 +1,26 @@
|
||||
[[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]]
|
||||
== Introduction
|
||||
|
||||
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
|
||||
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
|
||||
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`
|
||||
prefixes (similar to existing handlers for prefixes such as `http:`), this is generally
|
||||
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]]
|
||||
== The Resource interface
|
||||
== The Resource Interface
|
||||
|
||||
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]
|
||||
[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]
|
||||
[subs="verbatim,quotes"]
|
||||
----
|
||||
@@ -56,151 +73,158 @@ access to low-level resources.
|
||||
|
||||
}
|
||||
----
|
||||
====
|
||||
|
||||
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
|
||||
`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.
|
||||
* `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
|
||||
must be read once only and then closed to avoid resource leaks. Will be `false` for
|
||||
* `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
|
||||
must be read once only and then closed to avoid resource leaks. Returns `false` for
|
||||
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
|
||||
the actual URL of the resource.
|
||||
|
||||
Other methods allow you to obtain an actual `URL` or `File` object representing the
|
||||
resource (if the underlying implementation is compatible, and supports that
|
||||
Other methods let you obtain an actual `URL` or `File` object representing the
|
||||
resource (if the underlying implementation is compatible and supports that
|
||||
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
|
||||
(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
|
||||
that context implementation, or via special prefixes on the `String` path, allow the
|
||||
caller to specify that a specific `Resource` implementation must be created and used.
|
||||
that context implementation or, via special prefixes on the `String` path, let the
|
||||
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
|
||||
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
|
||||
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.
|
||||
|
||||
It is important to note that the `Resource` abstraction does not replace functionality:
|
||||
it wraps it where possible. For example, a `UrlResource` wraps a URL, and uses the
|
||||
NOTE: The `Resource` abstraction does not replace functionality.
|
||||
It wraps it where possible. For example, a `UrlResource` wraps a URL and uses the
|
||||
wrapped `URL` to do its work.
|
||||
|
||||
|
||||
|
||||
|
||||
[[resources-implementations]]
|
||||
== Built-in Resource implementations
|
||||
== Built-in Resource Implementations
|
||||
|
||||
There are a number of `Resource` implementations that come supplied straight out of the
|
||||
box in Spring:
|
||||
Spring includes the following `Resource` implementations:
|
||||
|
||||
* <<resources-implementations-urlresource>>
|
||||
* <<resources-implementations-classpathresource>>
|
||||
* <<resources-implementations-filesystemresource>>
|
||||
* <<resources-implementations-servletcontextresource>>
|
||||
* <<resources-implementations-inputstreamresource>>
|
||||
* <<resources-implementations-bytearrayresource>>
|
||||
|
||||
|
||||
|
||||
[[resources-implementations-urlresource]]
|
||||
=== UrlResource
|
||||
=== `UrlResource`
|
||||
|
||||
The `UrlResource` wraps a `java.net.URL`, and may be used to access any object that is
|
||||
normally accessible via a URL, such as files, an HTTP target, an FTP target, etc. All
|
||||
`UrlResource` wraps a `java.net.URL` and can be used to access any object that is
|
||||
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
|
||||
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,
|
||||
`ftp:` for accessing resources via FTP, etc.
|
||||
accessing filesystem paths, `http:` for accessing resources through the HTTP protocol,
|
||||
`ftp:` for accessing resources through FTP, and others.
|
||||
|
||||
A `UrlResource` is created by Java code explicitly using the `UrlResource` constructor,
|
||||
but will often be created implicitly when you call an API method which takes a `String`
|
||||
argument which is meant to represent a path. For the latter case, a JavaBeans
|
||||
`PropertyEditor` will ultimately decide 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
|
||||
create an appropriate specialized `Resource` for that prefix. However, if it doesn't
|
||||
recognize the prefix, it will assume the this is just a standard URL string, and will
|
||||
create a `UrlResource`.
|
||||
A `UrlResource` is created by Java code by explicitly using the `UrlResource` constructor
|
||||
but is often created implicitly when you call an API method that takes a `String`
|
||||
argument meant to represent a path. For the latter case, a JavaBeans
|
||||
`PropertyEditor` ultimately decides which type of `Resource` to create. If the path
|
||||
string contains well-known (to it, that is) prefix (such as `classpath:`), it
|
||||
creates an appropriate specialized `Resource` for that prefix. However, if it does not
|
||||
recognize the prefix, it assume the string is a standard URL string and
|
||||
creates a `UrlResource`.
|
||||
|
||||
|
||||
|
||||
[[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
|
||||
loading resources.
|
||||
|
||||
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
|
||||
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
|
||||
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)
|
||||
to the filesystem. To address this, the various `Resource` implementations always support
|
||||
resolution as a `java.net.URL`.
|
||||
|
||||
A `ClassPathResource` is created by Java code explicitly using the `ClassPathResource`
|
||||
constructor, but will often be created implicitly when you call an API method which
|
||||
takes a `String` argument which is meant to represent a path. For the latter case, a
|
||||
JavaBeans `PropertyEditor` will recognize the special prefix `classpath:` on the string
|
||||
path, and create a `ClassPathResource` in that case.
|
||||
A `ClassPathResource` is created by Java code by explicitly using the `ClassPathResource`
|
||||
constructor but is often created implicitly when you call an API method that
|
||||
takes a `String` argument meant to represent a path. For the latter case, a
|
||||
JavaBeans `PropertyEditor` recognizes the special prefix, `classpath:`, on the string
|
||||
path and creates a `ClassPathResource` in that case.
|
||||
|
||||
|
||||
|
||||
[[resources-implementations-filesystemresource]]
|
||||
=== FileSystemResource
|
||||
=== `FileSystemResource`
|
||||
|
||||
This is a `Resource` implementation for `java.io.File` handles. It obviously supports
|
||||
resolution as a `File`, and as a `URL`.
|
||||
This is a `Resource` implementation for `java.io.File` handles. It supports
|
||||
resolution as a `File` and as a `URL`.
|
||||
|
||||
|
||||
|
||||
[[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.
|
||||
|
||||
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
|
||||
filesystem. Whether or not it's expanded and on the filesystem like this, or accessed
|
||||
directly from the JAR or somewhere else like a DB (it's conceivable) is actually
|
||||
filesystem. Whether or not it is expanded and on the filesystem or accessed
|
||||
directly from the JAR or somewhere else like a database (which is conceivable) is actually
|
||||
dependent on the Servlet container.
|
||||
|
||||
|
||||
|
||||
[[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
|
||||
`ByteArrayResource` or any of the file-based `Resource` implementations where possible.
|
||||
|
||||
In contrast to other `Resource` implementations, this is a descriptor for an __already__
|
||||
opened resource - therefore returning `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
|
||||
In contrast to other `Resource` implementations, this is a descriptor for an already-opened
|
||||
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
|
||||
times.
|
||||
|
||||
|
||||
|
||||
[[resources-implementations-bytearrayresource]]
|
||||
=== ByteArrayResource
|
||||
=== `ByteArrayResource`
|
||||
|
||||
This is a `Resource` implementation for a given byte array. It creates a
|
||||
`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`.
|
||||
|
||||
|
||||
|
||||
|
||||
[[resources-resourceloader]]
|
||||
== The ResourceLoader
|
||||
== The `ResourceLoader`
|
||||
|
||||
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]
|
||||
[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.
|
||||
|
||||
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
|
||||
snippet of code was executed against a `ClassPathXmlApplicationContext` instance:
|
||||
|
||||
====
|
||||
[source,java,indent=0]
|
||||
[subs="verbatim,quotes"]
|
||||
----
|
||||
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 `FileSystemXmlApplicationContext` instance, you'd get back a
|
||||
`FileSystemResource`. For a `WebApplicationContext`, you'd get back a
|
||||
`ServletContextResource`, and so on.
|
||||
Against a `ClassPathXmlApplicationContext`, that code returns a `ClassPathResource`. If the same method were executed
|
||||
against a `FileSystemXmlApplicationContext` instance, it would return a
|
||||
`FileSystemResource`. For a `WebApplicationContext`, it would return a
|
||||
`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.
|
||||
|
||||
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]
|
||||
[subs="verbatim,quotes"]
|
||||
----
|
||||
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
|
||||
`java.net.URL` prefixes:
|
||||
Similarly, you can force a `UrlResource` to be used by specifying any of the standard
|
||||
`java.net.URL` prefixes. The following pair of examples use the `file` and `http`
|
||||
prefixes:
|
||||
|
||||
====
|
||||
[source,java,indent=0]
|
||||
[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");
|
||||
----
|
||||
====
|
||||
|
||||
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]]
|
||||
.Resource strings
|
||||
@@ -270,8 +303,7 @@ The following table summarizes the strategy for converting ``String``s to ``Reso
|
||||
|
||||
| file:
|
||||
| `file:///data/config.xml`
|
||||
| Loaded as a `URL`, from the filesystem. footnote:[But see also
|
||||
pass:specialcharacters,macros[<<resources-filesystemresource-caveats>>].]
|
||||
| Loaded as a `URL` from the filesystem. See also <<resources-filesystemresource-caveats>>.
|
||||
|
||||
| http:
|
||||
| `http://myserver/logo.png`
|
||||
@@ -284,13 +316,14 @@ The following table summarizes the strategy for converting ``String``s to ``Reso
|
||||
|
||||
|
||||
|
||||
|
||||
[[resources-resourceloaderaware]]
|
||||
== The ResourceLoaderAware interface
|
||||
== The `ResourceLoaderAware` interface
|
||||
|
||||
The `ResourceLoaderAware` interface is a special marker interface, identifying objects
|
||||
that expect to be provided with a `ResourceLoader` reference.
|
||||
The `ResourceLoaderAware` interface is a special marker interface that identifies objects
|
||||
that expect to be provided with a `ResourceLoader` reference. The following listing shows
|
||||
the definition of the `ResourceLoaderAware` interface:
|
||||
|
||||
====
|
||||
[source,java,indent=0]
|
||||
[subs="verbatim,quotes"]
|
||||
----
|
||||
@@ -299,50 +332,51 @@ that expect to be provided with a `ResourceLoader` reference.
|
||||
void setResourceLoader(ResourceLoader resourceLoader);
|
||||
}
|
||||
----
|
||||
====
|
||||
|
||||
When a class implements `ResourceLoaderAware` and is deployed into an application
|
||||
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
|
||||
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
|
||||
context directly to load resources, but in general, it's better to use the specialized
|
||||
`ResourceLoader` interface if that's all that's needed. The code would just be coupled
|
||||
to the resource loading interface, which can be considered a utility interface, and not
|
||||
context directly to load resources. However, in general, it is better to use the specialized
|
||||
`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 whole Spring `ApplicationContext` interface.
|
||||
|
||||
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
|
||||
of providing a dependency of type `ResourceLoader` for either a constructor argument or
|
||||
setter method parameter respectively. For more flexibility (including the ability to
|
||||
autowire fields and multiple parameter methods), consider using the new annotation-based
|
||||
autowiring features. In that case, the `ResourceLoader` will be autowired into a field,
|
||||
constructor argument, or method parameter that is expecting the `ResourceLoader` type as
|
||||
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
|
||||
autowire fields and multiple parameter methods), consider using the annotation-based
|
||||
autowiring features. In that case, the `ResourceLoader` is autowired into a field,
|
||||
constructor argument, or method parameter that expects the `ResourceLoader` type as
|
||||
long as the field, constructor, or method in question carries the `@Autowired`
|
||||
annotation. For more information, see <<beans-autowired-annotation>>.
|
||||
|
||||
|
||||
|
||||
|
||||
[[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
|
||||
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
|
||||
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,
|
||||
and expect that they will be injected into it.
|
||||
interface completely, have the bean expose the `Resource` properties it needs,
|
||||
and expect them to be injected into it.
|
||||
|
||||
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
|
||||
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:
|
||||
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
|
||||
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 the following example shows:
|
||||
|
||||
====
|
||||
[source,xml,indent=0]
|
||||
[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"/>
|
||||
</bean>
|
||||
----
|
||||
====
|
||||
|
||||
Note that the resource path has no prefix, so because the application context itself is
|
||||
going to be used as the `ResourceLoader`, the resource itself will be loaded via a
|
||||
`ClassPathResource`, `FileSystemResource`, or `ServletContextResource` (as appropriate)
|
||||
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 is loaded through a
|
||||
`ClassPathResource`, a `FileSystemResource`, or a `ServletContextResource`,
|
||||
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
|
||||
used. The following two examples show how to force a `ClassPathResource` and a
|
||||
`UrlResource` (the latter being used to access a filesystem file).
|
||||
If you need to force a specific `Resource` type to be used, you can use a prefix.
|
||||
The following two examples show how to force a `ClassPathResource` and a
|
||||
`UrlResource` (the latter being used to access a filesystem file):
|
||||
|
||||
====
|
||||
[source,xml,indent=0]
|
||||
[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"/>
|
||||
----
|
||||
|
||||
====
|
||||
|
||||
|
||||
|
||||
[[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]]
|
||||
=== Constructing application contexts
|
||||
=== Constructing Application Contexts
|
||||
|
||||
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.
|
||||
|
||||
When such a location path doesn't 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
|
||||
specific application context. For example, if you create a
|
||||
`ClassPathXmlApplicationContext` as follows:
|
||||
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
|
||||
specific application context. For example, consider the following example, which creates a
|
||||
`ClassPathXmlApplicationContext`:
|
||||
|
||||
====
|
||||
[source,java,indent=0]
|
||||
[subs="verbatim,quotes"]
|
||||
----
|
||||
ApplicationContext ctx = new ClassPathXmlApplicationContext("conf/appContext.xml");
|
||||
----
|
||||
====
|
||||
|
||||
The bean definitions will be loaded from the classpath, as a `ClassPathResource` will be
|
||||
used. But if you create a `FileSystemXmlApplicationContext` as follows:
|
||||
The bean definitions are loaded from the classpath, because a `ClassPathResource` is
|
||||
used. However, consider the following example, which creates a `FileSystemXmlApplicationContext`:
|
||||
|
||||
====
|
||||
[source,java,indent=0]
|
||||
[subs="verbatim,quotes"]
|
||||
----
|
||||
ApplicationContext ctx =
|
||||
new FileSystemXmlApplicationContext("conf/appContext.xml");
|
||||
----
|
||||
====
|
||||
|
||||
The bean definition will be loaded from a filesystem location, in this case relative to
|
||||
the current working directory.
|
||||
Now the bean definition is loaded from a filesystem location (in this case, relative to
|
||||
the current working directory).
|
||||
|
||||
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
|
||||
definition. So this `FileSystemXmlApplicationContext`...
|
||||
location path overrides the default type of `Resource` created to load the
|
||||
definition. Consider the folowing example:
|
||||
|
||||
[source,java,indent=0]
|
||||
[subs="verbatim,quotes"]
|
||||
@@ -422,23 +465,24 @@ definition. So this `FileSystemXmlApplicationContext`...
|
||||
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
|
||||
unprefixed paths will still be treated as filesystem paths.
|
||||
unprefixed paths are still treated as filesystem paths.
|
||||
|
||||
|
||||
|
||||
[[resources-app-ctx-classpathxml]]
|
||||
==== Constructing ClassPathXmlApplicationContext instances - shortcuts
|
||||
==== Constructing `ClassPathXmlApplicationContext` Instances -- Shortcuts
|
||||
|
||||
The `ClassPathXmlApplicationContext` exposes a number of constructors to enable
|
||||
convenient instantiation. The basic idea is that one supplies merely a string array
|
||||
containing just the filenames of the XML files themselves (without the leading path
|
||||
information), and one __also__ supplies a `Class`; the `ClassPathXmlApplicationContext`
|
||||
will derive the path information from the supplied class.
|
||||
convenient instantiation. The basic idea is that you can supply merely a string array
|
||||
that contains only the filenames of the XML files themselves (without the leading path
|
||||
information) and also supplies a `Class`. The `ClassPathXmlApplicationContext`
|
||||
then derives the path information from the supplied class.
|
||||
|
||||
An example will hopefully make this clear. Consider a directory layout that looks like
|
||||
this:
|
||||
Consider the following directory layout:
|
||||
|
||||
====
|
||||
[literal]
|
||||
[subs="verbatim,quotes"]
|
||||
----
|
||||
@@ -448,48 +492,53 @@ com/
|
||||
daos.xml
|
||||
MessengerService.class
|
||||
----
|
||||
====
|
||||
|
||||
A `ClassPathXmlApplicationContext` instance composed of the beans defined in the
|
||||
`'services.xml'` and `'daos.xml'` could be instantiated like so...
|
||||
The following example shows how a `ClassPathXmlApplicationContext` instance composed of the beans defined in
|
||||
files named `services.xml` and `daos.xml` (which are on the classpath) can be instantiated:
|
||||
|
||||
====
|
||||
[source,java,indent=0]
|
||||
[subs="verbatim,quotes"]
|
||||
----
|
||||
ApplicationContext ctx = new ClassPathXmlApplicationContext(
|
||||
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.
|
||||
|
||||
|
||||
|
||||
[[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
|
||||
shown above) 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
|
||||
(matched using Spring's `PathMatcher` utility). Both of the latter are effectively
|
||||
wildcards
|
||||
The resource paths in application context constructor values may be simple paths (as
|
||||
shown earlier), each of which has a one-to-one mapping to a target `Resource` or, alternately, may
|
||||
contain the special "classpath*:" prefix or internal Ant-style regular expressions
|
||||
(matched by using Spring's `PathMatcher` utility). Both of the latter are effectively
|
||||
wildcards.
|
||||
|
||||
One use for this mechanism is when doing component-style application assembly. All
|
||||
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
|
||||
`classpath*:`, all component fragments will be picked up automatically.
|
||||
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,
|
||||
when the final application context is created using the same path prefixed with
|
||||
`classpath*:`, all component fragments are automatically picked up.
|
||||
|
||||
Note that this wildcarding is specific to use of resource paths in application context
|
||||
constructors (or when using the `PathMatcher` utility class hierarchy directly), and is
|
||||
Note that this wildcarding is specific to the use of resource paths in application context
|
||||
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.
|
||||
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.
|
||||
|
||||
|
||||
|
||||
[[resources-app-ctx-ant-patterns-in-paths]]
|
||||
==== 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]
|
||||
[subs="verbatim"]
|
||||
----
|
||||
@@ -498,101 +547,103 @@ com/mycompany/**/applicationContext.xml
|
||||
file:C:/some/path/*-context.xml
|
||||
classpath:com/mycompany/**/applicationContext.xml
|
||||
----
|
||||
====
|
||||
|
||||
The resolver follows a more complex but defined procedure to try to resolve the
|
||||
wildcard. It produces a Resource for the path up to the last non-wildcard segment and
|
||||
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
|
||||
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
|
||||
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
|
||||
the wildcards.
|
||||
|
||||
[[resources-app-ctx-portability]]
|
||||
===== Implications on portability
|
||||
===== Implications on Portability
|
||||
|
||||
If the specified path is already a file URL (either explicitly, or implicitly because
|
||||
the base `ResourceLoader` is a filesystem one), then wildcarding is guaranteed to work in
|
||||
If the specified path is already a file URL (either implicitly because
|
||||
the base `ResourceLoader` is a filesystem one or explicitly), wildcarding is guaranteed to work in
|
||||
a completely portable fashion.
|
||||
|
||||
If the specified path is a classpath location, then the resolver must obtain the last
|
||||
non-wildcard path segment URL via 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
|
||||
`ClassLoader` javadocs) 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
|
||||
resource resolves to a filesystem location, or a jar URL of some sort, where the
|
||||
classpath resource resolves to a jar location. Still, there is a portability concern on
|
||||
If the specified path is a classpath location, the resolver must obtain the last
|
||||
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
|
||||
`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
|
||||
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
|
||||
this operation.
|
||||
|
||||
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
|
||||
walk the contents of the jar, and resolve the wildcard. This will work in most
|
||||
environments, but will fail in others, and it is strongly recommended that the wildcard
|
||||
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 does work in most
|
||||
environments but fails in others, and we strongly recommend that the wildcard
|
||||
resolution of resources coming from jars be thoroughly tested in your specific
|
||||
environment before you rely on it.
|
||||
|
||||
|
||||
|
||||
[[resources-classpath-wildcards]]
|
||||
==== The classpath*: prefix
|
||||
==== The `classpath*:` Prefix
|
||||
|
||||
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]
|
||||
[subs="verbatim,quotes"]
|
||||
----
|
||||
ApplicationContext ctx =
|
||||
new ClassPathXmlApplicationContext("classpath*:conf/appContext.xml");
|
||||
----
|
||||
====
|
||||
|
||||
This special prefix specifies that all classpath resources that match the given name
|
||||
must be obtained (internally, this essentially happens via a
|
||||
`ClassLoader.getResources(...)` call), and then merged to form the final application
|
||||
must be obtained (internally, this essentially happens through a call to
|
||||
`ClassLoader.getResources(...)`) and then merged to form the final application
|
||||
context definition.
|
||||
|
||||
[NOTE]
|
||||
====
|
||||
The wildcard classpath relies on the `getResources()` method of the underlying
|
||||
NOTE: The wildcard classpath relies on the `getResources()` method of the underlying
|
||||
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
|
||||
within a jar on the classpath:
|
||||
`getClass().getClassLoader().getResources("<someFileInsideTheJar>")`. Try this test with
|
||||
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
|
||||
settings that might affect the classloader behavior.
|
||||
====
|
||||
|
||||
The `classpath*:` prefix can also be combined with a `PathMatcher` pattern in the
|
||||
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
|
||||
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
|
||||
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
|
||||
class loader hierarchy, and then off each resource the same PathMatcher resolution
|
||||
strategy described above is used for the wildcard subpath.
|
||||
class loader hierarchy and then, off each resource, the same `PathMatcher` resolution
|
||||
strategy described earlier is used for the wildcard subpath.
|
||||
|
||||
|
||||
|
||||
[[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
|
||||
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
|
||||
from the root of expanded directories.
|
||||
|
||||
Spring's ability to retrieve classpath entries originates from the JDK's
|
||||
`ClassLoader.getResources()` method which only returns file system locations for a
|
||||
passed-in empty string (indicating potential roots to search). Spring evaluates
|
||||
`URLClassLoader` runtime configuration and the "java.class.path" manifest in jar files
|
||||
as well but this is not guaranteed to lead to portable behavior.
|
||||
`ClassLoader.getResources()` method, which only returns file system locations for an
|
||||
empty string (indicating potential roots to search). Spring evaluates
|
||||
`URLClassLoader` runtime configuration and the `java.class.path` manifest in jar files
|
||||
as well, but this is not guaranteed to lead to portable behavior.
|
||||
|
||||
[NOTE]
|
||||
====
|
||||
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
|
||||
get exposed based on security policies in some environments, e.g. standalone apps on
|
||||
JDK 1.7.0_45 and higher (which requires 'Trusted-Library' setup in your manifests; see
|
||||
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' to be set up in your manifests. See
|
||||
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.
|
||||
@@ -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
|
||||
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]
|
||||
[subs="verbatim,quotes"]
|
||||
----
|
||||
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]
|
||||
[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
|
||||
----
|
||||
|
||||
is used to try to resolve it, the resolver will work off the (first) URL returned by
|
||||
`getResource("com/mycompany")`;. If this base package node exists in multiple
|
||||
classloader locations, the actual end resource may not be underneath. Therefore,
|
||||
preferably, use " `classpath*:`" with the same Ant-style pattern in such a case, which
|
||||
will search all class path locations that contain the root package.
|
||||
Such a resource may be in only one location, but when a path such as the preceding example
|
||||
is used to try to resolve it, the resolver works off the (first) URL returned by
|
||||
`getResource("com/mycompany");`. If this base package node exists in multiple
|
||||
classloader locations, the actual end resource may not be there. Therefore, in such a case
|
||||
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]]
|
||||
=== FileSystemResource caveats
|
||||
=== `FileSystemResource` Caveats
|
||||
|
||||
A `FileSystemResource` that is not attached to a `FileSystemApplicationContext` (that
|
||||
is, a `FileSystemApplicationContext` is not the actual `ResourceLoader`) will treat
|
||||
absolute vs. relative paths as you would expect. Relative paths are relative to the
|
||||
is, when a `FileSystemApplicationContext` is not the actual `ResourceLoader`) treats
|
||||
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
|
||||
filesystem.
|
||||
|
||||
For backwards compatibility (historical) reasons however, this changes when 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.
|
||||
In practice, this means the following are equivalent:
|
||||
In practice, this means the following examples are equivalent:
|
||||
|
||||
====
|
||||
[source,java,indent=0]
|
||||
[subs="verbatim,quotes"]
|
||||
----
|
||||
@@ -654,10 +709,12 @@ In practice, this means the following are equivalent:
|
||||
ApplicationContext ctx =
|
||||
new FileSystemXmlApplicationContext("/conf/context.xml");
|
||||
----
|
||||
====
|
||||
|
||||
As are the following: (Even though it would make sense for them to be different, as one
|
||||
case is relative and the other absolute.)
|
||||
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):
|
||||
|
||||
====
|
||||
[source,java,indent=0]
|
||||
[subs="verbatim,quotes"]
|
||||
----
|
||||
@@ -671,11 +728,14 @@ case is relative and the other absolute.)
|
||||
FileSystemXmlApplicationContext ctx = ...;
|
||||
ctx.getResource("/some/resource/path/myTemplate.txt");
|
||||
----
|
||||
====
|
||||
|
||||
In practice, if true absolute filesystem paths are needed, it is better to forgo the use
|
||||
of absolute paths with `FileSystemResource` / `FileSystemXmlApplicationContext`, and
|
||||
just force the use of a `UrlResource`, by using the `file:` URL prefix.
|
||||
In practice, if you need true absolute filesystem paths, you should avoid using
|
||||
absolute paths with `FileSystemResource` or `FileSystemXmlApplicationContext` and
|
||||
force the use of a `UrlResource` by using the `file:` URL prefix. The following examples
|
||||
show how to do so:
|
||||
|
||||
====
|
||||
[source,java,indent=0]
|
||||
[subs="verbatim,quotes"]
|
||||
----
|
||||
@@ -690,3 +750,4 @@ just force the use of a `UrlResource`, by using the `file:` URL prefix.
|
||||
ApplicationContext ctx =
|
||||
new FileSystemXmlApplicationContext("file:///conf/context.xml");
|
||||
----
|
||||
====
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user