diff --git a/src/asciidoc/core-aop.adoc b/src/asciidoc/core-aop.adoc index 1d6c4ad25db..b0063a7bbf3 100644 --- a/src/asciidoc/core-aop.adoc +++ b/src/asciidoc/core-aop.adoc @@ -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 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 <> or the <>. 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 <>. +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 is used in the Spring Framework to... @@ -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. 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). [[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. [[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. [[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-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 [[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: [[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: ---- -This assumes that you are using schema support as described in <>. See -<> for how to import the tags in the `aop` namespace. +This assumes that you are using schema support as described in <>. +See <> for how to import the tags in the `aop` namespace. @@ -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. [[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. [[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__. [[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 <>. [[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. [[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. [[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 [[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: [[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. [[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). [[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. [[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. [[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. [[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: [[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. [[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. [[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). [[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 [[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: [[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 [[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: [[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 of advice parameters. To use the aop namespace tags described in this section, you need to import the -`spring-aop` schema as described in <>. See <> -for how to import the tags in the `aop` namespace. +`spring-aop` schema as described in <>. +See <> for how to import the tags in the `aop` namespace. Within your Spring configurations, all aspect and advisor elements must be placed within an `` element (you can have more than one `` element in an @@ -1573,6 +1604,7 @@ just the `` 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: ---- -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 element, enabling the pointcut definition to be shared across several aspects and advisors. @@ -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"] ---- @@ -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 `` using the element. @@ -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 `` in the same way as before advice. For example: @@ -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 `` using the after-throwing element: @@ -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: [[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 [[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 <> for details. If you wish @@ -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 <>. 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. [[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: [[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. [[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. [[aop-schema-example]] === Example + Let's see how the concurrent locking failure retry example from <> looks when rewritten using the schema support. @@ -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. [[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. [[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. [[aop-mixing-styles]] == Mixing aspect types + It is perfectly possible to mix @AspectJ style aspects using the autoproxying support, schema-defined `` aspects, `` 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. [[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__. [[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. 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] 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. [[aop-aspectj-programmatic]] == Programmatic creation of @AspectJ Proxies + In addition to declaring aspects in your configuration using either `` or ``, 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. [[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. [[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. [[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. [[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: [[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 [[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 [[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. [NOTE] ==== The example presented here uses XML style configuration, it is also possible to -configure and use @AspectJ with <>. Specifically the -`@EnableLoadTimeWeaving` annotation can be used as an alternative to +configure and use @AspectJ with <>. +Specifically the `@EnableLoadTimeWeaving` annotation can be used as an alternative to `` (see <> for details). ==== @@ -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.) [[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: [[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. [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 [[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. [[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 [[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. [[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. 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). - diff --git a/src/asciidoc/core-beans.adoc b/src/asciidoc/core-beans.adoc index 99c351cf35a..c44b20a5c59 100644 --- a/src/asciidoc/core-beans.adoc +++ b/src/asciidoc/core-beans.adoc @@ -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` 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` which delivers +several additional access variants, including `getIfAvailable` and `getIfUnique`. + The JSR-330 variant of this is called `Provider`, used with a `Provider` declaration and a corresponding `get()` call for every retrieval attempt. See <> for more details on JSR-330 overall. @@ -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: } ---- -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 `#{ }`. 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 It is also possible to add additional runtime filtering via the `condition` attribute of the -annotation that defines a <> that should match to actually invoke -the method for a particular event. +annotation that defines a <> 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: [source,java,indent=0] [subs="verbatim,quotes"] ---- - public class EntityCreatedEvent - extends ApplicationEvent implements ResolvableTypeProvider { + public class EntityCreatedEvent extends ApplicationEvent implements ResolvableTypeProvider { public EntityCreatedEvent(T entity) { super(entity); @@ -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 <> (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 <> 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 [[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 | 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: // 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: 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. +====