diff --git a/src/docs/asciidoc/core/core-beans.adoc b/src/docs/asciidoc/core/core-beans.adoc index 6abc689a70..89c2a8f5df 100644 --- a/src/docs/asciidoc/core/core-beans.adoc +++ b/src/docs/asciidoc/core/core-beans.adoc @@ -8605,23 +8605,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 @@ -8742,8 +8742,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); @@ -8880,36 +8879,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. -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. +`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. + +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, and as of 5.0 also registering functional bean definitions. + +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. @@ -8917,12 +8933,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 @@ -8931,17 +8951,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"] @@ -8950,14 +8970,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"] @@ -8974,8 +8994,17 @@ 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. +====