Browse Source

Revise BeanFactory vs ApplicationContext section in reference docs

Issue: SPR-17095
pull/1935/head
Juergen Hoeller 8 years ago
parent
commit
7ac99c1c2d
  1. 109
      src/asciidoc/core-aop.adoc
  2. 143
      src/asciidoc/core-beans.adoc

109
src/asciidoc/core-aop.adoc

@ -2,8 +2,11 @@ @@ -2,8 +2,11 @@
= Aspect Oriented Programming with Spring
[[aop-introduction]]
== Introduction
__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
@ -15,17 +18,16 @@ One of the key components of Spring is the __AOP framework__. While the Spring I @@ -15,17 +18,16 @@ One of the key components of Spring is the __AOP framework__. While the Spring I
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 2.0+ AOP
****
Spring 2.0 introduces a simpler and more powerful way of writing custom aspects using
Spring 2.0 introduced a simpler and more powerful way of writing custom aspects 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.
The Spring 2.0 schema- and @AspectJ-based AOP support is discussed in this chapter.
Spring 2.0 AOP remains fully backwards compatible with Spring 1.2 AOP, and the
lower-level AOP support offered by the Spring 1.2 APIs is discussed in <<aop-api,the
following chapter>>.
The Spring 2.0+ schema- and @AspectJ-based AOP support is discussed in this chapter.
The lower-level AOP support, as commonly exposed in Spring 1.2 applications, is
discussed in <<aop-api,the following chapter>>.
****
AOP is used in the Spring Framework to...
@ -46,6 +48,7 @@ Spring AOP, and can skip most of this chapter. @@ -46,6 +48,7 @@ Spring AOP, and can skip most of this chapter.
[[aop-introduction-defn]]
=== AOP concepts
Let us begin by defining some central AOP concepts and terminology. These terms are not
Spring-specific... unfortunately, AOP terminology is not particularly intuitive;
however, it would be even more confusing if Spring used its own terminology.
@ -59,7 +62,7 @@ however, it would be even more confusing if Spring used its own terminology. @@ -59,7 +62,7 @@ however, it would be even more confusing if Spring used its own terminology.
method or the handling of an exception. In Spring AOP, a join point __always__
represents a method execution.
* __Advice__: action taken by an aspect at a particular join point. Different types of
advice include "around," "before" and "after" advice. (Advice types are discussed
advice include "around", "before" and "after" advice. (Advice types are discussed
below.) Many AOP frameworks, including Spring, model an advice as an __interceptor__,
maintaining a chain of interceptors __around__ the join point.
* __Pointcut__: a predicate that matches join points. Advice is associated with a
@ -123,6 +126,7 @@ multiple objects (such as all business operations in the service layer). @@ -123,6 +126,7 @@ multiple objects (such as all business operations in the service layer).
[[aop-introduction-spring-defn]]
=== Spring AOP capabilities and goals
Spring AOP is implemented in pure Java. There is no need for a special compilation
process. Spring AOP does not need to control the class loader hierarchy, and is thus
suitable for use in a Servlet container or application server.
@ -182,6 +186,7 @@ style. @@ -182,6 +186,7 @@ style.
[[aop-introduction-proxies]]
=== AOP Proxies
Spring AOP defaults to using standard JDK __dynamic proxies__ for AOP proxies. This
enables any interface (or set of interfaces) to be proxied.
@ -202,6 +207,7 @@ implementation detail actually means. @@ -202,6 +207,7 @@ implementation detail actually means.
[[aop-ataspectj]]
== @AspectJ support
@AspectJ refers to a style of declaring aspects as regular Java classes annotated with
annotations. The @AspectJ style was introduced by the
http://www.eclipse.org/aspectj[AspectJ project] as part of the AspectJ 5 release. Spring
@ -219,6 +225,7 @@ discussed in <<aop-using-aspectj>>. @@ -219,6 +225,7 @@ discussed in <<aop-using-aspectj>>.
[[aop-aspectj-support]]
=== Enabling @AspectJ Support
To use @AspectJ aspects in a Spring configuration you need to enable Spring support for
configuring Spring AOP based on @AspectJ aspects, and __autoproxying__ beans based on
whether or not they are advised by those aspects. By autoproxying we mean that if Spring
@ -234,6 +241,7 @@ classpath of your application (version 1.6.8 or later). This library is availabl @@ -234,6 +241,7 @@ classpath of your application (version 1.6.8 or later). This library is availabl
[[aop-enable-aspectj-java]]
==== Enabling @AspectJ Support with Java configuration
To enable @AspectJ support with Java `@Configuration` add the `@EnableAspectJAutoProxy`
annotation:
@ -250,6 +258,7 @@ annotation: @@ -250,6 +258,7 @@ annotation:
[[aop-enable-aspectj-xml]]
==== Enabling @AspectJ Support with XML configuration
To enable @AspectJ support with XML based configuration use the `aop:aspectj-autoproxy`
element:
@ -259,8 +268,8 @@ element: @@ -259,8 +268,8 @@ element:
<aop:aspectj-autoproxy/>
----
This assumes that you are using schema support as described in <<xsd-configuration>>. See
<<xsd-config-body-schemas-aop>> for how to import the tags in the `aop` namespace.
This assumes that you are using schema support as described in <<xsd-configuration>>.
See <<xsd-config-body-schemas-aop>> for how to import the tags in the `aop` namespace.
@ -325,6 +334,7 @@ hence excludes it from auto-proxying. @@ -325,6 +334,7 @@ hence excludes it from auto-proxying.
[[aop-pointcuts]]
=== Declaring a pointcut
Recall that pointcuts determine join points of interest, and thus enable us to control
when advice executes. __Spring AOP only supports method execution join points for Spring
beans__, so you can think of a pointcut as matching the execution of methods on Spring
@ -357,6 +367,7 @@ et. al. or "AspectJ in Action" by Ramnivas Laddad. @@ -357,6 +367,7 @@ et. al. or "AspectJ in Action" by Ramnivas Laddad.
[[aop-pointcuts-designators]]
==== Supported Pointcut Designators
Spring AOP supports the following AspectJ pointcut designators (PCD) for use in pointcut
expressions:
@ -454,6 +465,7 @@ it is natural and straightforward to identify specific beans by name. @@ -454,6 +465,7 @@ it is natural and straightforward to identify specific beans by name.
[[aop-pointcuts-combining]]
==== Combining pointcut expressions
Pointcut expressions can be combined using '&&', '||' and '!'. It is also possible to
refer to pointcut expressions by name. The following example shows three pointcut
expressions: `anyPublicOperation` (which matches if a method execution join point
@ -483,6 +495,7 @@ __matching__. @@ -483,6 +495,7 @@ __matching__.
[[aop-common-pointcuts]]
==== Sharing common pointcut definitions
When working with enterprise applications, you often want to refer to modules of the
application and particular sets of operations from within several aspects. We recommend
defining a "SystemArchitecture" aspect that captures common pointcut expressions for
@ -577,6 +590,7 @@ transaction elements are discussed in <<transaction>>. @@ -577,6 +590,7 @@ transaction elements are discussed in <<transaction>>.
[[aop-pointcuts-examples]]
==== Examples
Spring AOP users are likely to use the `execution` pointcut designator the most often.
The format of an execution expression is:
@ -793,6 +807,7 @@ how to make the annotation object(s) available in the advice body. @@ -793,6 +807,7 @@ how to make the annotation object(s) available in the advice body.
[[writing-good-pointcuts]]
==== Writing good pointcuts
During compilation, AspectJ processes pointcuts in order to try and optimize matching
performance. Examining code and determining if each join point matches (statically or
dynamically) a given pointcut is a costly process. (A dynamic match means the match
@ -830,6 +845,7 @@ pointcut should always include one if possible. @@ -830,6 +845,7 @@ pointcut should always include one if possible.
[[aop-advice]]
=== Declaring advice
Advice is associated with a pointcut expression, and runs before, after, or around
method executions matched by the pointcut. The pointcut expression may be either a
simple reference to a named pointcut, or a pointcut expression declared in place.
@ -837,6 +853,7 @@ simple reference to a named pointcut, or a pointcut expression declared in place @@ -837,6 +853,7 @@ simple reference to a named pointcut, or a pointcut expression declared in place
[[aop-advice-before]]
==== Before advice
Before advice is declared in an aspect using the `@Before` annotation:
[source,java,indent=0]
@ -878,6 +895,7 @@ If using an in-place pointcut expression we could rewrite the above example as: @@ -878,6 +895,7 @@ If using an in-place pointcut expression we could rewrite the above example as:
[[aop-advice-after-returning]]
==== After returning advice
After returning advice runs when a matched method execution returns normally. It is
declared using the `@AfterReturning` annotation:
@ -939,6 +957,7 @@ using after-returning advice. @@ -939,6 +957,7 @@ using after-returning advice.
[[aop-advice-after-throwing]]
==== After throwing advice
After throwing advice runs when a matched method execution exits by throwing an
exception. It is declared using the `@AfterThrowing` annotation:
@ -992,6 +1011,7 @@ of the specified type ( `DataAccessException` in this case). @@ -992,6 +1011,7 @@ of the specified type ( `DataAccessException` in this case).
[[aop-advice-after-finally]]
==== After (finally) advice
After (finally) advice runs however a matched method execution exits. It is declared
using the `@After` annotation. After advice must be prepared to handle both normal and
exception return conditions. It is typically used for releasing resources, etc.
@ -1016,6 +1036,7 @@ exception return conditions. It is typically used for releasing resources, etc. @@ -1016,6 +1036,7 @@ exception return conditions. It is typically used for releasing resources, etc.
[[aop-ataspectj-around-advice]]
==== Around advice
The final kind of advice is around advice. Around advice runs "around" a matched method
execution. It has the opportunity to do work both before and after the method executes,
and to determine when, how, and even if, the method actually gets to execute at all.
@ -1077,6 +1098,7 @@ legal. @@ -1077,6 +1098,7 @@ legal.
[[aop-ataspectj-advice-params]]
==== Advice parameters
Spring offers fully typed advice - meaning that you declare the parameters you need
in the advice signature (as we saw for the returning and throwing examples above) rather
than work with `Object[]` arrays all the time. We'll see how to make argument and other
@ -1098,6 +1120,7 @@ Please do consult the javadocs for full details. @@ -1098,6 +1120,7 @@ Please do consult the javadocs for full details.
[[aop-ataspectj-advice-params-passing]]
===== Passing parameters to advice
We've already seen how to bind the returned value or exception value (using after
returning and after throwing advice). To make argument values available to the advice
body, you can use the binding form of `args`. If a parameter name is used in place of a
@ -1172,6 +1195,7 @@ And then the advice that matches the execution of `@Auditable` methods: @@ -1172,6 +1195,7 @@ And then the advice that matches the execution of `@Auditable` methods:
[[aop-ataspectj-advice-params-generics]]
===== Advice parameters and generics
Spring AOP can handle generics used in class declarations and method parameters. Suppose
you have a generic type like this:
@ -1216,6 +1240,7 @@ check the type of the elements. @@ -1216,6 +1240,7 @@ check the type of the elements.
[[aop-ataspectj-advice-params-names]]
===== Determining argument names
The parameter binding in advice invocations relies on matching names used in pointcut
expressions to declared parameter names in (advice and pointcut) method signatures.
Parameter names are __not__ available through Java reflection, so Spring AOP uses the
@ -1295,6 +1320,7 @@ will retain the needed information. @@ -1295,6 +1320,7 @@ will retain the needed information.
[[aop-ataspectj-advice-proceeding-with-the-call]]
===== Proceeding with arguments
We remarked earlier that we would describe how to write a proceed call __with
arguments__ that works consistently across Spring AOP and AspectJ. The solution is
simply to ensure that the advice signature binds each of the method parameters in order.
@ -1318,6 +1344,7 @@ In many cases you will be doing this binding anyway (as in the example above). @@ -1318,6 +1344,7 @@ In many cases you will be doing this binding anyway (as in the example above).
[[aop-ataspectj-advice-ordering]]
==== Advice ordering
What happens when multiple pieces of advice all want to run at the same join point?
Spring AOP follows the same precedence rules as AspectJ to determine the order of advice
execution. The highest precedence advice runs first "on the way in" (so given two pieces
@ -1343,6 +1370,7 @@ pieces of advice into separate aspect classes - which can be ordered at the aspe @@ -1343,6 +1370,7 @@ pieces of advice into separate aspect classes - which can be ordered at the aspe
[[aop-introductions]]
=== Introductions
Introductions (known as inter-type declarations in AspectJ) enable an aspect to declare
that advised objects implement a given interface, and to provide an implementation of
that interface on behalf of those objects.
@ -1387,6 +1415,7 @@ you would write the following: @@ -1387,6 +1415,7 @@ you would write the following:
[[aop-instantiation-models]]
=== Aspect instantiation models
[NOTE]
====
(This is an advanced topic, so if you are just starting out with AOP you can safely skip
@ -1435,6 +1464,7 @@ creates one aspect instance for each unique target object at matched join points @@ -1435,6 +1464,7 @@ creates one aspect instance for each unique target object at matched join points
[[aop-ataspectj-example]]
=== Example
Now that you have seen how all the constituent parts work, let's put them together to do
something useful!
@ -1544,6 +1574,7 @@ expression so that only `@Idempotent` operations match: @@ -1544,6 +1574,7 @@ expression so that only `@Idempotent` operations match:
[[aop-schema]]
== Schema-based AOP support
If you prefer an XML-based format, then Spring also offers support for defining aspects
using the new "aop" namespace tags. The exact same pointcut expressions and advice kinds
are supported as when using the @AspectJ style, hence in this section we will focus on
@ -1552,8 +1583,8 @@ the new __syntax__ and refer the reader to the discussion in the previous sectio @@ -1552,8 +1583,8 @@ the new __syntax__ and refer the reader to the discussion in the previous sectio
of advice parameters.
To use the aop namespace tags described in this section, you need to import the
`spring-aop` schema as described in <<xsd-configuration>>. See <<xsd-config-body-schemas-aop>>
for how to import the tags in the `aop` namespace.
`spring-aop` schema as described in <<xsd-configuration>>.
See <<xsd-config-body-schemas-aop>> for how to import the tags in the `aop` namespace.
Within your Spring configurations, all aspect and advisor elements must be placed within
an `<aop:config>` element (you can have more than one `<aop:config>` element in an
@ -1573,6 +1604,7 @@ just the `<aop:config>` style, or just the `AutoProxyCreator` style. @@ -1573,6 +1604,7 @@ just the `<aop:config>` style, or just the `AutoProxyCreator` style.
[[aop-schema-declaring-an-aspect]]
=== Declaring an aspect
Using the schema support, an aspect is simply a regular Java object defined as a bean in
your Spring application context. The state and behavior is captured in the fields and
methods of the object, and the pointcut and advice information is captured in the XML.
@ -1594,13 +1626,14 @@ using the `ref` attribute: @@ -1594,13 +1626,14 @@ using the `ref` attribute:
</bean>
----
The bean backing the aspect (" `aBean`" in this case) can of course be configured and
The bean backing the aspect (`"aBean"` in this case) can of course be configured and
dependency injected just like any other Spring bean.
[[aop-schema-pointcuts]]
=== Declaring a pointcut
A named pointcut can be declared inside an <aop:config> element, enabling the pointcut
definition to be shared across several aspects and advisors.
@ -1690,12 +1723,12 @@ parameters of the matching names: @@ -1690,12 +1723,12 @@ parameters of the matching names:
}
----
When combining pointcut sub-expressions, '&&' is awkward within an XML document, and so
the keywords 'and', 'or' and 'not' can be used in place of '&&', '||' and '!'
When combining pointcut sub-expressions, `&&` is awkward within an XML document, and so
the keywords `and`, `or`, and `not` can be used in place of `&&`, `||`, and `!`
respectively. For example, the previous pointcut may be better written as:
[source,xml,indent=0]
[subs="verbatim"]
[subs="verbatim,quotes"]
----
<aop:config>
@ -1720,12 +1753,14 @@ style. @@ -1720,12 +1753,14 @@ style.
[[aop-schema-advice]]
=== Declaring advice
The same five advice kinds are supported as for the @AspectJ style, and they have
exactly the same semantics.
[[aop-schema-advice-before]]
==== Before advice
Before advice runs before a matched method execution. It is declared inside an
`<aop:aspect>` using the <aop:before> element.
@ -1773,6 +1808,7 @@ bean will be invoked. @@ -1773,6 +1808,7 @@ bean will be invoked.
[[aop-schema-advice-after-returning]]
==== After returning advice
After returning advice runs when a matched method execution completes normally. It is
declared inside an `<aop:aspect>` in the same way as before advice. For example:
@ -1822,6 +1858,7 @@ example, the method signature may be declared as: @@ -1822,6 +1858,7 @@ example, the method signature may be declared as:
[[aop-schema-advice-after-throwing]]
==== After throwing advice
After throwing advice executes when a matched method execution exits by throwing an
exception. It is declared inside an `<aop:aspect>` using the after-throwing element:
@ -1871,6 +1908,7 @@ example, the method signature may be declared as: @@ -1871,6 +1908,7 @@ example, the method signature may be declared as:
[[aop-schema-advice-after-finally]]
==== After (finally) advice
After (finally) advice runs however a matched method execution exits. It is declared
using the `after` element:
@ -1891,6 +1929,7 @@ using the `after` element: @@ -1891,6 +1929,7 @@ using the `after` element:
[[aop-schema-advice-around]]
==== Around advice
The final kind of advice is around advice. Around advice runs "around" a matched method
execution. It has the opportunity to do work both before and after the method executes,
and to determine when, how, and even if, the method actually gets to execute at all.
@ -1937,6 +1976,7 @@ The implementation of the `doBasicProfiling` advice would be exactly the same as @@ -1937,6 +1976,7 @@ The implementation of the `doBasicProfiling` advice would be exactly the same as
[[aop-schema-params]]
==== Advice parameters
The schema based declaration style supports fully typed advice in the same way as
described for the @AspectJ support - by matching pointcut parameters by name against
advice method parameters. See <<aop-ataspectj-advice-params>> for details. If you wish
@ -2074,6 +2114,7 @@ ms % Task name @@ -2074,6 +2114,7 @@ ms % Task name
[[aop-ordering]]
==== Advice ordering
When multiple advice needs to execute at the same join point (executing method) the
ordering rules are as described in <<aop-ataspectj-advice-ordering>>. The precedence
between aspects is determined by either adding the `Order` annotation to the bean
@ -2083,6 +2124,7 @@ backing the aspect or by having the bean implement the `Ordered` interface. @@ -2083,6 +2124,7 @@ backing the aspect or by having the bean implement the `Ordered` interface.
[[aop-schema-introductions]]
=== Introductions
Introductions (known as inter-type declarations in AspectJ) enable an aspect to declare
that advised objects implement a given interface, and to provide an implementation of
that interface on behalf of those objects.
@ -2139,6 +2181,7 @@ following: @@ -2139,6 +2181,7 @@ following:
[[aop-schema-instatiation-models]]
=== Aspect instantiation models
The only supported instantiation model for schema-defined aspects is the singleton
model. Other instantiation models may be supported in future releases.
@ -2146,7 +2189,8 @@ model. Other instantiation models may be supported in future releases. @@ -2146,7 +2189,8 @@ model. Other instantiation models may be supported in future releases.
[[aop-schema-advisors]]
=== Advisors
The concept of "advisors" is brought forward from the AOP support defined in Spring 1.2
The concept of "advisors" is brought forward from the AOP support defined in Spring
and does not have a direct equivalent in AspectJ. An advisor is like a small
self-contained aspect that has a single piece of advice. The advice itself is
represented by a bean, and must implement one of the advice interfaces described in
@ -2188,6 +2232,7 @@ use the `order` attribute to define the `Ordered` value of the advisor. @@ -2188,6 +2232,7 @@ use the `order` attribute to define the `Ordered` value of the advisor.
[[aop-schema-example]]
=== Example
Let's see how the concurrent locking failure retry example from
<<aop-ataspectj-example>> looks when rewritten using the schema support.
@ -2314,6 +2359,7 @@ pointcut expression so that only `@Idempotent` operations match: @@ -2314,6 +2359,7 @@ pointcut expression so that only `@Idempotent` operations match:
[[aop-choosing]]
== Choosing which AOP declaration style to use
Once you have decided that an aspect is the best approach for implementing a given
requirement, how do you decide between using Spring AOP or AspectJ, and between the
Aspect language (code) style, @AspectJ annotation style, or the Spring XML style? These
@ -2324,6 +2370,7 @@ development tools, and team familiarity with AOP. @@ -2324,6 +2370,7 @@ development tools, and team familiarity with AOP.
[[aop-spring-or-aspectj]]
=== Spring AOP or full AspectJ?
Use the simplest thing that can work. Spring AOP is simpler than using full AspectJ as
there is no requirement to introduce the AspectJ compiler / weaver into your development
and build processes. If you only need to advise the execution of operations on Spring
@ -2347,6 +2394,7 @@ an aspect weaving phase to your build script. @@ -2347,6 +2394,7 @@ an aspect weaving phase to your build script.
[[aop-ataspectj-or-xml]]
=== @AspectJ or XML for Spring AOP?
If you have chosen to use Spring AOP, then you have a choice of @AspectJ or XML style.
There are various tradeoffs to consider.
@ -2409,6 +2457,7 @@ that do more than simple "configuration" of enterprise services. @@ -2409,6 +2457,7 @@ that do more than simple "configuration" of enterprise services.
[[aop-mixing-styles]]
== Mixing aspect types
It is perfectly possible to mix @AspectJ style aspects using the autoproxying support,
schema-defined `<aop:aspect>` aspects, `<aop:advisor>` declared advisors and even
proxies and interceptors defined using the Spring 1.2 style in the same configuration.
@ -2420,6 +2469,7 @@ co-exist without any difficulty. @@ -2420,6 +2469,7 @@ co-exist without any difficulty.
[[aop-proxying]]
== 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).
@ -2479,6 +2529,7 @@ proxies __for all three of them__. @@ -2479,6 +2529,7 @@ proxies __for all three of them__.
[[aop-understanding-aop-proxies]]
=== Understanding AOP proxies
Spring AOP is __proxy-based__. It is vitally important that you grasp the semantics of
what that last statement actually means before you write your own aspects or use any of
the Spring AOP-based aspects supplied with the Spring Framework.
@ -2506,7 +2557,7 @@ code snippet. @@ -2506,7 +2557,7 @@ code snippet.
If you invoke a method on an object reference, the method is invoked __directly__ on
that object reference, as can be seen below.
image::images/aop-proxy-plain-pojo-call.png[width=400]
image::images/aop-proxy-plain-pojo-call.png[]
[source,java,indent=0]
[subs="verbatim,quotes"]
@ -2526,7 +2577,7 @@ image::images/aop-proxy-plain-pojo-call.png[width=400] @@ -2526,7 +2577,7 @@ image::images/aop-proxy-plain-pojo-call.png[width=400]
Things change slightly when the reference that client code has is a proxy. Consider the
following diagram and code snippet.
image::images/aop-proxy-call.png[width=400]
image::images/aop-proxy-call.png[]
[source,java,indent=0]
[subs="verbatim,quotes"]
@ -2613,6 +2664,7 @@ it is not a proxy-based AOP framework. @@ -2613,6 +2664,7 @@ it is not a proxy-based AOP framework.
[[aop-aspectj-programmatic]]
== Programmatic creation of @AspectJ Proxies
In addition to declaring aspects in your configuration using either `<aop:config>` or
`<aop:aspectj-autoproxy>`, it is also possible programmatically to create proxies that
advise target objects. For the full details of Spring's AOP API, see the next chapter.
@ -2646,6 +2698,7 @@ full information. @@ -2646,6 +2698,7 @@ full information.
[[aop-using-aspectj]]
== Using AspectJ with Spring applications
Everything we've covered so far in this chapter is pure Spring AOP. In this section,
we're going to look at how you can use the AspectJ compiler/weaver instead of, or in
addition to, Spring AOP if your needs go beyond the facilities offered by Spring AOP
@ -2663,6 +2716,7 @@ using AspectJ. @@ -2663,6 +2716,7 @@ using AspectJ.
[[aop-atconfigurable]]
=== Using AspectJ to dependency inject domain objects with Spring
The Spring container instantiates and configures beans defined in your application
context. It is also possible to ask a bean factory to configure a __pre-existing__
object given the name of a bean definition containing the configuration to be applied.
@ -2843,6 +2897,7 @@ that it has not been configured by Spring. @@ -2843,6 +2897,7 @@ that it has not been configured by Spring.
[[aop-configurable-container]]
==== Working with multiple application contexts
The `AnnotationBeanConfigurerAspect` used to implement the `@Configurable` support is an
AspectJ singleton aspect. The scope of a singleton aspect is the same as the scope of
`static` members, that is to say there is one aspect instance per classloader that
@ -2872,6 +2927,7 @@ not what you want. @@ -2872,6 +2927,7 @@ not what you want.
[[aop-ajlib-other]]
=== Other Spring aspects for AspectJ
In addition to the `@Configurable` aspect, `spring-aspects.jar` contains an AspectJ
aspect that can be used to drive Spring's transaction management for types and methods
annotated with the `@Transactional` annotation. This is primarily intended for users who
@ -2929,6 +2985,7 @@ fully-qualified class names: @@ -2929,6 +2985,7 @@ fully-qualified class names:
[[aop-aj-configure]]
=== Configuring AspectJ aspects using Spring IoC
When using AspectJ aspects with Spring applications, it is natural to both want and
expect to be able to configure such aspects using Spring. The AspectJ runtime itself is
responsible for aspect creation, and the means of configuring the AspectJ created
@ -2986,6 +3043,7 @@ declaration is just being used here, but the AspectJ runtime is __not__ involved @@ -2986,6 +3043,7 @@ declaration is just being used here, but the AspectJ runtime is __not__ involved
[[aop-aj-ltw]]
=== Load-time weaving with AspectJ in the Spring Framework
Load-time weaving (LTW) refers to the process of weaving AspectJ aspects into an
application's class files as they are being loaded into the Java virtual machine (JVM).
The focus of this section is on configuring and using LTW in the specific context of the
@ -3021,6 +3079,7 @@ https://github.com/spring-projects/spring-petclinic[Petclinic sample application @@ -3021,6 +3079,7 @@ https://github.com/spring-projects/spring-petclinic[Petclinic sample application
[[aop-aj-ltw-first-example]]
==== A first example
Let us 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, what we are going to do is switch on a simple profiling aspect that will enable us
@ -3030,8 +3089,8 @@ profiling tool to that specific area immediately afterwards. @@ -3030,8 +3089,8 @@ profiling tool to that specific area immediately afterwards.
[NOTE]
====
The example presented here uses XML style configuration, it is also possible to
configure and use @AspectJ with <<beans-java,Java Configuration>>. Specifically the
`@EnableLoadTimeWeaving` annotation can be used as an alternative to
configure and use @AspectJ with <<beans-java,Java Configuration>>.
Specifically the `@EnableLoadTimeWeaving` annotation can be used as an alternative to
`<context:load-time-weaver/>` (see <<aop-aj-ltw-spring,below>> for details).
====
@ -3229,6 +3288,7 @@ into UAT or production. @@ -3229,6 +3288,7 @@ into UAT or production.
[[aop-aj-ltw-the-aspects]]
==== Aspects
The aspects that you use in LTW have to be AspectJ aspects. They can be written in
either the AspectJ language itself or you can write your aspects in the @AspectJ-style.
It means that your aspects are then both valid AspectJ __and__ Spring AOP aspects.
@ -3253,6 +3313,7 @@ directing you there.) @@ -3253,6 +3313,7 @@ directing you there.)
[[aop-aj-ltw-libraries]]
==== Required libraries (JARS)
At a minimum you will need the following libraries to use the Spring Framework's support
for AspectJ LTW:
@ -3267,6 +3328,7 @@ instrumentation>>, you will also need: @@ -3267,6 +3328,7 @@ instrumentation>>, you will also need:
[[aop-aj-ltw-spring]]
==== Spring configuration
The key component in Spring's LTW support is the `LoadTimeWeaver` interface (in the
`org.springframework.instrument.classloading` package), and the numerous implementations
of it that ship with the Spring distribution. A `LoadTimeWeaver` is responsible for
@ -3276,7 +3338,6 @@ happens to be the LTW of aspects. @@ -3276,7 +3338,6 @@ happens to be the LTW of aspects.
[TIP]
====
If you are unfamiliar with the idea of runtime class file transformation, you are
encouraged to read the javadoc API documentation for the `java.lang.instrument` package
before continuing. This is not a huge chore because there is - rather annoyingly -
@ -3442,12 +3503,14 @@ It accepts one of three possible values, summarized below, with the default valu @@ -3442,12 +3503,14 @@ It accepts one of three possible values, summarized below, with the default valu
[[aop-aj-ltw-environments]]
==== Environment-specific configuration
This last section contains any additional settings and configuration that you will need
when using Spring's LTW support in environments such as application servers and web
containers.
[[aop-aj-ltw-environment-tomcat]]
===== Tomcat
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
@ -3498,6 +3561,7 @@ deployed web applications, no matter what ClassLoader they happen to run on. @@ -3498,6 +3561,7 @@ deployed web applications, no matter what ClassLoader they happen to run on.
[[aop-aj-ltw-environments-weblogic-oc4j-resin-glassfish-jboss]]
===== WebLogic, WebSphere, Resin, GlassFish, JBoss
Recent versions of WebLogic Server (version 10 and above), IBM WebSphere Application
Server (version 7 and above), Resin (3.1 and above) and JBoss (6.x or above) provide a
ClassLoader that is capable of local instrumentation. Spring's native LTW leverages such
@ -3521,6 +3585,7 @@ to your artifact a file named `WEB-INF/jboss-scanning.xml` with the following co @@ -3521,6 +3585,7 @@ to your artifact a file named `WEB-INF/jboss-scanning.xml` with the following co
[[aop-aj-ltw-environment-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
@ -3549,6 +3614,7 @@ support) a dedicated LTW. @@ -3549,6 +3614,7 @@ support) a dedicated LTW.
[[aop-resources]]
== Further Resources
More information on AspectJ can be found on the http://www.eclipse.org/aspectj[AspectJ
website].
@ -3558,4 +3624,3 @@ comprehensive introduction and reference for the AspectJ language. @@ -3558,4 +3624,3 @@ comprehensive introduction and reference for the AspectJ language.
The book __AspectJ in Action, Second Edition__ by Ramnivas Laddad (Manning, 2009) comes highly
recommended; the focus of the book is on AspectJ, but a lot of general AOP themes are
explored (in some depth).

143
src/asciidoc/core-beans.adoc

@ -2,6 +2,8 @@ @@ -2,6 +2,8 @@
= The IoC container
[[beans-introduction]]
== Introduction to the Spring IoC container and beans
@ -2763,6 +2765,9 @@ constructor/setter argument or autowired field) as `ObjectFactory<MyTargetBean>` @@ -2763,6 +2765,9 @@ constructor/setter argument or autowired field) as `ObjectFactory<MyTargetBean>`
allowing for a `getObject()` call to retrieve the current instance on demand every
time it is needed - without holding on to the instance or storing it separately.
As an extended variant, you may declare `ObjectProvider<MyTargetBean>` which delivers
several additional access variants, including `getIfAvailable` and `getIfUnique`.
The JSR-330 variant of this is called `Provider`, used with a `Provider<MyTargetBean>`
declaration and a corresponding `get()` call for every retrieval attempt.
See <<beans-standard-annotations,here>> for more details on JSR-330 overall.
@ -4552,21 +4557,6 @@ through Java 8's `java.util.Optional`: @@ -4552,21 +4557,6 @@ through Java 8's `java.util.Optional`:
}
----
As of Spring Framework 5.0, you may also use an `@Nullable` annotation (of any kind
in any package, e.g. `javax.annotation.Nullable` from JSR-305):
[source,java,indent=0]
[subs="verbatim,quotes"]
----
public class SimpleMovieLister {
@Autowired
public void setMovieFinder(@Nullable MovieFinder movieFinder) {
...
}
}
----
You can also use `@Autowired` for interfaces that are well-known resolvable
dependencies: `BeanFactory`, `ApplicationContext`, `Environment`, `ResourceLoader`,
`ApplicationEventPublisher`, and `MessageSource`. These interfaces and their extended
@ -5645,7 +5635,7 @@ support for autowiring of `@Bean` methods: @@ -5645,7 +5635,7 @@ support for autowiring of `@Bean` methods:
}
----
The example autowires the `String` method parameter `country` to the value of the `Age`
The example autowires the `String` method parameter `country` to the value of the `age`
property on another bean named `privateInstance`. A Spring Expression Language element
defines the value of the property through the notation `#{ <expression> }`. For `@Value`
annotations, an expression resolver is preconfigured to look for bean names when
@ -8524,23 +8514,23 @@ parameter at all, the event type(s) can also be specified on the annotation itse @@ -8524,23 +8514,23 @@ parameter at all, the event type(s) can also be specified on the annotation itse
It is also possible to add additional runtime filtering via the `condition` attribute of the
annotation that defines a <<expressions,`SpEL` expression>> that should match to actually invoke
the method for a particular event.
annotation that defines a <<expressions,`SpEL` expression>> that should match to actually
invoke the method for a particular event.
For instance, our notifier can be rewritten to be only invoked if the `test` attribute of the
event is equal to `foo`:
For instance, our notifier can be rewritten to be only invoked if the `content` attribute
of the event is equal to `foo`:
[source,java,indent=0]
[subs="verbatim,quotes"]
----
@EventListener(condition = "#blEvent.test == 'foo'")
@EventListener(condition = "#blEvent.content == 'foo'")
public void processBlackListEvent(BlackListEvent blEvent) {
// notify appropriate parties via notificationAddress...
}
----
Each `SpEL` expression evaluates again a dedicated context. The next table lists the items made
available to the context so one can use them for conditional event processing:
Each `SpEL` expression evaluates against a dedicated context. The next table lists the
items made available to the context so one can use them for conditional event processing:
[[context-functionality-events-annotation-tbl]]
.Event SpEL available metadata
@ -8661,8 +8651,7 @@ environment provides: @@ -8661,8 +8651,7 @@ environment provides:
[source,java,indent=0]
[subs="verbatim,quotes"]
----
public class EntityCreatedEvent<T>
extends ApplicationEvent implements ResolvableTypeProvider {
public class EntityCreatedEvent<T> extends ApplicationEvent implements ResolvableTypeProvider {
public EntityCreatedEvent(T entity) {
super(entity);
@ -8799,36 +8788,53 @@ be used by other application modules on the same machine. @@ -8799,36 +8788,53 @@ be used by other application modules on the same machine.
[[beans-beanfactory]]
== The BeanFactory
The `BeanFactory` provides the underlying basis for Spring's IoC functionality but it is
only used directly in integration with other third-party frameworks and is now largely
historical in nature for most users of Spring. The `BeanFactory` and related interfaces,
such as `BeanFactoryAware`, `InitializingBean`, `DisposableBean`, are still present in
Spring for the purposes of backward compatibility with the large number of third-party
frameworks that integrate with Spring. Often third-party components that can not use
more modern equivalents such as `@PostConstruct` or `@PreDestroy` in order to avoid a
dependency on JSR-250.
The `BeanFactory` API provides the underlying basis for Spring's IoC functionality.
Its specific contracts are mostly used in integration with other parts of Spring and
related third-party frameworks, and its `DefaultListableBeanFactory` implementation
is a key delegate within the higher-level `GenericApplicationContext` container.
`BeanFactory` and related interfaces such as `BeanFactoryAware`, `InitializingBean`,
`DisposableBean` are important integration points for other framework components:
not requiring any annotations or even reflection, they allow for very efficient
interaction between the container and its components. Application-level beans may
use the same callback interfaces but will typically prefer declarative dependency
injection instead, either via annotations or through programmatic configuration.
This section provides additional background into the differences between the
`BeanFactory` and `ApplicationContext` and how one might access the IoC container
directly through a classic singleton lookup.
Note that the core `BeanFactory` API level and its `DefaultListableBeanFactory`
implementation do not make assumptions about the configuration format or any
component annotations to be used. All of these flavors come in through extensions
such as `XmlBeanDefinitionReader` and `AutowiredAnnotationBeanPostProcessor`,
operating on shared `BeanDefinition` objects as a core metadata representation.
This is the essence of what makes Spring's container so flexible and extensible.
The following section explains the differences between the `BeanFactory` and
`ApplicationContext` container levels and the implications on bootstrapping.
[[context-introduction-ctx-vs-beanfactory]]
=== BeanFactory or ApplicationContext?
Use an `ApplicationContext` unless you have a good reason for not doing so.
Because the `ApplicationContext` includes all functionality of the `BeanFactory`, it is
generally recommended over the `BeanFactory`, except for a few situations such as in
embedded applications running on resource-constrained devices where memory consumption
might be critical and a few extra kilobytes might make a difference. However, for
most typical enterprise applications and systems, the `ApplicationContext` is what you
will want to use. Spring makes __heavy__ use of the <<beans-factory-extension-bpp,
`BeanPostProcessor` extension point>> (to effect proxying and so on). If you use only a
plain `BeanFactory`, a fair amount of support such as transactions and AOP will not take
effect, at least not without some extra steps on your part. This situation could be
confusing because nothing is actually wrong with the configuration.
Use an `ApplicationContext` unless you have a good reason for not doing so, with
`GenericApplicationContext` and its subclass `AnnotationConfigApplicationContext`
as the common implementations for custom bootstrapping. These are the primary entry
points to Spring's core container for all common purposes: loading of configuration
files, triggering a classpath scan, programmatically registering bean definitions
and annotated classes.
Because an `ApplicationContext` includes all functionality of a `BeanFactory`, it is
generally recommended over a plain `BeanFactory`, except for a scenarios where full
control over bean processing is needed. Within an `ApplicationContext` such as the
`GenericApplicationContext` implementation, several kinds of beans will be detected
by convention (i.e. by bean name or by bean type), in particular post-processors,
whereas 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.
If you use only a plain `DefaultListableBeanFactory`, such post-processors will not
get detected and activated by default. This situation could be confusing because
nothing is actually wrong with your bean configuration; it is rather the container
which needs to be fully bootstrapped through additional setup in such a scenario.
The following table lists features provided by the `BeanFactory` and
`ApplicationContext` interfaces and implementations.
@ -8836,12 +8842,16 @@ The following table lists features provided by the `BeanFactory` and @@ -8836,12 +8842,16 @@ The following table lists features provided by the `BeanFactory` and
[[context-introduction-ctx-vs-beanfactory-feature-matrix]]
.Feature Matrix
|===
| Feature| `BeanFactory`| `ApplicationContext`
| Feature | `BeanFactory` | `ApplicationContext`
| Bean instantiation/wiring
| Yes
| Yes
| Integrated lifecycle management
| No
| Yes
| Automatic `BeanPostProcessor` registration
| No
| Yes
@ -8850,17 +8860,17 @@ The following table lists features provided by the `BeanFactory` and @@ -8850,17 +8860,17 @@ The following table lists features provided by the `BeanFactory` and
| No
| Yes
| Convenient `MessageSource` access (for i18n)
| Convenient `MessageSource` access (for internalization)
| No
| Yes
| `ApplicationEvent` publication
| Built-in `ApplicationEvent` publication mechanism
| No
| Yes
|===
To explicitly register a bean post-processor with a `BeanFactory` implementation,
you need to write code like this:
To explicitly register a bean post-processor with a `DefaultListableBeanFactory`,
you need to programmatically call `addBeanPostProcessor`:
[source,java,indent=0]
[subs="verbatim,quotes"]
@ -8869,14 +8879,14 @@ you need to write code like this: @@ -8869,14 +8879,14 @@ you need to write code like this:
// populate the factory with bean definitions
// now register any needed BeanPostProcessor instances
MyBeanPostProcessor postProcessor = new MyBeanPostProcessor();
factory.addBeanPostProcessor(postProcessor);
factory.addBeanPostProcessor(new AutowiredAnnotationBeanPostProcessor());
factory.addBeanPostProcessor(new MyBeanPostProcessor());
// now start using the factory
----
To explicitly register a `BeanFactoryPostProcessor` when using a `BeanFactory`
implementation, you must write code like this:
To apply a `BeanFactoryPostProcessor` to a plain `DefaultListableBeanFactory`,
you need to call its `postProcessBeanFactory` method:
[source,java,indent=0]
[subs="verbatim,quotes"]
@ -8893,11 +8903,20 @@ implementation, you must write code like this: @@ -8893,11 +8903,20 @@ implementation, you must write code like this:
cfg.postProcessBeanFactory(factory);
----
In both cases, the explicit registration step is inconvenient, which is one reason why
the various `ApplicationContext` implementations are preferred above plain `BeanFactory`
implementations in the vast majority of Spring-backed applications, especially when
using ``BeanFactoryPostProcessor``s and ``BeanPostProcessor``s. These mechanisms implement
important functionality such as property placeholder replacement and AOP.
In both cases, the explicit registration steps are inconvenient, which is
why the various `ApplicationContext` variants are preferred over a plain
`DefaultListableBeanFactory` in Spring-backed applications, especially when
relying on ``BeanFactoryPostProcessor``s and ``BeanPostProcessor``s for extended
container functionality in a typical enterprise setup.
[NOTE]
====
An `AnnotationConfigApplicationContext` has all common annotation post-processors
registered out of the box and may bring in additional processors underneath the
covers through configuration annotations such as `@EnableTransactionManagement`.
At the abstraction level of Spring's annotation-based configuration model,
the notion of bean post-processors becomes a mere internal container detail.
====

Loading…
Cancel
Save