Merge branch '5.1.x'
This commit is contained in:
@@ -1,14 +1,10 @@
|
||||
[[aop-api]]
|
||||
= Spring AOP APIs
|
||||
|
||||
The previous chapter described the Spring's support for AOP with
|
||||
@AspectJ and schema-based aspect definitions. In this chapter, we discuss the lower-level
|
||||
Spring AOP APIs and the AOP support typically used in Spring 1.2 applications. For new
|
||||
applications, we recommend the use of the Spring 2.0 and later AOP support described in
|
||||
the previous chapter. However, when you work with existing applications (or when you read books
|
||||
and articles), you may come across Spring 1.2-style examples. Spring 5 remains backwards
|
||||
compatible with Spring 1.2, and everything described in this chapter is fully supported
|
||||
in Spring 5.
|
||||
The previous chapter described the Spring's support for AOP with @AspectJ and schema-based
|
||||
aspect definitions. In this chapter, we discuss the lower-level Spring AOP APIs. For common
|
||||
applications, we recommend the use of Spring AOP with AspectJ pointcuts as described in the
|
||||
previous chapter.
|
||||
|
||||
|
||||
|
||||
@@ -111,7 +107,7 @@ Since 2.0, the most important type of pointcut used by Spring is
|
||||
`org.springframework.aop.aspectj.AspectJExpressionPointcut`. This is a pointcut that
|
||||
uses an AspectJ-supplied library to parse an AspectJ pointcut expression string.
|
||||
|
||||
See the <<aop,previous chapter>> for a discussion of supported AspectJ pointcut primitives.
|
||||
See the <<aop, previous chapter>> for a discussion of supported AspectJ pointcut primitives.
|
||||
|
||||
|
||||
|
||||
@@ -241,8 +237,7 @@ following example shows how to subclass `StaticMethodMatcherPointcut`:
|
||||
----
|
||||
|
||||
There are also superclasses for dynamic pointcuts.
|
||||
|
||||
You can use custom pointcuts with any advice type in Spring 1.0 RC2 and above.
|
||||
You can use custom pointcuts with any advice type.
|
||||
|
||||
|
||||
|
||||
@@ -996,8 +991,7 @@ to consider:
|
||||
and included in the spring-core JAR. In other words, CGLIB-based AOP works "`out of
|
||||
the box`", as do JDK dynamic proxies.
|
||||
|
||||
There is little performance difference between CGLIB proxying and dynamic proxies. As of
|
||||
Spring 1.0, dynamic proxies are slightly faster. However, this may change in the future.
|
||||
There is little performance difference between CGLIB proxying and dynamic proxies.
|
||||
Performance should not be a decisive consideration in this case.
|
||||
|
||||
|
||||
@@ -1092,7 +1086,7 @@ we override the transaction propagation settings:
|
||||
|
||||
Note that in the parent bean example, we explicitly marked the parent bean definition as
|
||||
being abstract by setting the `abstract` attribute to `true`, as described
|
||||
<<beans-child-bean-definitions,previously>>, so that it may not actually ever be
|
||||
<<beans-child-bean-definitions, previously>>, so that it may not actually ever be
|
||||
instantiated. Application contexts (but not simple bean factories), by default,
|
||||
pre-instantiate all singletons. Therefore, it is important (at least for singleton beans)
|
||||
that, if you have a (parent) bean definition that you intend to use only as a template,
|
||||
@@ -1226,9 +1220,7 @@ Depending on how you created the proxy, you can usually set a `frozen` flag. In
|
||||
case, the `Advised` `isFrozen()` method returns `true`, and any attempts to modify
|
||||
advice through addition or removal results in an `AopConfigException`. The ability
|
||||
to freeze the state of an advised object is useful in some cases (for example, to
|
||||
prevent calling code removing a security interceptor). It may also be used in Spring 1.1
|
||||
to allow aggressive optimization if runtime advice modification is known not to be
|
||||
required.
|
||||
prevent calling code removing a security interceptor).
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -2,33 +2,31 @@
|
||||
= Aspect Oriented Programming with Spring
|
||||
|
||||
Aspect-oriented Programming (AOP) complements Object-oriented Programming (OOP) by
|
||||
providing another way of thinking about program structure. The key unit of modularity in
|
||||
OOP is the class, whereas in AOP the unit of modularity is the aspect. Aspects
|
||||
providing another way of thinking about program structure. The key unit of modularity
|
||||
in OOP is the class, whereas in AOP the unit of modularity is the aspect. Aspects
|
||||
enable the modularization of concerns (such as transaction management) that cut across
|
||||
multiple types and objects. (Such concerns are often termed "`crosscutting`" concerns in
|
||||
AOP literature.)
|
||||
multiple types and objects. (Such concerns are often termed "`crosscutting`" concerns
|
||||
in AOP literature.)
|
||||
|
||||
One of the key components of Spring is the AOP framework. While the Spring IoC
|
||||
container does not depend on AOP (meaning you do not need to use AOP if you don't want
|
||||
to), AOP complements Spring IoC to provide a very capable middleware solution.
|
||||
|
||||
.Spring 2.0+ AOP
|
||||
.Spring AOP with AspectJ pointcuts
|
||||
****
|
||||
Spring 2.0 introduced a simpler and more powerful way of writing custom aspects by using
|
||||
either a <<aop-schema,schema-based approach>> or the <<aop-ataspectj,@AspectJ annotation
|
||||
style>>. Both of these styles offer fully typed advice and use of the AspectJ pointcut
|
||||
language while still using Spring AOP for weaving.
|
||||
Spring provides simple and powerful ways of writing custom aspects by using either a
|
||||
<<aop-schema, schema-based approach>> or the <<aop-ataspectj, @AspectJ annotation style>>.
|
||||
Both of these styles offer fully typed advice and use of the AspectJ pointcut language
|
||||
while still using Spring AOP for weaving.
|
||||
|
||||
This chapter discusses the Spring 2.0+ schema- and @AspectJ-based AOP support.
|
||||
The lower-level AOP support, as commonly exposed in Spring 1.2 applications, is
|
||||
discussed in <<aop-api,the following chapter>>.
|
||||
This chapter discusses the schema- and @AspectJ-based AOP support.
|
||||
The lower-level AOP support is discussed in <<aop-api, the following chapter>>.
|
||||
****
|
||||
|
||||
AOP is used in the Spring Framework to:
|
||||
|
||||
* Provide declarative enterprise services, especially as a replacement for EJB
|
||||
declarative services. The most important such service is
|
||||
<<transaction-declarative,declarative transaction management>>.
|
||||
* Provide declarative enterprise services. The most important such service is
|
||||
<<transaction-declarative, declarative transaction management>>.
|
||||
* Let users implement custom aspects, complementing their use of OOP with AOP.
|
||||
|
||||
NOTE: If you are interested only in generic declarative services or other pre-packaged
|
||||
@@ -48,7 +46,7 @@ However, it would be even more confusing if Spring used its own terminology.
|
||||
* Aspect: A modularization of a concern that cuts across multiple classes.
|
||||
Transaction management is a good example of a crosscutting concern in enterprise Java
|
||||
applications. In Spring AOP, aspects are implemented by using regular classes
|
||||
(the <<aop-schema,schema-based approach>>) or regular classes annotated with the
|
||||
(the <<aop-schema, schema-based approach>>) or regular classes annotated with the
|
||||
`@Aspect` annotation (the <<aop-ataspectj, @AspectJ style>>).
|
||||
* Join point: A point during the execution of a program, such as the execution of a
|
||||
method or the handling of an exception. In Spring AOP, a join point always
|
||||
@@ -104,14 +102,14 @@ the same thing. Using the most specific advice type provides a simpler programmi
|
||||
with less potential for errors. For example, you do not need to invoke the `proceed()`
|
||||
method on the `JoinPoint` used for around advice, and, hence, you cannot fail to invoke it.
|
||||
|
||||
In Spring 2.0, all advice parameters are statically typed so that you work with advice
|
||||
parameters of the appropriate type (the type of the return value from a method execution
|
||||
for example) rather than `Object` arrays.
|
||||
All advice parameters are statically typed so that you work with advice parameters of
|
||||
the appropriate type (e.g. the type of the return value from a method execution) rather
|
||||
than `Object` arrays.
|
||||
|
||||
The concept of join points matched by pointcuts is the key to AOP, which distinguishes
|
||||
it from older technologies offering only interception. Pointcuts enable advice to be
|
||||
targeted independently of the object-oriented hierarchy. For example, you can apply an around advice
|
||||
providing declarative transaction management to a set of methods that span
|
||||
targeted independently of the object-oriented hierarchy. For example, you can apply an
|
||||
around advice providing declarative transaction management to a set of methods that span
|
||||
multiple objects (such as all business operations in the service layer).
|
||||
|
||||
|
||||
@@ -149,8 +147,8 @@ frameworks such as AspectJ are valuable and that they are complementary, rather
|
||||
competition. Spring seamlessly integrates Spring AOP and IoC with AspectJ, to enable
|
||||
all uses of AOP within a consistent Spring-based application
|
||||
architecture. This integration does not affect the Spring AOP API or the AOP Alliance
|
||||
API. Spring AOP remains backward-compatible. See <<aop-api,the following chapter>> for a
|
||||
discussion of the Spring AOP APIs.
|
||||
API. Spring AOP remains backward-compatible. See <<aop-api, the following chapter>>
|
||||
for a discussion of the Spring AOP APIs.
|
||||
|
||||
[NOTE]
|
||||
====
|
||||
@@ -171,8 +169,8 @@ configuration-style approach. The fact that this chapter chooses to introduce th
|
||||
@AspectJ-style approach first should not be taken as an indication that the Spring team
|
||||
favors the @AspectJ annotation-style approach over the Spring XML configuration-style.
|
||||
|
||||
See <<aop-choosing>> for a more complete discussion of the "`whys and wherefores`" of each
|
||||
style.
|
||||
See <<aop-choosing>> for a more complete discussion of the "`whys and wherefores`" of
|
||||
each style.
|
||||
====
|
||||
|
||||
|
||||
@@ -188,7 +186,7 @@ Spring AOP can also use CGLIB proxies. This is necessary to proxy classes rather
|
||||
interfaces. By default, CGLIB is used if a business object does not implement an
|
||||
interface. As it is good practice to program to interfaces rather than classes, business
|
||||
classes normally implement one or more business interfaces. It is possible to
|
||||
<<aop-proxying,force the use of CGLIB>>, in those (hopefully rare) cases where you
|
||||
<<aop-proxying, force the use of CGLIB>>, in those (hopefully rare) cases where you
|
||||
need to advise a method that is not declared on an interface or where you need to
|
||||
pass a proxied object to a method as a concrete type.
|
||||
|
||||
@@ -209,8 +207,8 @@ interprets the same annotations as AspectJ 5, using a library supplied by Aspect
|
||||
for pointcut parsing and matching. The AOP runtime is still pure Spring AOP, though, and
|
||||
there is no dependency on the AspectJ compiler or weaver.
|
||||
|
||||
NOTE: Using the AspectJ compiler and weaver enables use of the full AspectJ language and is
|
||||
discussed in <<aop-using-aspectj>>.
|
||||
NOTE: Using the AspectJ compiler and weaver enables use of the full AspectJ language and
|
||||
is discussed in <<aop-using-aspectj>>.
|
||||
|
||||
|
||||
|
||||
@@ -259,9 +257,9 @@ element, as the following example shows:
|
||||
----
|
||||
|
||||
This assumes that you use schema support as described in
|
||||
<<core.adoc#xsd-schemas, XML Schema-based configuration>>. See
|
||||
<<core.adoc#xsd-schemas-aop, the AOP schema>> for how to import the tags in the `aop`
|
||||
namespace.
|
||||
<<core.adoc#xsd-schemas, XML Schema-based configuration>>.
|
||||
See <<core.adoc#xsd-schemas-aop, the AOP schema>> for how to
|
||||
import the tags in the `aop` namespace.
|
||||
|
||||
|
||||
|
||||
@@ -273,8 +271,8 @@ class that is an @AspectJ aspect (has the `@Aspect` annotation) is automatically
|
||||
detected by Spring and used to configure Spring AOP. The next two examples show the
|
||||
minimal definition required for a not-very-useful aspect.
|
||||
|
||||
The first of the two example shows a regular bean definition in the application context that points to a bean class that has
|
||||
the `@Aspect` annotation:
|
||||
The first of the two example shows a regular bean definition in the application
|
||||
context that points to a bean class that has the `@Aspect` annotation:
|
||||
|
||||
[source,xml,indent=0]
|
||||
[subs="verbatim,quotes"]
|
||||
@@ -284,8 +282,8 @@ the `@Aspect` annotation:
|
||||
</bean>
|
||||
----
|
||||
|
||||
The second of the two examples shows the `NotVeryUsefulAspect` class definition, which is annotated with
|
||||
the `org.aspectj.lang.annotation.Aspect` annotation;
|
||||
The second of the two examples shows the `NotVeryUsefulAspect` class definition,
|
||||
which is annotated with the `org.aspectj.lang.annotation.Aspect` annotation;
|
||||
|
||||
[source,java,indent=0]
|
||||
[subs="verbatim,quotes"]
|
||||
@@ -413,7 +411,7 @@ If a pointcut is strictly meant to be public-only, even in a CGLIB proxy scenari
|
||||
potential non-public interactions through proxies, it needs to be defined accordingly.
|
||||
|
||||
If your interception needs include method calls or even constructors within the target
|
||||
class, consider the use of Spring-driven <<aop-aj-ltw,native AspectJ weaving>> instead
|
||||
class, consider the use of Spring-driven <<aop-aj-ltw, native AspectJ weaving>> instead
|
||||
of Spring's proxy-based AOP framework. This constitutes a different mode of AOP usage
|
||||
with different characteristics, so be sure to make yourself familiar with weaving
|
||||
before making a decision.
|
||||
@@ -1032,8 +1030,8 @@ taken by Spring is simpler and a better match to its proxy-based, execution-only
|
||||
semantics. You only need to be aware of this difference if you compile @AspectJ
|
||||
aspects written for Spring and use `proceed` with arguments with the AspectJ compiler
|
||||
and weaver. There is a way to write such aspects that is 100% compatible across both
|
||||
Spring AOP and AspectJ, and this is discussed in the <<aop-ataspectj-advice-params,following section on advice
|
||||
parameters>>.
|
||||
Spring AOP and AspectJ, and this is discussed in the
|
||||
<<aop-ataspectj-advice-params, following section on advice parameters>>.
|
||||
|
||||
The following example shows how to use around advice:
|
||||
|
||||
@@ -1551,8 +1549,7 @@ of advice parameters.
|
||||
|
||||
To use the aop namespace tags described in this section, you need to import the
|
||||
`spring-aop` schema, as described in <<core.adoc#xsd-schemas,
|
||||
XML Schema-based configuration>>.
|
||||
See <<core.adoc#xsd-schemas-aop, the AOP schema>>
|
||||
XML Schema-based configuration>>. See <<core.adoc#xsd-schemas-aop, the AOP schema>>
|
||||
for how to import the tags in the `aop` namespace.
|
||||
|
||||
Within your Spring configurations, all aspect and advisor elements must be placed within
|
||||
@@ -1561,10 +1558,11 @@ application context configuration). An `<aop:config>` element can contain pointc
|
||||
advisor, and aspect elements (note that these must be declared in that order).
|
||||
|
||||
WARNING: The `<aop:config>` style of configuration makes heavy use of Spring's
|
||||
<<aop-autoproxy,auto-proxying>> mechanism. This can cause issues (such as advice not
|
||||
being woven) if you already use explicit auto-proxying through the use of
|
||||
`BeanNameAutoProxyCreator` or something similar. The recommended usage pattern is to use either
|
||||
only the `<aop:config>` style or only the `AutoProxyCreator` style and never mix them.
|
||||
<<aop-autoproxy, auto-proxying>> mechanism. This can cause issues (such as advice
|
||||
not being woven) if you already use explicit auto-proxying through the use of
|
||||
`BeanNameAutoProxyCreator` or something similar. The recommended usage pattern is to
|
||||
use either only the `<aop:config>` style or only the `AutoProxyCreator` style and
|
||||
never mix them.
|
||||
|
||||
|
||||
|
||||
@@ -1618,10 +1616,9 @@ be defined as follows:
|
||||
----
|
||||
|
||||
Note that the pointcut expression itself is using the same AspectJ pointcut expression
|
||||
language as described in <<aop-ataspectj>>. If you use the schema based
|
||||
declaration style, you can refer to named pointcuts defined in types
|
||||
(@Aspects) within the pointcut expression. Another way of defining the above pointcut
|
||||
would be as follows:
|
||||
language as described in <<aop-ataspectj>>. If you use the schema based declaration
|
||||
style, you can refer to named pointcuts defined in types (@Aspects) within the
|
||||
pointcut expression. Another way of defining the above pointcut would be as follows:
|
||||
|
||||
[source,xml,indent=0]
|
||||
[subs="verbatim,quotes"]
|
||||
@@ -2413,11 +2410,11 @@ The downside of the XML approach is that you cannot define the
|
||||
|
||||
The @AspectJ style supports additional instantiation models and richer pointcut
|
||||
composition. It has the advantage of keeping the aspect as a modular unit. It also has
|
||||
the advantage that the @AspectJ aspects can be understood (and thus consumed) both by Spring
|
||||
AOP and by AspectJ. So, if you later decide you need the capabilities of AspectJ to
|
||||
implement additional requirements, you can easily migrate to an AspectJ-based
|
||||
approach. On balance, the Spring team prefers the @AspectJ style whenever you have aspects
|
||||
that do more than simple configuration of enterprise services.
|
||||
the advantage that the @AspectJ aspects can be understood (and thus consumed) both by
|
||||
Spring AOP and by AspectJ. So, if you later decide you need the capabilities of AspectJ
|
||||
to implement additional requirements, you can easily migrate to a classic AspectJ setup.
|
||||
On balance, the Spring team prefers the @AspectJ style for custom aspects beyond simple
|
||||
configuration of enterprise services.
|
||||
|
||||
|
||||
|
||||
@@ -2426,10 +2423,9 @@ that do more than simple configuration of enterprise services.
|
||||
== Mixing Aspect Types
|
||||
|
||||
It is perfectly possible to mix @AspectJ style aspects by using the auto-proxying support,
|
||||
schema-defined `<aop:aspect>` aspects, `<aop:advisor>` declared advisors, and even
|
||||
proxies and interceptors defined with the Spring 1.2 style in the same configuration.
|
||||
All of these are implemented by using the same underlying support mechanism and can
|
||||
co-exist without any difficulty.
|
||||
schema-defined `<aop:aspect>` aspects, `<aop:advisor>` declared advisors, and even proxies
|
||||
and interceptors in other styles in the same configuration. All of these are implemented
|
||||
by using the same underlying support mechanism and can co-exist without any difficulty.
|
||||
|
||||
|
||||
|
||||
@@ -2438,29 +2434,26 @@ co-exist without any difficulty.
|
||||
== Proxying Mechanisms
|
||||
|
||||
Spring AOP uses either JDK dynamic proxies or CGLIB to create the proxy for a given
|
||||
target object. (JDK dynamic proxies are preferred whenever you have a choice).
|
||||
target object. JDK dynamic proxies are built into the JDK, whereas CGLIB is a common
|
||||
open-source class definition library (repackaged into `spring-core`).
|
||||
|
||||
If the target object to be proxied implements at least one interface, a JDK dynamic
|
||||
proxy is used. All of the interfaces implemented by the target type are
|
||||
proxied. If the target object does not implement any interfaces, a CGLIB proxy is
|
||||
created.
|
||||
proxy is used. All of the interfaces implemented by the target type are proxied.
|
||||
If the target object does not implement any interfaces, a CGLIB proxy is created.
|
||||
|
||||
If you want to force the use of CGLIB proxying (for example, to proxy every method
|
||||
defined for the target object, not only those implemented by its interfaces), you can do
|
||||
so. However, you should consider the following issues:
|
||||
defined for the target object, not only those implemented by its interfaces),
|
||||
you can do so. However, you should consider the following issues:
|
||||
|
||||
* `final` methods cannot be advised, as they cannot be overridden.
|
||||
* As of Spring 3.2, it is no longer necessary to add CGLIB to your project classpath, as
|
||||
CGLIB classes are repackaged under `org.springframework` and included directly in the
|
||||
spring-core JAR. This means that CGLIB-based proxy support "`just works`", in the same
|
||||
way that JDK dynamic proxies always have.
|
||||
* As of Spring 4.0, the constructor of your proxied object is NOT called twice
|
||||
any more, since the CGLIB proxy instance is created through Objenesis. Only if your
|
||||
JVM does not allow for constructor bypassing, you might see double invocations and
|
||||
* With CGLIB, `final` methods cannot be advised, as they cannot be overridden in
|
||||
runtime-generated subclasses.
|
||||
* As of Spring 4.0, the constructor of your proxied object is NOT called twice anymore,
|
||||
since the CGLIB proxy instance is created through Objenesis. Only if your JVM does
|
||||
not allow for constructor bypassing, you might see double invocations and
|
||||
corresponding debug log entries from Spring's AOP support.
|
||||
|
||||
To force the use of CGLIB proxies, set the value of the `proxy-target-class` attribute of
|
||||
the `<aop:config>` element to true, as follows:
|
||||
To force the use of CGLIB proxies, set the value of the `proxy-target-class` attribute
|
||||
of the `<aop:config>` element to true, as follows:
|
||||
|
||||
[source,xml,indent=0]
|
||||
[subs="verbatim,quotes"]
|
||||
@@ -2471,8 +2464,8 @@ the `<aop:config>` element to true, as follows:
|
||||
----
|
||||
|
||||
To force CGLIB proxying when you use the @AspectJ auto-proxy support, set the
|
||||
`proxy-target-class` attribute of the `<aop:aspectj-autoproxy>` element to `true`, as
|
||||
follows:
|
||||
`proxy-target-class` attribute of the `<aop:aspectj-autoproxy>` element to `true`,
|
||||
as follows:
|
||||
|
||||
[source,xml,indent=0]
|
||||
[subs="verbatim,quotes"]
|
||||
@@ -2533,9 +2526,7 @@ image::images/aop-proxy-plain-pojo-call.png[]
|
||||
public class Main {
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
Pojo pojo = new SimplePojo();
|
||||
|
||||
// this is a direct method call on the 'pojo' reference
|
||||
pojo.foo();
|
||||
}
|
||||
@@ -2553,36 +2544,33 @@ image::images/aop-proxy-call.png[]
|
||||
public class Main {
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
ProxyFactory factory = new ProxyFactory(new SimplePojo());
|
||||
factory.addInterface(Pojo.class);
|
||||
factory.addAdvice(new RetryAdvice());
|
||||
|
||||
Pojo pojo = (Pojo) factory.getProxy();
|
||||
|
||||
// this is a method call on the proxy!
|
||||
pojo.foo();
|
||||
}
|
||||
}
|
||||
----
|
||||
|
||||
The key thing to understand here is that the client code inside the `main(..)` method of the
|
||||
`Main` class has a reference to the proxy. This means that method calls on that
|
||||
object reference are calls on the proxy. As a result, the proxy can
|
||||
delegate to all of the interceptors (advice) that are relevant to that particular method
|
||||
call. However, once the call has finally reached the target object (the `SimplePojo`,
|
||||
reference in this case), any method calls that it may make on itself, such as
|
||||
`this.bar()` or `this.foo()`, are going to be invoked against the `this` reference,
|
||||
and not the proxy. This has important implications. It means that self-invocation is
|
||||
not going to result in the advice associated with a method invocation getting a
|
||||
chance to execute.
|
||||
The key thing to understand here is that the client code inside the `main(..)` method
|
||||
of the `Main` class has a reference to the proxy. This means that method calls on that
|
||||
object reference are calls on the proxy. As a result, the proxy can delegate to all of
|
||||
the interceptors (advice) that are relevant to that particular method call. However,
|
||||
once the call has finally reached the target object (the `SimplePojo`, reference in
|
||||
this case), any method calls that it may make on itself, such as `this.bar()` or
|
||||
`this.foo()`, are going to be invoked against the `this` reference, and not the proxy.
|
||||
This has important implications. It means that self-invocation is not going to result
|
||||
in the advice associated with a method invocation getting a chance to execute.
|
||||
|
||||
Okay, so what is to be done about this? The best approach (the term, "`best,`" is used loosely
|
||||
here) is to refactor your code such that the self-invocation does not happen.
|
||||
Okay, so what is to be done about this? The best approach (the term, "`best,`" is used
|
||||
loosely here) is to refactor your code such that the self-invocation does not happen.
|
||||
This does entail some work on your part, but it is the best, least-invasive approach.
|
||||
The next approach is absolutely horrendous, and we hesitate to point it out,
|
||||
precisely because it is so horrendous. You can (painful as it is to us) totally tie the logic within
|
||||
your class to Spring AOP, as the following example shows:
|
||||
The next approach is absolutely horrendous, and we hesitate to point it out, precisely
|
||||
because it is so horrendous. You can (painful as it is to us) totally tie the logic
|
||||
within your class to Spring AOP, as the following example shows:
|
||||
|
||||
[source,java,indent=0]
|
||||
[subs="verbatim,quotes"]
|
||||
@@ -2611,14 +2599,12 @@ following example shows:
|
||||
public class Main {
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
ProxyFactory factory = new ProxyFactory(new SimplePojo());
|
||||
factory.adddInterface(Pojo.class);
|
||||
factory.addAdvice(new RetryAdvice());
|
||||
factory.setExposeProxy(true);
|
||||
|
||||
Pojo pojo = (Pojo) factory.getProxy();
|
||||
|
||||
// this is a method call on the proxy!
|
||||
pojo.foo();
|
||||
}
|
||||
@@ -2634,11 +2620,11 @@ it is not a proxy-based AOP framework.
|
||||
[[aop-aspectj-programmatic]]
|
||||
== Programmatic Creation of @AspectJ Proxies
|
||||
|
||||
In addition to declaring aspects in your configuration by using either `<aop:config>` or
|
||||
`<aop:aspectj-autoproxy>`, it is also possible to programmatically create proxies that
|
||||
advise target objects. For the full details of Spring's AOP API, see the <<aop-api,next chapter>>.
|
||||
Here, we want to focus on the ability to automatically create proxies by using @AspectJ
|
||||
aspects.
|
||||
In addition to declaring aspects in your configuration by using either `<aop:config>`
|
||||
or `<aop:aspectj-autoproxy>`, it is also possible to programmatically create proxies
|
||||
that advise target objects. For the full details of Spring's AOP API, see the
|
||||
<<aop-api, next chapter>>. Here, we want to focus on the ability to automatically
|
||||
create proxies by using @AspectJ aspects.
|
||||
|
||||
You can use the `org.springframework.aop.aspectj.annotation.AspectJProxyFactory` class
|
||||
to create a proxy for a target object that is advised by one or more @AspectJ aspects.
|
||||
@@ -2748,13 +2734,12 @@ Spring now looks for a bean definition named `account` and uses that as the
|
||||
definition to configure new `Account` instances.
|
||||
|
||||
You can also use autowiring to avoid having to specify a dedicated bean definition at
|
||||
all. To have Spring apply autowiring, use the `autowire` property of the
|
||||
`@Configurable` annotation. You can specify either `@Configurable(autowire=Autowire.BY_TYPE)` or
|
||||
all. To have Spring apply autowiring, use the `autowire` property of the `@Configurable`
|
||||
annotation. You can specify either `@Configurable(autowire=Autowire.BY_TYPE)` or
|
||||
`@Configurable(autowire=Autowire.BY_NAME` for autowiring by type or by name,
|
||||
respectively. As an alternative, as of Spring 2.5, it is preferable to specify explicit,
|
||||
annotation-driven dependency injection for your `@Configurable` beans by using
|
||||
`@Autowired` or `@Inject` at the field or method level (see <<beans-annotation-config>>
|
||||
for further details).
|
||||
respectively. As an alternative, it is preferable to specify explicit, annotation-driven
|
||||
dependency injection for your `@Configurable` beans through `@Autowired` or `@Inject`
|
||||
at the field or method level (see <<beans-annotation-config>> for further details).
|
||||
|
||||
Finally, you can enable Spring dependency checking for the object references in the newly
|
||||
created and configured object by using the `dependencyCheck` attribute (for example,
|
||||
@@ -2764,13 +2749,13 @@ are not primitives or collections) have been set.
|
||||
|
||||
Note that using the annotation on its own does nothing. It is the
|
||||
`AnnotationBeanConfigurerAspect` in `spring-aspects.jar` that acts on the presence of
|
||||
the annotation. In essence, the aspect says, "`after returning from the initialization of a
|
||||
new object of a type annotated with `@Configurable`, configure the newly created object
|
||||
the annotation. In essence, the aspect says, "`after returning from the initialization of
|
||||
a new object of a type annotated with `@Configurable`, configure the newly created object
|
||||
using Spring in accordance with the properties of the annotation`". In this context,
|
||||
"`initialization`" refers to newly instantiated objects (for example, objects instantiated with
|
||||
the `new` operator) as well as to `Serializable` objects that are undergoing
|
||||
"`initialization`" refers to newly instantiated objects (for example, objects instantiated
|
||||
with the `new` operator) as well as to `Serializable` objects that are undergoing
|
||||
deserialization (for example, through
|
||||
http://docs.oracle.com/javase/6/docs/api/java/io/Serializable.html[readResolve()]).
|
||||
http://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html[readResolve()]).
|
||||
|
||||
[NOTE]
|
||||
=====
|
||||
@@ -2786,7 +2771,7 @@ available for use in the body of the constructors, you need to define this on th
|
||||
[source,java,indent=0]
|
||||
[subs="verbatim,quotes"]
|
||||
----
|
||||
@Configurable(preConstruction=true)
|
||||
@Configurable(preConstruction = true)
|
||||
----
|
||||
|
||||
You can find more information about the language semantics of the various pointcut
|
||||
@@ -2811,7 +2796,6 @@ use Java-based configuration, you can add `@EnableSpringConfigured` to any
|
||||
@Configuration
|
||||
@EnableSpringConfigured
|
||||
public class AppConfig {
|
||||
|
||||
}
|
||||
----
|
||||
|
||||
@@ -2943,7 +2927,6 @@ fully qualified class names:
|
||||
initialization(new(..)) &&
|
||||
SystemArchitecture.inDomainModel() &&
|
||||
this(beanInstance);
|
||||
|
||||
}
|
||||
----
|
||||
|
||||
@@ -3027,14 +3010,12 @@ per-`ClassLoader` basis, which is more fine-grained and which can make more
|
||||
sense in a 'single-JVM-multiple-application' environment (such as is found in a typical
|
||||
application server environment).
|
||||
|
||||
Further, <<aop-aj-ltw-environments,in certain environments>>, this support enables
|
||||
Further, <<aop-aj-ltw-environments, in certain environments>>, this support enables
|
||||
load-time weaving without making any modifications to the application server's launch
|
||||
script that is needed to add `-javaagent:path/to/aspectjweaver.jar` or (as we
|
||||
describe later in this section)
|
||||
`-javaagent:path/to/org.springframework.instrument-{version}.jar` (previously named
|
||||
`spring-agent.jar`). Developers modify one or more files that form the
|
||||
application context to enable load-time weaving instead of relying on administrators who
|
||||
typically are in charge of the deployment configuration, such as the launch script.
|
||||
script that is needed to add `-javaagent:path/to/aspectjweaver.jar` or (as we describe
|
||||
later in this section) `-javaagent:path/to/spring-instrument.jar`. Developers configure
|
||||
the application context to enable load-time weaving instead of relying on administrators
|
||||
who typically are in charge of the deployment configuration, such as the launch script.
|
||||
|
||||
Now that the sales pitch is over, let us first walk through a quick example of AspectJ
|
||||
LTW that uses Spring, followed by detailed specifics about elements introduced in the
|
||||
@@ -3046,18 +3027,18 @@ https://github.com/spring-projects/spring-petclinic[Petclinic sample application
|
||||
==== A First Example
|
||||
|
||||
Assume that you are an application developer who has been tasked with diagnosing
|
||||
the cause of some performance problems in a system. Rather than break out a profiling
|
||||
tool, we are going to switch on a simple profiling aspect that lets us
|
||||
quickly get some performance metrics. We can then apply a finer-grained
|
||||
profiling tool to that specific area immediately afterwards.
|
||||
the cause of some performance problems in a system. Rather than break out a
|
||||
profiling tool, we are going to switch on a simple profiling aspect that lets us
|
||||
quickly get some performance metrics. We can then apply a finer-grained profiling
|
||||
tool to that specific area immediately afterwards.
|
||||
|
||||
NOTE: The example presented here uses XML configuration. You can also
|
||||
configure and use @AspectJ with <<beans-java,Java configuration>>.
|
||||
Specifically, you can use the `@EnableLoadTimeWeaving` annotation as an alternative to
|
||||
`<context:load-time-weaver/>` (see <<aop-aj-ltw-spring,below>> for details).
|
||||
NOTE: The example presented here uses XML configuration. You can also configure and
|
||||
use @AspectJ with <<beans-java, Java configuration>>. Specifically, you can use the
|
||||
`@EnableLoadTimeWeaving` annotation as an alternative to `<context:load-time-weaver/>`
|
||||
(see <<aop-aj-ltw-spring, below>> for details).
|
||||
|
||||
The following example shows the profiling aspect, which is not fancy -- it is a time-based
|
||||
profiler that uses the @AspectJ-style of aspect declaration:
|
||||
The following example shows the profiling aspect, which is not fancy.
|
||||
It is a time-based profiler that uses the @AspectJ-style of aspect declaration:
|
||||
|
||||
[source,java,indent=0]
|
||||
[subs="verbatim"]
|
||||
@@ -3091,10 +3072,10 @@ profiler that uses the @AspectJ-style of aspect declaration:
|
||||
}
|
||||
----
|
||||
|
||||
We also need to create an `META-INF/aop.xml` file, to inform the AspectJ weaver
|
||||
that we want to weave our `ProfilingAspect` into our classes. This file convention,
|
||||
namely the presence of a file (or files) on the Java classpath called
|
||||
`META-INF/aop.xml` is standard AspectJ. The following example shows the `aop.xml` file:
|
||||
We also need to create an `META-INF/aop.xml` file, to inform the AspectJ weaver that
|
||||
we want to weave our `ProfilingAspect` into our classes. This file convention, namely
|
||||
the presence of a file (or files) on the Java classpath called `META-INF/aop.xml` is
|
||||
standard AspectJ. The following example shows the `aop.xml` file:
|
||||
|
||||
[source,xml,indent=0]
|
||||
[subs="verbatim,quotes"]
|
||||
@@ -3115,12 +3096,13 @@ namely the presence of a file (or files) on the Java classpath called
|
||||
</aspectj>
|
||||
----
|
||||
|
||||
Now we can move on to the Spring-specific portion of the configuration. We need to configure a
|
||||
`LoadTimeWeaver` (explained later). This load-time
|
||||
weaver is the essential component responsible for weaving the aspect configuration in
|
||||
one or more `META-INF/aop.xml` files into the classes in your application. The good
|
||||
thing is that it does not require a lot of configuration (there
|
||||
are some more options that you can specify, but these are detailed later), as can be seen in the following example:
|
||||
Now we can move on to the Spring-specific portion of the configuration. We need
|
||||
to configure a `LoadTimeWeaver` (explained later). This load-time weaver is the
|
||||
essential component responsible for weaving the aspect configuration in one or
|
||||
more `META-INF/aop.xml` files into the classes in your application. The good
|
||||
thing is that it does not require a lot of configuration (there are some more
|
||||
options that you can specify, but these are detailed later), as can be seen in
|
||||
the following example:
|
||||
|
||||
[source,xml,indent=0]
|
||||
[subs="verbatim,quotes"]
|
||||
@@ -3145,8 +3127,8 @@ are some more options that you can specify, but these are detailed later), as ca
|
||||
----
|
||||
|
||||
Now that all the required artifacts (the aspect, the `META-INF/aop.xml`
|
||||
file, and the Spring configuration) are in place, we can create the following driver class with a
|
||||
`main(..)` method to demonstrate the LTW in action:
|
||||
file, and the Spring configuration) are in place, we can create the following
|
||||
driver class with a `main(..)` method to demonstrate the LTW in action:
|
||||
|
||||
[source,java,indent=0]
|
||||
[subs="verbatim,quotes"]
|
||||
@@ -3158,11 +3140,10 @@ file, and the Spring configuration) are in place, we can create the following dr
|
||||
public final class Main {
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
ApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml", Main.class);
|
||||
|
||||
EntitlementCalculationService entitlementCalculationService
|
||||
= (EntitlementCalculationService) ctx.getBean("entitlementCalculationService");
|
||||
EntitlementCalculationService entitlementCalculationService =
|
||||
(EntitlementCalculationService) ctx.getBean("entitlementCalculationService");
|
||||
|
||||
// the profiling aspect is 'woven' around this method execution
|
||||
entitlementCalculationService.calculateEntitlement();
|
||||
@@ -3172,8 +3153,8 @@ file, and the Spring configuration) are in place, we can create the following dr
|
||||
|
||||
We have one last thing to do. The introduction to this section did say that one could
|
||||
switch on LTW selectively on a per-`ClassLoader` basis with Spring, and this is true.
|
||||
However, for this example, we use a Java agent (supplied with Spring)
|
||||
to switch on the LTW. We use the following command to run the `Main` class shown earlier:
|
||||
However, for this example, we use a Java agent (supplied with Spring) to switch on LTW.
|
||||
We use the following command to run the `Main` class shown earlier:
|
||||
|
||||
[literal]
|
||||
[subs="verbatim,quotes"]
|
||||
@@ -3182,7 +3163,7 @@ java -javaagent:C:/projects/foo/lib/global/spring-instrument.jar foo.Main
|
||||
----
|
||||
|
||||
The `-javaagent` is a flag for specifying and enabling
|
||||
http://docs.oracle.com/javase/6/docs/api/java/lang/instrument/package-summary.html[agents
|
||||
http://docs.oracle.com/javase/8/docs/api/java/lang/instrument/package-summary.html[agents
|
||||
to instrument programs that run on the JVM]. The Spring Framework ships with such an
|
||||
agent, the `InstrumentationSavingAgent`, which is packaged in the
|
||||
`spring-instrument.jar` that was supplied as the value of the `-javaagent` argument in
|
||||
@@ -3220,11 +3201,10 @@ result:
|
||||
public final class Main {
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
new ClassPathXmlApplicationContext("beans.xml", Main.class);
|
||||
|
||||
EntitlementCalculationService entitlementCalculationService =
|
||||
new StubEntitlementCalculationService();
|
||||
new StubEntitlementCalculationService();
|
||||
|
||||
// the profiling aspect will be 'woven' around this method execution
|
||||
entitlementCalculationService.calculateEntitlement();
|
||||
@@ -3261,8 +3241,9 @@ Furthermore, the compiled aspect classes need to be available on the classpath.
|
||||
The AspectJ LTW infrastructure is configured by using one or more `META-INF/aop.xml`
|
||||
files that are on the Java classpath (either directly or, more typically, in jar files).
|
||||
|
||||
The structure and contents of this file is detailed in the LTW part http://www.eclipse.org/aspectj/doc/released/devguide/ltw-configuration.html[AspectJ reference
|
||||
documentation]. Because the aop.xml file is 100% AspectJ, we do not describe it further here.
|
||||
The structure and contents of this file is detailed in the LTW part of the
|
||||
http://www.eclipse.org/aspectj/doc/released/devguide/ltw-configuration.html[AspectJ reference
|
||||
documentation]. Because the `aop.xml` file is 100% AspectJ, we do not describe it further here.
|
||||
|
||||
|
||||
[[aop-aj-ltw-libraries]]
|
||||
@@ -3271,10 +3252,10 @@ documentation]. Because the aop.xml file is 100% AspectJ, we do not describe it
|
||||
At minimum, you need the following libraries to use the Spring Framework's support
|
||||
for AspectJ LTW:
|
||||
|
||||
* `spring-aop.jar` (version 2.5 or later, plus all mandatory dependencies)
|
||||
* `aspectjweaver.jar` (version 1.6.8 or later)
|
||||
* `spring-aop.jar`
|
||||
* `aspectjweaver.jar`
|
||||
|
||||
If you use the <<aop-aj-ltw-environment-generic,Spring-provided agent to enable
|
||||
If you use the <<aop-aj-ltw-environment-generic, Spring-provided agent to enable
|
||||
instrumentation>>, you also need:
|
||||
|
||||
* `spring-instrument.jar`
|
||||
@@ -3309,7 +3290,6 @@ which typically is done by using the `@EnableLoadTimeWeaving` annotation, as fol
|
||||
@Configuration
|
||||
@EnableLoadTimeWeaving
|
||||
public class AppConfig {
|
||||
|
||||
}
|
||||
----
|
||||
|
||||
@@ -3335,50 +3315,50 @@ Alternatively, if you prefer XML-based configuration, use the
|
||||
</beans>
|
||||
----
|
||||
|
||||
The preceding configuration automatically defines and registers a number of LTW-specific infrastructure
|
||||
beans, such as a `LoadTimeWeaver` and an `AspectJWeavingEnabler`, for you.
|
||||
The preceding configuration automatically defines and registers a number of LTW-specific
|
||||
infrastructure beans, such as a `LoadTimeWeaver` and an `AspectJWeavingEnabler`, for you.
|
||||
The default `LoadTimeWeaver` is the `DefaultContextLoadTimeWeaver` class, which attempts
|
||||
to decorate an automatically detected `LoadTimeWeaver`. The exact type of
|
||||
`LoadTimeWeaver` that is "`automatically detected`" is dependent upon your runtime
|
||||
environment. The following table summarizes various `LoadTimeWeaver` implementations:
|
||||
to decorate an automatically detected `LoadTimeWeaver`. The exact type of `LoadTimeWeaver`
|
||||
that is "`automatically detected`" is dependent upon your runtime environment.
|
||||
The following table summarizes various `LoadTimeWeaver` implementations:
|
||||
|
||||
[[aop-aj-ltw-spring-env-impls]]
|
||||
.DefaultContextLoadTimeWeaver LoadTimeWeavers
|
||||
|===
|
||||
| Runtime Environment| `LoadTimeWeaver` implementation
|
||||
|
||||
| Running in Oracle's
|
||||
http://www.oracle.com/technetwork/middleware/weblogic/overview/index-085209.html[WebLogic]
|
||||
| `WebLogicLoadTimeWeaver`
|
||||
|
||||
| Running in Oracle's http://glassfish.dev.java.net/[GlassFish]
|
||||
| `GlassFishLoadTimeWeaver`
|
||||
|
||||
| Running in http://tomcat.apache.org/[Apache Tomcat]
|
||||
| `TomcatLoadTimeWeaver`
|
||||
|
||||
| Running in http://glassfish.dev.java.net/[GlassFish] (limited to EAR deployments)
|
||||
| `GlassFishLoadTimeWeaver`
|
||||
|
||||
| Running in Red Hat's http://www.jboss.org/jbossas/[JBoss AS] or http://www.wildfly.org/[WildFly]
|
||||
| `JBossLoadTimeWeaver`
|
||||
|
||||
| Running in IBM's http://www-01.ibm.com/software/webservers/appserv/was/[WebSphere]
|
||||
| `WebSphereLoadTimeWeaver`
|
||||
|
||||
| JVM started with Spring `InstrumentationSavingAgent` (`java
|
||||
-javaagent:path/to/spring-instrument.jar`)
|
||||
| Running in Oracle's
|
||||
http://www.oracle.com/technetwork/middleware/weblogic/overview/index-085209.html[WebLogic]
|
||||
| `WebLogicLoadTimeWeaver`
|
||||
|
||||
| JVM started with Spring `InstrumentationSavingAgent`
|
||||
(`java -javaagent:path/to/spring-instrument.jar`)
|
||||
| `InstrumentationLoadTimeWeaver`
|
||||
|
||||
| Fallback, expecting the underlying ClassLoader to follow common conventions (for example
|
||||
applicable to `TomcatInstrumentableClassLoader` and http://www.caucho.com/[Resin])
|
||||
| Fallback, expecting the underlying ClassLoader to follow common conventions
|
||||
(namely `addTransformer` and optionally a `getThrowawayClassLoader` method)
|
||||
| `ReflectiveLoadTimeWeaver`
|
||||
|===
|
||||
|
||||
Note that the table lists only the `LoadTimeWeavers` that are autodetected when you use the
|
||||
`DefaultContextLoadTimeWeaver`. You can specify exactly which
|
||||
`LoadTimeWeaver` implementation to use.
|
||||
Note that the table lists only the `LoadTimeWeavers` that are autodetected when you
|
||||
use the `DefaultContextLoadTimeWeaver`. You can specify exactly which `LoadTimeWeaver`
|
||||
implementation to use.
|
||||
|
||||
To specify a specific `LoadTimeWeaver` with Java configuration, implement the
|
||||
`LoadTimeWeavingConfigurer` interface and override the `getLoadTimeWeaver()` method. The
|
||||
following example specifies a `ReflectiveLoadTimeWeaver`:
|
||||
`LoadTimeWeavingConfigurer` interface and override the `getLoadTimeWeaver()` method.
|
||||
The following example specifies a `ReflectiveLoadTimeWeaver`:
|
||||
|
||||
[source,java,indent=0]
|
||||
[subs="verbatim,quotes"]
|
||||
@@ -3426,10 +3406,9 @@ the `org.aspectj.weaver.loadtime` package) class. See the class-level javadoc of
|
||||
`ClassPreProcessorAgentAdapter` class for further details, because the specifics of how
|
||||
the weaving is actually effected is beyond the scope of this document.
|
||||
|
||||
There is one final attribute of the configuration left to discuss: the
|
||||
`aspectjWeaving` attribute (or `aspectj-weaving` if you use XML). This
|
||||
attribute controls whether LTW is enabled or not.
|
||||
It accepts one of three possible values, with the default value being
|
||||
There is one final attribute of the configuration left to discuss: the `aspectjWeaving`
|
||||
attribute (or `aspectj-weaving` if you use XML). This attribute controls whether LTW
|
||||
is enabled or not. It accepts one of three possible values, with the default value being
|
||||
`autodetect` if the attribute is not present. The following table summarizes the three
|
||||
possible values:
|
||||
|
||||
@@ -3460,69 +3439,17 @@ This last section contains any additional settings and configuration that you ne
|
||||
when you use Spring's LTW support in environments such as application servers and web
|
||||
containers.
|
||||
|
||||
[[aop-aj-ltw-environment-tomcat]]
|
||||
===== Tomcat
|
||||
[[aop-aj-ltw-environments-tomcat-jboss-etc]]
|
||||
===== Tomcat, JBoss, WebSphere, WebLogic
|
||||
|
||||
Historically, http://tomcat.apache.org/[Apache Tomcat]'s default class loader did not
|
||||
support class transformation, which is why Spring provides an enhanced implementation
|
||||
that addresses this need. Named `TomcatInstrumentableClassLoader`, the loader works on
|
||||
Tomcat 6.0 and above.
|
||||
Tomcat, JBoss/WildFly, IBM WebSphere Application Server and Oracle WebLogic Server all
|
||||
provide a general app `ClassLoader` that is capable of local instrumentation. Spring's
|
||||
native LTW may leverage those ClassLoader implementations to provide AspectJ weaving.
|
||||
You can simply enable load-time weaving, as <<aop-using-aspectj, described earlier>>.
|
||||
Specifically, you do not need to modify the JVM launch script to add
|
||||
`-javaagent:path/to/spring-instrument.jar`.
|
||||
|
||||
TIP: Do not define `TomcatInstrumentableClassLoader` on Tomcat 8.0 and higher.
|
||||
Instead, let Spring automatically use Tomcat's new native `InstrumentableClassLoader`
|
||||
facility through the `TomcatLoadTimeWeaver` strategy.
|
||||
|
||||
If you still need to use `TomcatInstrumentableClassLoader`, you can register it
|
||||
individually for each web application as follows:
|
||||
|
||||
. Copy `org.springframework.instrument.tomcat.jar` into `$CATALINA_HOME/lib`, where
|
||||
`$CATALINA_HOME` represents the root of the Tomcat installation
|
||||
. Instruct Tomcat to use the custom class loader (instead of the default) by editing the
|
||||
web application context file, as the following example shows:
|
||||
|
||||
[source,xml,indent=0]
|
||||
[subs="verbatim,quotes"]
|
||||
----
|
||||
<Context path="/myWebApp" docBase="/my/webApp/location">
|
||||
<Loader
|
||||
loaderClass="org.springframework.instrument.classloading.tomcat.TomcatInstrumentableClassLoader"/>
|
||||
</Context>
|
||||
----
|
||||
|
||||
Apache Tomcat 6.0+ supports several context locations:
|
||||
|
||||
* Server configuration file: `$CATALINA_HOME/conf/server.xml`
|
||||
* Default context configuration: `$CATALINA_HOME/conf/context.xml`, which affects all
|
||||
deployed web applications
|
||||
* A per-web application configuration, which can be deployed either on the server-side at
|
||||
`$CATALINA_HOME/conf/[enginename]/[hostname]/[webapp]-context.xml` or embedded
|
||||
inside the web-app archive at `META-INF/context.xml`
|
||||
|
||||
For efficiency, we recommend the embedded per-web application configuration style, because it
|
||||
impacts only applications that use the custom class loader and does not require any
|
||||
changes to the server configuration. See the Tomcat 6.0.x
|
||||
http://tomcat.apache.org/tomcat-6.0-doc/config/context.html[documentation] for more
|
||||
details about available context locations.
|
||||
|
||||
Alternatively, consider using the Spring-provided generic VM agent, to be specified
|
||||
in Tomcat's launch script (described earlier in this section). This makes instrumentation available to all
|
||||
deployed web applications, no matter the `ClassLoader` on which they happen to run.
|
||||
|
||||
[[aop-aj-ltw-environments-weblogic-oc4j-resin-glassfish-jboss]]
|
||||
===== WebLogic, WebSphere, Resin, GlassFish, and JBoss
|
||||
|
||||
Recent versions of WebLogic Server (version 10 and above), IBM WebSphere Application
|
||||
Server (version 7 and above), Resin (version 3.1 and above), and JBoss (version 6.x or above) provide a
|
||||
`ClassLoader` that is capable of local instrumentation. Spring's native LTW leverages such
|
||||
ClassLoader implementations to enable AspectJ weaving. You can enable LTW by activating
|
||||
load-time weaving, as <<aop-using-aspectj,described earlier>>. Specifically, you do not need to modify the
|
||||
launch script to add `-javaagent:path/to/spring-instrument.jar`.
|
||||
|
||||
Note that the GlassFish instrumentation-capable `ClassLoader` is available only in its EAR
|
||||
environment. For GlassFish web applications, follow the Tomcat setup instructions
|
||||
<<aop-aj-ltw-environment-tomcat,outlined earlier>>.
|
||||
|
||||
Note that, on JBoss 6.x, you need to disable the app server scanning to prevent it from
|
||||
Note that on JBoss, you may need to disable the app server scanning to prevent it from
|
||||
loading the classes before the application actually starts. A quick workaround is to add
|
||||
to your artifact a file named `WEB-INF/jboss-scanning.xml` with the following content:
|
||||
|
||||
@@ -3532,31 +3459,28 @@ to your artifact a file named `WEB-INF/jboss-scanning.xml` with the following co
|
||||
<scanning xmlns="urn:jboss:scanning:1.0"/>
|
||||
----
|
||||
|
||||
[[aop-aj-ltw-environment-generic]]
|
||||
[[aop-aj-ltw-environments-generic]]
|
||||
===== Generic Java Applications
|
||||
|
||||
When class instrumentation is required in environments that do not support or are not
|
||||
supported by the existing `LoadTimeWeaver` implementations, a JDK agent can be the only
|
||||
solution. For such cases, Spring provides `InstrumentationLoadTimeWeaver`, which
|
||||
requires a Spring-specific (but very general) VM agent,
|
||||
`org.springframework.instrument-{version}.jar` (previously named `spring-agent.jar`).
|
||||
When class instrumentation is required in environments that are not supported by
|
||||
specific `LoadTimeWeaver` implementations, a JVM agent is the general solution.
|
||||
For such cases, Spring provides `InstrumentationLoadTimeWeaver` which requires a
|
||||
Spring-specific (but very general) JVM agent, `spring-instrument.jar`, autodetected
|
||||
by common `@EnableLoadTimeWeaving` and `<context:load-time-weaver/>` setups.
|
||||
|
||||
To use it, you must start the virtual machine with the Spring agent by supplying the
|
||||
following JVM options:
|
||||
To use it, you must start the virtual machine with the Spring agent by supplying
|
||||
the following JVM options:
|
||||
|
||||
[literal]
|
||||
[subs="verbatim,quotes"]
|
||||
----
|
||||
-javaagent:/path/to/org.springframework.instrument-{version}.jar
|
||||
-javaagent:/path/to/spring-instrument.jar
|
||||
----
|
||||
|
||||
Note that this requires modification of the VM launch script, which may prevent you from
|
||||
using this in application server environments (depending on your operation policies).
|
||||
Additionally, the JDK agent instruments the entire VM, which can be expensive.
|
||||
|
||||
For performance reasons, we recommend that you use this configuration only if your target
|
||||
environment (such as http://www.eclipse.org/jetty/[Jetty]) does not have (or does not
|
||||
support) a dedicated LTW.
|
||||
Note that this requires modification of the JVM launch script, which may prevent you
|
||||
from using this in application server environments (depending on your server and your
|
||||
operation policies). That said, for one-app-per-JVM deployments such as standalone
|
||||
Spring Boot applications, you typically control the entire JVM setup in any case.
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
|
||||
|
||||
|
||||
|
||||
[[xsd-schemas]]
|
||||
== XML Schemas
|
||||
|
||||
@@ -36,7 +37,6 @@ correct schema so that the tags in the `util` namespace are available to you):
|
||||
----
|
||||
|
||||
|
||||
|
||||
[[xsd-schemas-util-constant]]
|
||||
==== Using `<util:constant/>`
|
||||
|
||||
@@ -72,8 +72,6 @@ developer's intent ("`inject this constant value`"), and it reads better:
|
||||
</bean>
|
||||
----
|
||||
|
||||
|
||||
|
||||
[[xsd-schemas-util-frfb]]
|
||||
===== Setting a Bean Property or Constructor Argument from a Field Value
|
||||
|
||||
@@ -127,10 +125,9 @@ described in the API documentation for the
|
||||
class.
|
||||
|
||||
Injecting enumeration values into beans as either property or constructor arguments is
|
||||
easy to do in Spring. You do not actually have to do anything or know
|
||||
anything about the Spring internals (or even about classes such as the
|
||||
`FieldRetrievingFactoryBean`). The following example enumeration shows how easy injecting an
|
||||
enum value is:
|
||||
easy to do in Spring. You do not actually have to do anything or know anything about
|
||||
the Spring internals (or even about classes such as the `FieldRetrievingFactoryBean`).
|
||||
The following example enumeration shows how easy injecting an enum value is:
|
||||
|
||||
[source,java,indent=0]
|
||||
[subs="verbatim,quotes"]
|
||||
@@ -170,7 +167,6 @@ Now consider the following setter of type `PersistenceContextType` and the corre
|
||||
----
|
||||
|
||||
|
||||
|
||||
[[xsd-schemas-util-property-path]]
|
||||
==== Using `<util:property-path/>`
|
||||
|
||||
@@ -327,7 +323,6 @@ The following example uses a `util:properties` element to make a more concise re
|
||||
----
|
||||
|
||||
|
||||
|
||||
[[xsd-schemas-util-list]]
|
||||
==== Using `<util:list/>`
|
||||
|
||||
@@ -386,7 +381,6 @@ following configuration:
|
||||
If no `list-class` attribute is supplied, the container chooses a `List` implementation.
|
||||
|
||||
|
||||
|
||||
[[xsd-schemas-util-map]]
|
||||
==== Using `<util:map/>`
|
||||
|
||||
@@ -445,7 +439,6 @@ following configuration:
|
||||
If no `'map-class'` attribute is supplied, the container chooses a `Map` implementation.
|
||||
|
||||
|
||||
|
||||
[[xsd-schemas-util-set]]
|
||||
==== Using `<util:set/>`
|
||||
|
||||
@@ -558,69 +551,64 @@ available to you:
|
||||
----
|
||||
|
||||
|
||||
|
||||
[[xsd-schemas-context-pphc]]
|
||||
==== Using `<property-placeholder/>`
|
||||
|
||||
This element activates the replacement of `${...}` placeholders, which are resolved against a
|
||||
specified properties file (as a <<core.adoc#resources,Spring resource location>>). This element
|
||||
is a convenience mechanism that sets up a <<core.adoc#beans-factory-placeholderconfigurer,
|
||||
`PropertySourcesPlaceholderConfigurer`>> for you. If you need more control over the
|
||||
`PropertySourcesPlaceholderConfigurer`, you can explicitly define one yourself.
|
||||
|
||||
specified properties file (as a <<core.adoc#resources, Spring resource location>>). This element is
|
||||
a convenience mechanism that sets up a <<core.adoc#beans-factory-placeholderconfigurer,
|
||||
`PropertyPlaceholderConfigurer`>> for you. If you need more control over the
|
||||
`PropertyPlaceholderConfigurer`, you can explicitly define one yourself.
|
||||
|
||||
|
||||
[[xsd-schemas-context-ac]]
|
||||
==== Using `<annotation-config/>`
|
||||
|
||||
This element activates the Spring infrastructure to detect annotations in bean
|
||||
classes:
|
||||
This element activates the Spring infrastructure to detect annotations in bean classes:
|
||||
|
||||
* Spring's <<core.adoc#beans-required-annotation, `@Required`>> and
|
||||
<<core.adoc#beans-annotation-config, `@Autowired`>>
|
||||
* JSR 250's `@PostConstruct`,
|
||||
`@PreDestroy` and `@Resource` (if available)
|
||||
* JPA's `@PersistenceContext` and
|
||||
`@PersistenceUnit` (if available).
|
||||
* Spring's <<core.adoc#beans-factory-metadata, `@Configuration`>> model
|
||||
* <<core.adoc#beans-annotation-config, `@Autowired`/`@Inject`>> and `@Value`
|
||||
* JSR-250's `@Resource`, `@PostConstruct` and `@PreDestroy` (if available)
|
||||
* JPA's `@PersistenceContext` and `@PersistenceUnit` (if available)
|
||||
* Spring's <<core.adoc#context-functionality-events-annotation, `@EventListener`>>
|
||||
|
||||
Alternatively, you can choose to explicitly activate the
|
||||
individual `BeanPostProcessors` for those annotations.
|
||||
Alternatively, you can choose to explicitly activate the individual `BeanPostProcessors`
|
||||
for those annotations.
|
||||
|
||||
NOTE: This element does not activate processing of Spring's
|
||||
<<data-access.adoc#transaction-declarative-annotations, `@Transactional`>> annotation. You can use the
|
||||
<<data-access.adoc#tx-decl-explained, `<tx:annotation-driven/>`>> element for that purpose.
|
||||
|
||||
<<data-access.adoc#transaction-declarative-annotations, `@Transactional`>> annotation;
|
||||
you can use the <<data-access.adoc#tx-decl-explained, `<tx:annotation-driven/>`>>
|
||||
element for that purpose. Similarly, Spring's
|
||||
<<integration.adoc#cache-annotations, caching annotations>> need to be explicitly
|
||||
<<integration.adoc#cache-annotation-enable, enabled>> as well.
|
||||
|
||||
|
||||
[[xsd-schemas-context-component-scan]]
|
||||
==== Using `<component-scan/>`
|
||||
|
||||
This element is detailed in <<core.adoc#beans-annotation-config,
|
||||
Annotation-based container configuration>>.
|
||||
|
||||
This element is detailed in the section on <<core.adoc#beans-annotation-config,
|
||||
annotation-based container configuration>>.
|
||||
|
||||
|
||||
[[xsd-schemas-context-ltw]]
|
||||
==== Using `<load-time-weaver/>`
|
||||
|
||||
This element is detailed in <<core.adoc#aop-aj-ltw,
|
||||
Load-time weaving with AspectJ in the Spring Framework>>.
|
||||
|
||||
This element is detailed in the section on <<core.adoc#aop-aj-ltw,
|
||||
load-time weaving with AspectJ in the Spring Framework>>.
|
||||
|
||||
|
||||
[[xsd-schemas-context-sc]]
|
||||
==== Using `<spring-configured/>`
|
||||
|
||||
This element is detailed in <<core.adoc#aop-atconfigurable,
|
||||
Using AspectJ to dependency inject domain objects with Spring>>.
|
||||
|
||||
This element is detailed in the section on <<core.adoc#aop-atconfigurable,
|
||||
using AspectJ to dependency inject domain objects with Spring>>.
|
||||
|
||||
|
||||
[[xsd-schemas-context-mbe]]
|
||||
==== Using `<mbean-export/>`
|
||||
|
||||
This element is detailed in <<integration.adoc#jmx-context-mbeanexport,
|
||||
Configuring annotation based MBean export>>.
|
||||
This element is detailed in the section on <<integration.adoc#jmx-context-mbeanexport,
|
||||
configuring annotation-based MBean export>>.
|
||||
|
||||
|
||||
|
||||
@@ -630,8 +618,8 @@ Configuring annotation based MBean export>>.
|
||||
Last but not least, we have the elements in the `beans` schema. These elements
|
||||
have been in Spring since the very dawn of the framework. Examples of the various elements
|
||||
in the `beans` schema are not shown here because they are quite comprehensively covered
|
||||
in <<core.adoc#beans-factory-properties-detailed,Dependencies and configuration in detail>>
|
||||
(and, indeed, in that entire <<core.adoc#beans,chapter>>).
|
||||
in <<core.adoc#beans-factory-properties-detailed, dependencies and configuration in detail>>
|
||||
(and, indeed, in that entire <<core.adoc#beans, chapter>>).
|
||||
|
||||
Note that you can add zero or more key-value pairs to `<bean/>` XML definitions.
|
||||
What, if anything, is done with this extra metadata is totally up to your own custom
|
||||
@@ -660,10 +648,9 @@ as it stands).
|
||||
----
|
||||
<1> This is the example `meta` element
|
||||
|
||||
In the case of the preceding example, you could assume that there is some logic that consumes
|
||||
the bean definition and sets up some caching infrastructure that uses the supplied metadata.
|
||||
|
||||
In the case of the preceding example, you could assume that there is some logic that
|
||||
consumes the bean definition and sets up some caching infrastructure that uses the supplied
|
||||
metadata.
|
||||
|
||||
|
||||
|
||||
@@ -683,11 +670,11 @@ Spring distribution, you should first read the appendix entitled <<xsd-config>>.
|
||||
|
||||
To create new XML configuration extensions:
|
||||
|
||||
. <<xsd-custom-schema,Author>> an XML schema to describe your custom element(s).
|
||||
. <<xsd-custom-namespacehandler,Code>> a custom `NamespaceHandler` implementation.
|
||||
. <<xsd-custom-parser,Code>> one or more `BeanDefinitionParser` implementations
|
||||
. <<xsd-custom-schema, Author>> an XML schema to describe your custom element(s).
|
||||
. <<xsd-custom-namespacehandler, Code>> a custom `NamespaceHandler` implementation.
|
||||
. <<xsd-custom-parser, Code>> one or more `BeanDefinitionParser` implementations
|
||||
(this is where the real work is done).
|
||||
. <<xsd-custom-registration,Register>> your new artifacts with Spring.
|
||||
. <<xsd-custom-registration, Register>> your new artifacts with Spring.
|
||||
|
||||
For a unified example, we create an
|
||||
XML extension (a custom XML element) that lets us configure objects of the type
|
||||
@@ -801,7 +788,7 @@ The `NamespaceHandler` interface features three methods:
|
||||
* `BeanDefinitionHolder decorate(Node, BeanDefinitionHolder, ParserContext)`: Called
|
||||
when Spring encounters an attribute or nested element of a different namespace.
|
||||
The decoration of one or more bean definitions is used (for example) with the
|
||||
<<core.adoc#beans-factory-scopes,scopes that Spring supports>>.
|
||||
<<core.adoc#beans-factory-scopes, scopes that Spring supports>>.
|
||||
We start by highlighting a simple example, without using decoration, after which
|
||||
we show decoration in a somewhat more advanced example.
|
||||
|
||||
@@ -889,7 +876,6 @@ the basic grunt work of creating a single `BeanDefinition`.
|
||||
<2> We supply the `AbstractSingleBeanDefinitionParser` superclass with the type that our
|
||||
single `BeanDefinition` represents.
|
||||
|
||||
|
||||
In this simple case, this is all that we need to do. The creation of our single
|
||||
`BeanDefinition` is handled by the `AbstractSingleBeanDefinitionParser` superclass, as
|
||||
is the extraction and setting of the bean definition's unique identifier.
|
||||
@@ -898,6 +884,7 @@ is the extraction and setting of the bean definition's unique identifier.
|
||||
|
||||
[[xsd-custom-registration]]
|
||||
=== Registering the Handler and the Schema
|
||||
|
||||
The coding is finished. All that remains to be done is to make the Spring XML
|
||||
parsing infrastructure aware of our custom element. We do so by registering our custom
|
||||
`namespaceHandler` and custom XSD file in two special-purpose properties files. These
|
||||
@@ -907,7 +894,6 @@ XML parsing infrastructure automatically picks up your new extension by consumin
|
||||
these special properties files, the formats of which are detailed in the next two sections.
|
||||
|
||||
|
||||
|
||||
[[xsd-custom-registration-spring-handlers]]
|
||||
==== Writing `META-INF/spring.handlers`
|
||||
|
||||
@@ -928,7 +914,6 @@ namespace extension and needs to exactly match exactly the value of the `targetN
|
||||
attribute, as specified in your custom XSD schema.
|
||||
|
||||
|
||||
|
||||
[[xsd-custom-registration-spring-schemas]]
|
||||
==== Writing 'META-INF/spring.schemas'
|
||||
|
||||
@@ -995,7 +980,6 @@ in a Spring XML configuration file:
|
||||
This section presents some more detailed examples of custom XML extensions.
|
||||
|
||||
|
||||
|
||||
[[xsd-custom-custom-nested]]
|
||||
==== Nesting Custom Elements within Custom Elements
|
||||
|
||||
@@ -1060,7 +1044,6 @@ The following listing shows the `Component` class:
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
}
|
||||
----
|
||||
|
||||
@@ -1068,7 +1051,6 @@ The typical solution to this issue is to create a custom `FactoryBean` that expo
|
||||
setter property for the `components` property. The following listing shows such a custom
|
||||
`FactoryBean`:
|
||||
|
||||
|
||||
[source,java,indent=0]
|
||||
[subs="verbatim,quotes"]
|
||||
----
|
||||
@@ -1107,15 +1089,14 @@ setter property for the `components` property. The following listing shows such
|
||||
public boolean isSingleton() {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
----
|
||||
|
||||
This works nicely, but it exposes a lot of Spring plumbing to the
|
||||
end user. What we are going to do is write a custom extension that hides away all of
|
||||
this Spring plumbing. If we stick to <<xsd-custom-introduction,the steps described
|
||||
previously>>, we start off by creating the XSD schema to define the structure of our
|
||||
custom tag, as the following listing shows:
|
||||
This works nicely, but it exposes a lot of Spring plumbing to the end user. What we are
|
||||
going to do is write a custom extension that hides away all of this Spring plumbing.
|
||||
If we stick to <<xsd-custom-introduction, the steps described previously>>, we start off
|
||||
by creating the XSD schema to define the structure of our custom tag, as the following
|
||||
listing shows:
|
||||
|
||||
[source,xml,indent=0]
|
||||
[subs="verbatim,quotes"]
|
||||
@@ -1141,7 +1122,8 @@ custom tag, as the following listing shows:
|
||||
</xsd:schema>
|
||||
----
|
||||
|
||||
Again following <<xsd-custom-introduction,the process described earlier>>, we then create a custom `NamespaceHandler`:
|
||||
Again following <<xsd-custom-introduction, the process described earlier>>,
|
||||
we then create a custom `NamespaceHandler`:
|
||||
|
||||
[source,java,indent=0]
|
||||
[subs="verbatim,quotes"]
|
||||
@@ -1155,13 +1137,12 @@ Again following <<xsd-custom-introduction,the process described earlier>>, we th
|
||||
public void init() {
|
||||
registerBeanDefinitionParser("component", new ComponentBeanDefinitionParser());
|
||||
}
|
||||
|
||||
}
|
||||
----
|
||||
|
||||
Next up is the custom `BeanDefinitionParser`. Remember that we are creating
|
||||
`BeanDefinition` that describes a `ComponentFactoryBean`. The following listing shows our
|
||||
custom `BeanDefinitionParser`:
|
||||
a `BeanDefinition` that describes a `ComponentFactoryBean`. The following
|
||||
listing shows our custom `BeanDefinitionParser` implementation:
|
||||
|
||||
[source,java,indent=0]
|
||||
[subs="verbatim,quotes"]
|
||||
@@ -1210,7 +1191,6 @@ custom `BeanDefinitionParser`:
|
||||
}
|
||||
factory.addPropertyValue("children", children);
|
||||
}
|
||||
|
||||
}
|
||||
----
|
||||
|
||||
@@ -1232,21 +1212,20 @@ http\://www.foo.com/schema/component/component.xsd=com/foo/component.xsd
|
||||
----
|
||||
|
||||
|
||||
|
||||
[[xsd-custom-custom-just-attributes]]
|
||||
==== Custom Attributes on "`Normal`" Elements
|
||||
|
||||
Writing your own custom parser and the associated artifacts is not hard. However, it is sometimes
|
||||
not the right thing to do. Consider a scenario where you need to add metadata to
|
||||
already existing bean definitions. In this case, you certainly do not want to have to
|
||||
write your own entire custom extension. Rather, you merely want to add an
|
||||
additional attribute to the existing bean definition element.
|
||||
Writing your own custom parser and the associated artifacts is not hard. However,
|
||||
it is sometimes not the right thing to do. Consider a scenario where you need to
|
||||
add metadata to already existing bean definitions. In this case, you certainly
|
||||
do not want to have to write your own entire custom extension. Rather, you merely
|
||||
want to add an additional attribute to the existing bean definition element.
|
||||
|
||||
By way of another example, suppose that you define a bean
|
||||
definition for a service object that (unknown to it) accesses a clustered
|
||||
http://jcp.org/en/jsr/detail?id=107[JCache], and you want to ensure that the named
|
||||
JCache instance is eagerly started within the surrounding cluster. The following
|
||||
listing shows such a definition:
|
||||
By way of another example, suppose that you define a bean definition for a
|
||||
service object that (unknown to it) accesses a clustered
|
||||
http://jcp.org/en/jsr/detail?id=107[JCache], and you want to ensure that the
|
||||
named JCache instance is eagerly started within the surrounding cluster.
|
||||
The following listing shows such a definition:
|
||||
|
||||
[source,xml,indent=0]
|
||||
[subs="verbatim,quotes"]
|
||||
@@ -1279,12 +1258,11 @@ JCache-initializing `BeanDefinition`. The following listing shows our `JCacheIni
|
||||
public void initialize() {
|
||||
// lots of JCache API calls to initialize the named cache...
|
||||
}
|
||||
|
||||
}
|
||||
----
|
||||
|
||||
Now we can move onto the custom extension. First, we need to author the XSD schema that describes the
|
||||
custom attribute, as follows:
|
||||
Now we can move onto the custom extension. First, we need to author
|
||||
the XSD schema that describes the custom attribute, as follows:
|
||||
|
||||
[source,xml,indent=0]
|
||||
[subs="verbatim,quotes"]
|
||||
@@ -1320,9 +1298,9 @@ Next, we need to create the associated `NamespaceHandler`, as follows:
|
||||
}
|
||||
----
|
||||
|
||||
Next, we need to create the parser. Note that, in this case, because we are going to parse an XML
|
||||
attribute, we write a `BeanDefinitionDecorator` rather than a `BeanDefinitionParser`.
|
||||
The following listing shows our `BeanDefinitionDecorator`:
|
||||
Next, we need to create the parser. Note that, in this case, because we are going to parse
|
||||
an XML attribute, we write a `BeanDefinitionDecorator` rather than a `BeanDefinitionParser`.
|
||||
The following listing shows our `BeanDefinitionDecorator` implementation:
|
||||
|
||||
[source,java,indent=0]
|
||||
[subs="verbatim,quotes"]
|
||||
@@ -1376,7 +1354,6 @@ The following listing shows our `BeanDefinitionDecorator`:
|
||||
}
|
||||
return beanName;
|
||||
}
|
||||
|
||||
}
|
||||
----
|
||||
|
||||
|
||||
@@ -104,13 +104,13 @@ Spring IoC container.
|
||||
NOTE: XML-based metadata is not the only allowed form of configuration metadata.
|
||||
The Spring IoC container itself is totally decoupled from the format in which this
|
||||
configuration metadata is actually written. These days, many developers choose
|
||||
<<beans-java,Java-based configuration>> for their Spring applications.
|
||||
<<beans-java, Java-based configuration>> for their Spring applications.
|
||||
|
||||
For information about using other forms of metadata with the Spring container, see:
|
||||
|
||||
* <<beans-annotation-config,Annotation-based configuration>>: Spring 2.5 introduced
|
||||
support for annotation-based configuration metadata.
|
||||
* <<beans-java,Java-based configuration>>: Starting with Spring 3.0, many features
|
||||
* <<beans-java, Java-based configuration>>: Starting with Spring 3.0, many features
|
||||
provided by the Spring JavaConfig project became part of the core Spring Framework.
|
||||
Thus, you can define beans external to your application classes by using Java rather
|
||||
than XML files. To use these new features, see the
|
||||
@@ -257,7 +257,7 @@ XML configuration file represents a logical layer or module in your architecture
|
||||
|
||||
You can use the application context constructor to load bean definitions from all these
|
||||
XML fragments. This constructor takes multiple `Resource` locations, as was shown in the
|
||||
<<beans-factory-instantiation,previous section>>. Alternatively, use one or more
|
||||
<<beans-factory-instantiation, previous section>>. Alternatively, use one or more
|
||||
occurrences of the `<import/>` element to load bean definitions from another file or
|
||||
files. The following example shows how to do so:
|
||||
|
||||
@@ -974,8 +974,8 @@ example shows:
|
||||
|
||||
Keep in mind that, to make this work out of the box, your code must be compiled with the
|
||||
debug flag enabled so that Spring can look up the parameter name from the constructor.
|
||||
If you cannot or do not want to compile your code with the debug flag, you can use
|
||||
http://download.oracle.com/javase/6/docs/api/java/beans/ConstructorProperties.html[@ConstructorProperties]
|
||||
If you cannot or do not want to compile your code with the debug flag, you can use the
|
||||
http://download.oracle.com/javase/8/docs/api/java/beans/ConstructorProperties.html[@ConstructorProperties]
|
||||
JDK annotation to explicitly name your constructor arguments. The sample class would
|
||||
then have to look as follows:
|
||||
|
||||
@@ -1042,7 +1042,7 @@ load an entire Spring IoC container instance.
|
||||
****
|
||||
Since you can mix constructor-based and setter-based DI, it is a good rule of thumb to
|
||||
use constructors for mandatory dependencies and setter methods or configuration methods
|
||||
for optional dependencies. Note that use of the <<beans-required-annotation,@Required>>
|
||||
for optional dependencies. Note that use of the <<beans-required-annotation, @Required>>
|
||||
annotation on a setter method can be used to make the property be a required dependency;
|
||||
however, constructor injection with programmatic validation of arguments is preferable.
|
||||
|
||||
@@ -1135,7 +1135,7 @@ to being injected into the dependent bean. This means that, if bean A has a depe
|
||||
bean B, the Spring IoC container completely configures bean B prior to invoking the
|
||||
setter method on bean A. In other words, the bean is instantiated (if it is not a
|
||||
pre-instantiated singleton), its dependencies are set, and the relevant lifecycle
|
||||
methods (such as a <<beans-factory-lifecycle-initializingbean,configured init method>>
|
||||
methods (such as a <<beans-factory-lifecycle-initializingbean, configured init method>>
|
||||
or the <<beans-factory-lifecycle-initializingbean,InitializingBean callback method>>)
|
||||
are invoked.
|
||||
|
||||
@@ -1292,7 +1292,7 @@ do not discuss those details here.
|
||||
[[beans-factory-properties-detailed]]
|
||||
=== Dependencies and Configuration in Detail
|
||||
|
||||
As mentioned in the <<beans-factory-collaborators,previous section>>, you can define bean
|
||||
As mentioned in the <<beans-factory-collaborators, previous section>>, you can define bean
|
||||
properties and constructor arguments as references to other managed beans (collaborators)
|
||||
or as values defined inline. Spring's XML-based configuration metadata supports
|
||||
sub-element types within its `<property/>` and `<constructor-arg/>` elements for this
|
||||
@@ -2077,11 +2077,11 @@ In the latter scenario, you have several options:
|
||||
|
||||
* Abandon autowiring in favor of explicit wiring.
|
||||
* Avoid autowiring for a bean definition by setting its `autowire-candidate` attributes
|
||||
to `false`, as described in the <<beans-factory-autowire-candidate,next section>>.
|
||||
to `false`, as described in the <<beans-factory-autowire-candidate, next section>>.
|
||||
* Designate a single bean definition as the primary candidate by setting the
|
||||
`primary` attribute of its `<bean/>` element to `true`.
|
||||
* Implement the more fine-grained control available
|
||||
with annotation-based configuration, as described in <<beans-annotation-config>>.
|
||||
* Implement the more fine-grained control available with annotation-based configuration,
|
||||
as described in <<beans-annotation-config>>.
|
||||
|
||||
|
||||
|
||||
@@ -2184,7 +2184,7 @@ https://spring.io/blog/2004/08/06/method-injection/[this blog entry].
|
||||
Lookup method injection is the ability of the container to override methods on
|
||||
container-managed beans and return the lookup result for another named bean in the
|
||||
container. The lookup typically involves a prototype bean, as in the scenario described
|
||||
in <<beans-factory-method-injection,the preceding section>>. The Spring Framework
|
||||
in <<beans-factory-method-injection, the preceding section>>. The Spring Framework
|
||||
implements this method injection by using bytecode generation from the CGLIB library to
|
||||
dynamically generate a subclass that overrides the method.
|
||||
|
||||
@@ -3326,7 +3326,7 @@ configured with a different method name, then each configured method is executed
|
||||
order listed after this note. However, if the same method name is configured -- for example,
|
||||
`init()` for an initialization method -- for more than one of these lifecycle mechanisms,
|
||||
that method is executed once, as explained in the
|
||||
<<beans-factory-lifecycle-default-init-destroy-methods,preceding section>>.
|
||||
<<beans-factory-lifecycle-default-init-destroy-methods, preceding section>>.
|
||||
|
||||
Multiple lifecycle mechanisms configured for the same bean, with different
|
||||
initialization methods, are called as follows:
|
||||
@@ -3575,7 +3575,7 @@ init-method.
|
||||
[[aware-list]]
|
||||
=== Other `Aware` Interfaces
|
||||
|
||||
Besides `ApplicationContextAware` and `BeanNameAware` (discussed <<beans-factory-aware,earlier>>),
|
||||
Besides `ApplicationContextAware` and `BeanNameAware` (discussed <<beans-factory-aware, earlier>>),
|
||||
Spring offers a wide range of `Aware` callback interfaces that let beans indicate to the container
|
||||
that they require a certain infrastructure dependency. As a general rule, the name indicates the
|
||||
dependency type. The following table summarizes the most important `Aware` interfaces:
|
||||
@@ -3680,7 +3680,6 @@ to do so:
|
||||
----
|
||||
<1> Note the `parent` attribute.
|
||||
|
||||
|
||||
A child bean definition uses the bean class from the parent definition if none is
|
||||
specified but can also override it. In the latter case, the child bean class must be
|
||||
compatible with the parent (that is, it must accept the parent's property values).
|
||||
@@ -4207,7 +4206,7 @@ while others argue that annotated classes are no longer POJOs and, furthermore,
|
||||
configuration becomes decentralized and harder to control.
|
||||
|
||||
No matter the choice, Spring can accommodate both styles and even mix them together.
|
||||
It is worth pointing out that through its <<beans-java,JavaConfig>> option, Spring lets
|
||||
It is worth pointing out that through its <<beans-java, JavaConfig>> option, Spring lets
|
||||
annotations be used in a non-invasive way, without touching the target components
|
||||
source code and that, in terms of tooling, all configuration styles are supported by the
|
||||
https://spring.io/tools/sts[Spring Tool Suite].
|
||||
@@ -4588,7 +4587,7 @@ an `ApplicationContext` object:
|
||||
|
||||
[NOTE]
|
||||
====
|
||||
The `@Autowired`, `@Inject`, `@Resource`, and `@Value` annotations are handled by Spring
|
||||
The `@Autowired`, `@Inject`, `@Value`, and `@Resource` annotations are handled by Spring
|
||||
`BeanPostProcessor` implementations. This means that you cannot apply these annotations
|
||||
within your own `BeanPostProcessor` or `BeanFactoryPostProcessor` types (if any).
|
||||
These types must be 'wired up' explicitly by using XML or a Spring `@Bean` method.
|
||||
@@ -5327,9 +5326,9 @@ supported as a marker for automatic exception translation in your persistence la
|
||||
=== Using Meta-annotations and Composed Annotations
|
||||
|
||||
Many of the annotations provided by Spring can be used as meta-annotations in your
|
||||
own code. A meta-annotation is an annotation that can be applied to another
|
||||
annotation. For example, the `@Service` annotation mentioned <<beans-stereotype-annotations,earlier>> is meta-annotated with
|
||||
`@Component`, as the following example shows:
|
||||
own code. A meta-annotation is an annotation that can be applied to another annotation.
|
||||
For example, the `@Service` annotation mentioned <<beans-stereotype-annotations, earlier>>
|
||||
is meta-annotated with `@Component`, as the following example shows:
|
||||
|
||||
[source,java,indent=0]
|
||||
[subs="verbatim,quotes"]
|
||||
@@ -5482,16 +5481,16 @@ TIP: The use of `<context:component-scan>` implicitly enables the functionality
|
||||
====
|
||||
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
|
||||
activate the files-only switch of the JAR task. Also, classpath directories may not
|
||||
be exposed based on security policies in some environments -- for example, standalone apps on
|
||||
activate the files-only switch of the JAR task. Also, classpath directories may not be
|
||||
exposed based on security policies in some environments -- for example, standalone apps on
|
||||
JDK 1.7.0_45 and higher (which requires 'Trusted-Library' setup 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.
|
||||
However, make sure that your component classes are exported in your `module-info`
|
||||
descriptors. If you expect Spring to invoke non-public members of your classes, make
|
||||
sure that they are 'opened' (that is, that they use an `opens` declaration instead of an `exports`
|
||||
declaration in your `module-info` descriptor).
|
||||
sure that they are 'opened' (that is, that they use an `opens` declaration instead of an
|
||||
`exports` declaration in your `module-info` descriptor).
|
||||
====
|
||||
|
||||
Furthermore, the `AutowiredAnnotationBeanPostProcessor` and
|
||||
@@ -6466,7 +6465,7 @@ following example shows:
|
||||
}
|
||||
----
|
||||
|
||||
NOTE: Remember that `@Configuration` classes are <<beans-meta-annotations,meta-annotated>>
|
||||
NOTE: Remember that `@Configuration` classes are <<beans-meta-annotations, meta-annotated>>
|
||||
with `@Component`, so they are candidates for component-scanning. In the preceding example,
|
||||
assuming that `AppConfig` is declared within the `com.acme` package (or any package
|
||||
underneath), it is picked up during the call to `scan()`. Upon `refresh()`, all its `@Bean`
|
||||
@@ -6544,8 +6543,8 @@ init-param):
|
||||
|
||||
`@Bean` is a method-level annotation and a direct analog of the XML `<bean/>` element.
|
||||
The annotation supports some of the attributes offered by `<bean/>`, such as:
|
||||
* <<beans-factory-lifecycle-initializingbean,init-method>>
|
||||
* <<beans-factory-lifecycle-disposablebean,destroy-method>>
|
||||
* <<beans-factory-lifecycle-initializingbean, init-method>>
|
||||
* <<beans-factory-lifecycle-disposablebean, destroy-method>>
|
||||
* <<beans-factory-autowire,autowiring>>
|
||||
* `name`.
|
||||
|
||||
@@ -6647,7 +6646,7 @@ parameter, as the following example shows:
|
||||
----
|
||||
|
||||
The resolution mechanism is pretty much identical to constructor-based dependency
|
||||
injection. See <<beans-constructor-injection,the relevant section>> for more details.
|
||||
injection. See <<beans-constructor-injection, the relevant section>> for more details.
|
||||
|
||||
|
||||
[[beans-java-lifecycle-callbacks]]
|
||||
@@ -6655,17 +6654,17 @@ injection. See <<beans-constructor-injection,the relevant section>> for more det
|
||||
|
||||
Any classes defined with the `@Bean` annotation support the regular lifecycle callbacks
|
||||
and can use the `@PostConstruct` and `@PreDestroy` annotations from JSR-250. See
|
||||
<<beans-postconstruct-and-predestroy-annotations,JSR-250 annotations>> for further
|
||||
<<beans-postconstruct-and-predestroy-annotations, JSR-250 annotations>> for further
|
||||
details.
|
||||
|
||||
The regular Spring <<beans-factory-nature,lifecycle>> callbacks are fully supported as
|
||||
The regular Spring <<beans-factory-nature, lifecycle>> callbacks are fully supported as
|
||||
well. If a bean implements `InitializingBean`, `DisposableBean`, or `Lifecycle`, their
|
||||
respective methods are called by the container.
|
||||
|
||||
The standard set of `*Aware` interfaces (such as <<beans-beanfactory,BeanFactoryAware>>,
|
||||
<<beans-factory-aware,BeanNameAware>>,
|
||||
<<context-functionality-messagesource,MessageSourceAware>>,
|
||||
<<beans-factory-aware,ApplicationContextAware>>, and so on) are also fully supported.
|
||||
The standard set of `*Aware` interfaces (such as <<beans-beanfactory, BeanFactoryAware>>,
|
||||
<<beans-factory-aware, BeanNameAware>>,
|
||||
<<context-functionality-messagesource, MessageSourceAware>>,
|
||||
<<beans-factory-aware, ApplicationContextAware>>, and so on) are also fully supported.
|
||||
|
||||
The `@Bean` annotation supports specifying arbitrary initialization and destruction
|
||||
callback methods, much like Spring XML's `init-method` and `destroy-method` attributes
|
||||
@@ -6769,7 +6768,7 @@ Spring includes the `@Scope` annotation so that you can specify the scope of a b
|
||||
|
||||
You can specify that your beans defined with the `@Bean` annotation should have a
|
||||
specific scope. You can use any of the standard scopes specified in the
|
||||
<<beans-factory-scopes,Bean Scopes>> section.
|
||||
<<beans-factory-scopes, Bean Scopes>> section.
|
||||
|
||||
The default scope is `singleton`, but you can override this with the `@Scope` annotation,
|
||||
as the following example shows:
|
||||
@@ -6792,14 +6791,15 @@ as the following example shows:
|
||||
===== `@Scope` and `scoped-proxy`
|
||||
|
||||
Spring offers a convenient way of working with scoped dependencies through
|
||||
<<beans-factory-scopes-other-injection,scoped proxies>>. The easiest way to create such
|
||||
a proxy when using the XML configuration is the `<aop:scoped-proxy/>` element.
|
||||
Configuring your beans in Java with a `@Scope` annotation offers equivalent support with
|
||||
the `proxyMode` attribute. The default is no proxy (`ScopedProxyMode.NO`), but you can
|
||||
specify `ScopedProxyMode.TARGET_CLASS` or `ScopedProxyMode.INTERFACES`.
|
||||
<<beans-factory-scopes-other-injection, scoped proxies>>. The easiest way to create
|
||||
such a proxy when using the XML configuration is the `<aop:scoped-proxy/>` element.
|
||||
Configuring your beans in Java with a `@Scope` annotation offers equivalent support
|
||||
with the `proxyMode` attribute. The default is no proxy (`ScopedProxyMode.NO`),
|
||||
but you can specify `ScopedProxyMode.TARGET_CLASS` or `ScopedProxyMode.INTERFACES`.
|
||||
|
||||
If you port the scoped proxy example from the XML reference documentation (see
|
||||
<<beans-factory-scopes-other-injection,scoped proxies>>) to our `@Bean` using Java, it resembles the following:
|
||||
<<beans-factory-scopes-other-injection, scoped proxies>>) to our `@Bean` using Java,
|
||||
it resembles the following:
|
||||
|
||||
[source,java,indent=0]
|
||||
[subs="verbatim,quotes"]
|
||||
@@ -6935,7 +6935,7 @@ by using plain `@Component` classes.
|
||||
[[beans-java-method-injection]]
|
||||
==== Lookup Method Injection
|
||||
|
||||
As noted earlier, <<beans-factory-method-injection,lookup method injection>> is an
|
||||
As noted earlier, <<beans-factory-method-injection, lookup method injection>> is an
|
||||
advanced feature that you should use rarely. It is useful in cases where a
|
||||
singleton-scoped bean has a dependency on a prototype-scoped bean. Using Java for this
|
||||
type of configuration provides a natural means for implementing this pattern. The
|
||||
@@ -7123,7 +7123,7 @@ issue, because no compiler is involved, and you can declare
|
||||
When using `@Configuration` classes, the Java compiler places constraints on
|
||||
the configuration model, in that references to other beans must be valid Java syntax.
|
||||
|
||||
Fortunately, solving this problem is simple. As <<beans-java-dependencies,we already discussed>>,
|
||||
Fortunately, solving this problem is simple. As <<beans-java-dependencies, we already discussed>>,
|
||||
a `@Bean` method can have an arbitrary number of parameters that describe the bean
|
||||
dependencies. Consider the following more real-world scenario with several `@Configuration`
|
||||
classes, each depending on beans declared in the others:
|
||||
@@ -7581,8 +7581,8 @@ jdbc.password=
|
||||
|
||||
The {api-spring-framework}/core/env/Environment.html[`Environment`] interface
|
||||
is an abstraction integrated in the container that models two key
|
||||
aspects of the application environment: <<beans-definition-profiles,profiles>>
|
||||
and <<beans-property-source-abstraction,properties>>.
|
||||
aspects of the application environment: <<beans-definition-profiles, profiles>>
|
||||
and <<beans-property-source-abstraction, properties>>.
|
||||
|
||||
A profile is a named, logical group of bean definitions to be registered with the
|
||||
container only if the given profile is active. Beans may be assigned to a profile
|
||||
@@ -7719,7 +7719,7 @@ NOTE: You cannot mix the `&` and `|` operators without using parentheses. For ex
|
||||
`production & us-east | eu-central` is not a valid expression. It must be expressed as
|
||||
`production & (us-east | eu-central)`.
|
||||
|
||||
You can use `@Profile` as a <<beans-meta-annotations,meta-annotation>> for the purpose
|
||||
You can use `@Profile` as a <<beans-meta-annotations, meta-annotation>> for the purpose
|
||||
of creating a custom composed annotation. The following example defines a custom
|
||||
`@Production` annotation that you can use as a drop-in replacement for
|
||||
`@Profile("production")`:
|
||||
@@ -7915,9 +7915,9 @@ In addition, you can also declaratively activate profiles through the
|
||||
`spring.profiles.active` property, which may be specified through system environment
|
||||
variables, JVM system properties, servlet context parameters in `web.xml`, or even as an
|
||||
entry in JNDI (see <<beans-property-source-abstraction>>). In integration tests, active
|
||||
profiles can be declared by using the `@ActiveProfiles` annotation in the `spring-test` module
|
||||
(see <<testing.adoc#testcontext-ctx-management-env-profiles,
|
||||
Context configuration with environment profiles>>).
|
||||
profiles can be declared by using the `@ActiveProfiles` annotation in the `spring-test`
|
||||
module (see <<testing.adoc#testcontext-ctx-management-env-profiles,
|
||||
context configuration with environment profiles>>).
|
||||
|
||||
Note that profiles are not an "`either-or`" proposition. You can activate multiple
|
||||
profiles at once. Programmatically, you can provide multiple profile names to the
|
||||
@@ -8169,9 +8169,10 @@ Alternatively, for XML configuration, you can use the `context:load-time-weaver`
|
||||
Once configured for the `ApplicationContext`, any bean within that `ApplicationContext`
|
||||
may implement `LoadTimeWeaverAware`, thereby receiving a reference to the load-time
|
||||
weaver instance. This is particularly useful in combination with
|
||||
<<data-access.adoc#orm-jpa,Spring's JPA support>> where load-time weaving may be necessary
|
||||
for JPA class transformation.
|
||||
Consult the {api-spring-framework}/orm/jpa/LocalContainerEntityManagerFactoryBean.html[`LocalContainerEntityManagerFactoryBean`]
|
||||
<<data-access.adoc#orm-jpa, Spring's JPA support>> where load-time weaving may be
|
||||
necessary for JPA class transformation.
|
||||
Consult the
|
||||
{api-spring-framework}/orm/jpa/LocalContainerEntityManagerFactoryBean.html[`LocalContainerEntityManagerFactoryBean`]
|
||||
javadoc for more detail. For more on AspectJ load-time weaving, see <<aop-aj-ltw>>.
|
||||
|
||||
|
||||
@@ -8180,7 +8181,7 @@ javadoc for more detail. For more on AspectJ load-time weaving, see <<aop-aj-ltw
|
||||
[[context-introduction]]
|
||||
== Additional Capabilities of the `ApplicationContext`
|
||||
|
||||
As discussed in the <<beans,chapter introduction>>, the `org.springframework.beans.factory`
|
||||
As discussed in the <<beans, chapter introduction>>, the `org.springframework.beans.factory`
|
||||
package provides basic functionality for managing and manipulating beans, including in a
|
||||
programmatic way. The `org.springframework.context` package adds the
|
||||
{api-spring-framework}/context/ApplicationContext.html[`ApplicationContext`]
|
||||
@@ -8416,7 +8417,7 @@ class and the `ApplicationListener` interface. If a bean that implements the
|
||||
Essentially, this is the standard Observer design pattern.
|
||||
|
||||
TIP: As of Spring 4.2, the event infrastructure has been significantly improved and offers
|
||||
an <<context-functionality-events-annotation,annotation-based model>> as well as the
|
||||
an <<context-functionality-events-annotation, annotation-based model>> as well as the
|
||||
ability to publish any arbitrary event (that is, an object that does not necessarily
|
||||
extend from `ApplicationEvent`). When such an object is published, we wrap it in an
|
||||
event for you.
|
||||
@@ -8640,12 +8641,12 @@ following example shows how to do so:
|
||||
}
|
||||
----
|
||||
|
||||
It is also possible to add additional runtime filtering by using the `condition` attribute of the
|
||||
annotation that defines a <<expressions,`SpEL` expression>> , which should match to actually
|
||||
invoke the method for a particular event.
|
||||
It is also possible to add additional runtime filtering by using the `condition` attribute
|
||||
of the annotation that defines a <<expressions, `SpEL` expression>> , which should match
|
||||
to actually invoke the method for a particular event.
|
||||
|
||||
The following example shows how our notifier can be rewritten to be invoked only if the `content` attribute
|
||||
of the event is equal to `my-event`:
|
||||
The following example shows how our notifier can be rewritten to be invoked only if the
|
||||
`content` attribute of the event is equal to `my-event`:
|
||||
|
||||
[source,java,indent=0]
|
||||
[subs="verbatim,quotes"]
|
||||
@@ -8699,8 +8700,8 @@ method signature to return the event that should be published, as the following
|
||||
}
|
||||
----
|
||||
|
||||
NOTE: This feature is not supported for <<context-functionality-events-async,asynchronous
|
||||
listeners>>.
|
||||
NOTE: This feature is not supported for
|
||||
<<context-functionality-events-async, asynchronous listeners>>.
|
||||
|
||||
This new method publishes a new `ListUpdateEvent` for every `BlackListEvent` handled by the
|
||||
method above. If you need to publish several events, you can return a `Collection` of events
|
||||
@@ -8711,8 +8712,8 @@ instead.
|
||||
==== Asynchronous Listeners
|
||||
|
||||
If you want a particular listener to process events asynchronously, you can reuse the
|
||||
<<integration.adoc#scheduling-annotation-support-async,regular `@Async` support>>. The
|
||||
following example shows how to do so:
|
||||
<<integration.adoc#scheduling-annotation-support-async, regular `@Async` support>>.
|
||||
The following example shows how to do so:
|
||||
|
||||
[source,java,indent=0]
|
||||
[subs="verbatim,quotes"]
|
||||
@@ -8801,9 +8802,8 @@ an event.
|
||||
[[context-functionality-resources]]
|
||||
=== Convenient Access to Low-level Resources
|
||||
|
||||
For optimal usage and understanding of application contexts, you should
|
||||
familiarize yourself with Spring's `Resource` abstraction, as described in
|
||||
<<resources>>.
|
||||
For optimal usage and understanding of application contexts, you should familiarize
|
||||
yourself with Spring's `Resource` abstraction, as described in <<resources>>.
|
||||
|
||||
An application context is a `ResourceLoader`, which can be used to load `Resource` objects.
|
||||
A `Resource` is essentially a more feature rich version of the JDK `java.net.URL` class.
|
||||
@@ -8957,11 +8957,11 @@ by convention (that is, by bean name or by bean type -- in particular, post-proc
|
||||
while a plain `DefaultListableBeanFactory` is agnostic about any special beans.
|
||||
|
||||
For many extended container features, such as annotation processing and AOP proxying,
|
||||
the <<beans-factory-extension-bpp,`BeanPostProcessor` extension point>> is essential.
|
||||
the <<beans-factory-extension-bpp, `BeanPostProcessor` extension point>> is essential.
|
||||
If you use only a plain `DefaultListableBeanFactory`, such post-processors do not
|
||||
get detected and activated by default. This situation could be confusing, because
|
||||
nothing is actually wrong with your bean configuration. Rather, in such a scenario, the
|
||||
container needs to be fully bootstrapped through additional setup.
|
||||
nothing is actually wrong with your bean configuration. Rather, in such a scenario,
|
||||
the container needs to be fully bootstrapped through additional setup.
|
||||
|
||||
The following table lists features provided by the `BeanFactory` and
|
||||
`ApplicationContext` interfaces and implementations.
|
||||
|
||||
@@ -10,7 +10,7 @@ APIs as follows:
|
||||
|
||||
* <<databuffers-factory>> abstracts the creation of a data buffer.
|
||||
* <<databuffers-buffer>> represents a byte buffer, which may be
|
||||
<<databuffers-buffer-pooled,pooled>>.
|
||||
<<databuffers-buffer-pooled, pooled>>.
|
||||
* <<databuffers-utils>> offers utility methods for data buffers.
|
||||
* <<Codecs>> decode or encode streams data buffer streams into higher level objects.
|
||||
|
||||
@@ -93,7 +93,6 @@ composite buffers, if that's supported by the underlying byte buffer API.
|
||||
|
||||
|
||||
|
||||
|
||||
[[codecs]]
|
||||
== Codecs
|
||||
|
||||
@@ -105,7 +104,7 @@ The `org.springframework.core.codec` package provides the following strategy int
|
||||
The `spring-core` module provides `byte[]`, `ByteBuffer`, `DataBuffer`, `Resource`, and
|
||||
`String` encoder and decoder implementations. The `spring-web` module adds Jackson JSON,
|
||||
Jackson Smile, JAXB2, Protocol Buffers and other encoders and decoders. See
|
||||
<<web-reactive.adoc#webflux-codecs,Codecs>> in the WebFlux section.
|
||||
<<web-reactive.adoc#webflux-codecs, Codecs>> in the WebFlux section.
|
||||
|
||||
|
||||
|
||||
@@ -114,7 +113,7 @@ Jackson Smile, JAXB2, Protocol Buffers and other encoders and decoders. See
|
||||
== Using `DataBuffer`
|
||||
|
||||
When working with data buffers, special care must be taken to ensure buffers are released
|
||||
since they may be <<databuffers-buffer-pooled,pooled>>. We'll use codecs to illustrate
|
||||
since they may be <<databuffers-buffer-pooled, pooled>>. We'll use codecs to illustrate
|
||||
how that works but the concepts apply more generally. Let's see what codecs must do
|
||||
internally to manage data buffers.
|
||||
|
||||
|
||||
@@ -10,8 +10,8 @@ While there are several other Java expression languages available -- OGNL, MVEL,
|
||||
EL, to name a few -- the Spring Expression Language was created to provide the Spring
|
||||
community with a single well supported expression language that can be used across all
|
||||
the products in the Spring portfolio. Its language features are driven by the
|
||||
requirements of the projects in the Spring portfolio, including tooling requirements for
|
||||
code completion support within the Eclipse-based Spring Tool Suite. That said,
|
||||
requirements of the projects in the Spring portfolio, including tooling requirements
|
||||
for code completion support within the Eclipse-based Spring Tool Suite. That said,
|
||||
SpEL is based on a technology-agnostic API that lets other expression language
|
||||
implementations be integrated, should the need arise.
|
||||
|
||||
@@ -20,14 +20,14 @@ portfolio, it is not directly tied to Spring and can be used independently. To
|
||||
be self contained, many of the examples in this chapter use SpEL as if it were an
|
||||
independent expression language. This requires creating a few bootstrapping
|
||||
infrastructure classes, such as the parser. Most Spring users need not deal with
|
||||
this infrastructure and can, instead, author only expression strings for evaluation. An
|
||||
example of this typical use is the integration of SpEL into creating XML or annotation-based
|
||||
bean definitions, as shown in <<expressions-beandef,Expression support
|
||||
for defining bean definitions>>.
|
||||
this infrastructure and can, instead, author only expression strings for evaluation.
|
||||
An example of this typical use is the integration of SpEL into creating XML or
|
||||
annotation-based bean definitions, as shown in
|
||||
<<expressions-beandef, Expression support for defining bean definitions>>.
|
||||
|
||||
This chapter covers the features of the expression language, its API, and its language
|
||||
syntax. In several places, `Inventor` and `Society` classes are used as the
|
||||
target objects for expression evaluation. These class declarations and the data used to
|
||||
syntax. In several places, `Inventor` and `Society` classes are used as the target
|
||||
objects for expression evaluation. These class declarations and the data used to
|
||||
populate them are listed at the end of the chapter.
|
||||
|
||||
The expression language supports the following functionality:
|
||||
@@ -60,7 +60,7 @@ The expression language supports the following functionality:
|
||||
|
||||
This section introduces the simple use of SpEL interfaces and its expression language.
|
||||
The complete language reference can be found in
|
||||
<<expressions-language-ref,Language Reference>>.
|
||||
<<expressions-language-ref, Language Reference>>.
|
||||
|
||||
The following code introduces the SpEL API to evaluate the literal string expression,
|
||||
`Hello World`.
|
||||
@@ -319,13 +319,14 @@ interpreter and only 3ms using the compiled version of the expression.
|
||||
[[expressions-compiler-configuration]]
|
||||
==== Compiler Configuration
|
||||
|
||||
The compiler is not turned on by default, but you can turn it on in either of two different ways.
|
||||
You can turn it on by using the parser configuration process (<<expressions-parser-configuration,discussed earlier>>)
|
||||
or by using a system property when SpEL usage is embedded inside another component. This section
|
||||
The compiler is not turned on by default, but you can turn it on in either of two
|
||||
different ways. You can turn it on by using the parser configuration process
|
||||
(<<expressions-parser-configuration, discussed earlier>>) or by using a system
|
||||
property when SpEL usage is embedded inside another component. This section
|
||||
discusses both of these options.
|
||||
|
||||
The compiler can operate in one of three modes, which are captured
|
||||
in the `org.springframework.expression.spel.SpelCompilerMode` enum. The modes are as follows:
|
||||
The compiler can operate in one of three modes, which are captured in the
|
||||
`org.springframework.expression.spel.SpelCompilerMode` enum. The modes are as follows:
|
||||
|
||||
* `OFF` (default): The compiler is switched off.
|
||||
* `IMMEDIATE`: In immediate mode, the expressions are compiled as soon as possible. This
|
||||
@@ -612,7 +613,7 @@ By default, real numbers are parsed by using Double.parseDouble().
|
||||
|
||||
Navigating with property references is easy. To do so, use a period to indicate a nested
|
||||
property value. The instances of the `Inventor` class, `pupin` and `tesla`, were populated with
|
||||
data listed in the <<expressions-example-classes,Classes used in the examples>> section.
|
||||
data listed in the <<expressions-example-classes, Classes used in the examples>> section.
|
||||
To navigate "`down`" and get Tesla's year of birth and Pupin's city of birth, we use the following
|
||||
expressions:
|
||||
|
||||
|
||||
@@ -1,29 +1,31 @@
|
||||
[[null-safety]]
|
||||
[-[null-safety]]
|
||||
= Null-safety
|
||||
|
||||
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:
|
||||
Although Java does not let you express null-safety with its type system, the 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 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/Nullable.html[`@Nullable`]: Annotation to indicate that a
|
||||
specific parameter, return value, or field can be `null`.
|
||||
* {api-spring-framework}/lang/NonNull.html[`@NonNull`]: Annotation to indicate that a specific
|
||||
parameter, return value, or field cannot be `null` (not needed on parameters / return values
|
||||
and fields where `@NonNullApi` and `@NonNullFields` apply, respectively).
|
||||
* {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.
|
||||
that declares non-null as the default semantics 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.
|
||||
level that declares non-null as the default semantics 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,
|
||||
varargs and array elements nullability are not supported yet, but should be in an upcoming
|
||||
release, see https://jira.spring.io/browse/SPR-15942[SPR-15942] for up-to-date information.
|
||||
Nullability declaration are expected to be fine-tuned between Spring Framework release,
|
||||
including minor ones. Nullability of types used inside method bodies is outside of the
|
||||
scope of this feature.
|
||||
The Spring Framework itself leverages 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, varargs and array elements nullability are not supported yet but
|
||||
should be in an upcoming release, see https://jira.spring.io/browse/SPR-15942[SPR-15942]
|
||||
for up-to-date information. Nullability declarations are expected to be fine-tuned between
|
||||
Spring Framework releases, 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 that use this feature.
|
||||
NOTE: Other common libraries such as Reactor and Spring Data provide null-safe APIs that
|
||||
use a similar nullability arrangement, delivering a consistent overall experience for
|
||||
Spring application developers.
|
||||
|
||||
|
||||
|
||||
@@ -32,25 +34,23 @@ NOTE: Libraries like Reactor or Spring Data provide null-safe APIs that use this
|
||||
|
||||
In addition to providing an explicit declaration for Spring Framework API nullability,
|
||||
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.
|
||||
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
|
||||
supports https://kotlinlang.org/docs/reference/null-safety.html[null-safety]. More details
|
||||
are available in the <<languages#kotlin-null-safety,Kotlin support documentation>>.
|
||||
are available in the <<languages#kotlin-null-safety, Kotlin support documentation>>.
|
||||
|
||||
|
||||
|
||||
|
||||
== JSR 305 meta-annotations
|
||||
== JSR-305 meta-annotations
|
||||
|
||||
Spring annotations are meta-annotated with https://jcp.org/en/jsr/detail?id=305[JSR 305]
|
||||
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.
|
||||
annotations (a dormant but wide-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 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.
|
||||
It is not necessary nor recommended to add a JSR-305 dependency to 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.
|
||||
|
||||
@@ -337,10 +337,10 @@ interface if that is all you need. The code would be coupled only to the resourc
|
||||
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
|
||||
`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 a
|
||||
In application components, you may also rely upon autowiring of the `ResourceLoader` as
|
||||
an alternative to implementing the `ResourceLoaderAware` interface. The "`traditional`"
|
||||
`constructor` and `byType` autowiring modes (as described in <<beans-factory-autowire>>)
|
||||
are capable of providing a `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,
|
||||
|
||||
@@ -20,18 +20,19 @@ directly. Because this is reference documentation, however, we felt that some ex
|
||||
might be in order. We explain the `BeanWrapper` in this chapter, since, if you are
|
||||
going to use it at all, you are most likely do so when trying to bind data to objects.
|
||||
|
||||
Spring's `DataBinder` and the lower-level `BeanWrapper` both use `PropertyEditorSupport` implementations to parse
|
||||
and format property values. The `PropertyEditor` and `PropertyEditorSupport` interfaces are part of the JavaBeans
|
||||
specification and are also explained in this chapter. Spring 3 introduced a
|
||||
`core.convert` package that provides a general type conversion facility, as well as a
|
||||
higher-level "`format`" package for formatting UI field values. You can use these packages
|
||||
as simpler alternatives to `PropertyEditorSupport` implementations. They are also discussed in this
|
||||
chapter.
|
||||
Spring's `DataBinder` and the lower-level `BeanWrapper` both use `PropertyEditorSupport`
|
||||
implementations to parse and format property values. The `PropertyEditor` and
|
||||
`PropertyEditorSupport` types are part of the JavaBeans specification and are also
|
||||
explained in this chapter. Spring 3 introduced a `core.convert` package that provides a
|
||||
general type conversion facility, as well as a higher-level "`format`" package for
|
||||
formatting UI field values. You can use these packages as simpler alternatives to
|
||||
`PropertyEditorSupport` implementations. They are also discussed in this chapter.
|
||||
|
||||
.JSR-303/JSR-349 Bean Validation
|
||||
****
|
||||
As of version 4.0, Spring Framework supports Bean Validation 1.0 (JSR-303) and Bean Validation 1.1
|
||||
(JSR-349) for setup support and adapting them to Spring's `Validator` interface.
|
||||
As of version 4.0, Spring Framework supports Bean Validation 1.0 (JSR-303) and
|
||||
Bean Validation 1.1 (JSR-349) for setup support and adapting them to Spring's
|
||||
`Validator` interface.
|
||||
|
||||
An application can choose to enable Bean Validation once globally, as described in
|
||||
<<validation-beanvalidation>>, and use it exclusively for all validation needs.
|
||||
@@ -167,22 +168,21 @@ methods it offers can be found in the {api-spring-framework}validation/Errors.ht
|
||||
[[validation-conversion]]
|
||||
== Resolving Codes to Error Messages
|
||||
|
||||
We covered databinding and validation. This section covers outputting messages that correspond to
|
||||
validation errors. In the example shown in the <<validator,preceding section>>,
|
||||
we rejected the `name` and `age` fields. If we want to output the error
|
||||
messages by using a `MessageSource`, we can do so using the error code we provide when
|
||||
rejecting the field ('name' and 'age' in this case). When you call (either directly, or
|
||||
indirectly, by using, for example, the `ValidationUtils` class) `rejectValue` or one of the
|
||||
other `reject` methods from the `Errors` interface, the underlying implementation
|
||||
not only registers the code you passed in but also registers a number of additional error
|
||||
codes. The `MessageCodesResolver` determines which error codes the `Errors` interface registers.
|
||||
By default, the `DefaultMessageCodesResolver` is used, which (for example) not only
|
||||
registers a message with the code you gave but also registers messages that include the field
|
||||
name you passed to the reject method. So, if you reject a field by using
|
||||
`rejectValue("age", "too.darn.old")`, apart from the `too.darn.old` code, Spring
|
||||
also registers `too.darn.old.age` and `too.darn.old.age.int` (the first includes
|
||||
the field name and the second includes the type of the field). This is done as a
|
||||
convenience to aid developers when targeting error messages.
|
||||
We covered databinding and validation. This section covers outputting messages that correspond
|
||||
to validation errors. In the example shown in the <<validator, preceding section>>,
|
||||
we rejected the `name` and `age` fields. If we want to output the error messages by using a
|
||||
`MessageSource`, we can do so using the error code we provide when rejecting the field
|
||||
('name' and 'age' in this case). When you call (either directly, or indirectly, by using,
|
||||
for example, the `ValidationUtils` class) `rejectValue` or one of the other `reject` methods
|
||||
from the `Errors` interface, the underlying implementation not only registers the code you
|
||||
passed in but also registers a number of additional error codes. The `MessageCodesResolver`
|
||||
determines which error codes the `Errors` interface registers. By default, the
|
||||
`DefaultMessageCodesResolver` is used, which (for example) not only registers a message
|
||||
with the code you gave but also registers messages that include the field name you passed
|
||||
to the reject method. So, if you reject a field by using `rejectValue("age", "too.darn.old")`,
|
||||
apart from the `too.darn.old` code, Spring also registers `too.darn.old.age` and
|
||||
`too.darn.old.age.int` (the first includes the field name and the second includes the type
|
||||
of the field). This is done as a convenience to aid developers when targeting error messages.
|
||||
|
||||
More information on the `MessageCodesResolver` and the default strategy can be found
|
||||
in the javadoc of
|
||||
@@ -253,8 +253,8 @@ object. The following table shows some examples of these conventions:
|
||||
|
||||
(This next section is not vitally important to you if you do not plan to work with
|
||||
the `BeanWrapper` directly. If you use only the `DataBinder` and the `BeanFactory`
|
||||
and their default implementations, you should skip ahead to the <<beans-beans-conversion,section about
|
||||
`PropertyEditors`>>.)
|
||||
and their default implementations, you should skip ahead to the
|
||||
<<beans-beans-conversion, section on `PropertyEditors`>>.)
|
||||
|
||||
The following two example classes use the `BeanWrapper` to get and set
|
||||
properties:
|
||||
@@ -521,17 +521,17 @@ where it can be automatically detected and applied.
|
||||
Note that all bean factories and application contexts automatically use a number of
|
||||
built-in property editors, through their use a `BeanWrapper` to
|
||||
handle property conversions. The standard property editors that the `BeanWrapper`
|
||||
registers are listed in <<beans-beans-conversion,the previous section>>. Additionally,
|
||||
`ApplicationContexts` also override or add additional editors to handle
|
||||
registers are listed in the <<beans-beans-conversion, previous section>>.
|
||||
Additionally, `ApplicationContexts` also override or add additional editors to handle
|
||||
resource lookups in a manner appropriate to the specific application context type.
|
||||
|
||||
Standard JavaBeans `PropertyEditor` instances are used to convert property values
|
||||
expressed as strings to the actual complex type of the property.
|
||||
You can use `CustomEditorConfigurer`, a bean factory post-processor, to conveniently add
|
||||
expressed as strings to the actual complex type of the property. You can use
|
||||
`CustomEditorConfigurer`, a bean factory post-processor, to conveniently add
|
||||
support for additional `PropertyEditor` instances to an `ApplicationContext`.
|
||||
|
||||
Consider the following example, which defines a user class called `ExoticType` and another class called `DependsOnExoticType`, which needs
|
||||
`ExoticType` set as a property:
|
||||
Consider the following example, which defines a user class called `ExoticType` and
|
||||
another class called `DependsOnExoticType`, which needs `ExoticType` set as a property:
|
||||
|
||||
[source,java,indent=0]
|
||||
[subs="verbatim,quotes"]
|
||||
@@ -605,14 +605,15 @@ Finally, the following example shows how to use `CustomEditorConfigurer` to regi
|
||||
|
||||
Another mechanism for registering property editors with the Spring container is to
|
||||
create and use a `PropertyEditorRegistrar`. This interface is particularly useful when
|
||||
you need to use the same set of property editors in several different situations. You can write
|
||||
a corresponding registrar and reuse it in each case. `PropertyEditorRegistrar` instances work
|
||||
in conjunction with an interface called `PropertyEditorRegistry`, an interface that is
|
||||
implemented by the Spring `BeanWrapper` (and `DataBinder`). `PropertyEditorRegistrar` instances
|
||||
are particularly convenient when used in conjunction with `CustomEditorConfigurer`
|
||||
(described <<beans-beans-conversion-customeditor-registration,here>>), which exposes a
|
||||
property called `setPropertyEditorRegistrars(..)`. `PropertyEditorRegistrar` instances added to a
|
||||
`CustomEditorConfigurer` in this fashion can easily be shared with `DataBinder` and
|
||||
you need to use the same set of property editors in several different situations.
|
||||
You can write a corresponding registrar and reuse it in each case.
|
||||
`PropertyEditorRegistrar` instances work in conjunction with an interface called
|
||||
`PropertyEditorRegistry`, an interface that is implemented by the Spring `BeanWrapper`
|
||||
(and `DataBinder`). `PropertyEditorRegistrar` instances are particularly convenient
|
||||
when used in conjunction with `CustomEditorConfigurer` (described
|
||||
<<beans-beans-conversion-customeditor-registration, here>>), which exposes a property
|
||||
called `setPropertyEditorRegistrars(..)`. `PropertyEditorRegistrar` instances added
|
||||
to a `CustomEditorConfigurer` in this fashion can easily be shared with `DataBinder` and
|
||||
Spring MVC controllers. Furthermore, it avoids the need for synchronization on custom
|
||||
editors: A `PropertyEditorRegistrar` is expected to create fresh `PropertyEditor`
|
||||
instances for each bean creation attempt.
|
||||
@@ -659,7 +660,7 @@ The next example shows how to configure a `CustomEditorConfigurer` and inject an
|
||||
----
|
||||
|
||||
Finally (and in a bit of a departure from the focus of this chapter for those of you
|
||||
using <<web.adoc#mvc,Spring's MVC web framework>>), using `PropertyEditorRegistrars` in
|
||||
using <<web.adoc#mvc, Spring's MVC web framework>>), using `PropertyEditorRegistrars` in
|
||||
conjunction with data-binding `Controllers` (such as `SimpleFormController`) can be very
|
||||
convenient. The following example uses a `PropertyEditorRegistrar` in the
|
||||
implementation of an `initBinder(..)` method:
|
||||
@@ -954,8 +955,7 @@ It is also common to use a `ConversionService` within a Spring MVC application.
|
||||
<<web.adoc#mvc-config-conversion, Conversion and Formatting>> in the Spring MVC chapter.
|
||||
|
||||
In certain situations, you may wish to apply formatting during conversion. See
|
||||
<<format-FormatterRegistry-SPI>> for details on using
|
||||
`FormattingConversionServiceFactoryBean`.
|
||||
<<format-FormatterRegistry-SPI>> for details on using `FormattingConversionServiceFactoryBean`.
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user