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
@@ -143,7 +144,7 @@ The following example shows the basic structure of XML-based configuration metad
@ -2568,6 +2570,7 @@ The following table describes the supported scopes:
@@ -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:
@@ -2957,7 +2960,7 @@ understand the "`why`" as well as the "`how`" behind it:
<!-- an HTTP Session-scoped bean exposed as a proxy -->
<!-- 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.
@@ -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.
@@ -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:
@@ -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
@@ -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:
@@ -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
@@ -5516,7 +5519,7 @@ named customerPreferenceDao and then falls back to a primary type match for the
@ -5630,7 +5633,7 @@ annotation. For example, the `@Service` annotation mentioned <<beans-stereotype-
@@ -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:
@@ -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:
@@ -8191,7 +8194,7 @@ the following example shows:
}
@Bean("dataSource")
**@Profile("production")**
@Profile("production") <2>
public DataSource jndiDataSource() throws Exception {
@ -8199,6 +8202,7 @@ the following example shows:
@@ -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:
@@ -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
@@ -9460,6 +9465,7 @@ The following table lists features provided by the `BeanFactory` and
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
@@ -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
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.
@@ -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.
@@ -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.
@@ -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
Spring includes the following `Resource` implementations:
There are a number of `Resource` implementations that come supplied straight out of the
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
@@ -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:
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
@@ -256,8 +288,9 @@ Similarly, one can force a `UrlResource` to be used by specifying any of the sta
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
@@ -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
| 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
@@ -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.
@@ -299,50 +332,51 @@ that expect to be provided with a `ResourceLoader` reference.
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:
@@ -350,16 +384,18 @@ be configured with a simple string for that resource, as follows:
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
@@ -371,49 +407,56 @@ used. The following two examples show how to force a `ClassPathResource` and a
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`...
@@ -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.
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
@@ -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
@@ -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:
@@ -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.)
@@ -671,11 +728,14 @@ case is relative and the other absolute.)
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.
@@ -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");