Revise BeanFactory vs ApplicationContext section in reference docs
Issue: SPR-17095
This commit is contained in:
parent
e366b20037
commit
8277ea5794
|
|
@ -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 <<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
|
||||
|
|
@ -8742,8 +8742,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);
|
||||
|
|
@ -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.
|
||||
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 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.
|
||||
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.
|
||||
|
|
@ -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.
|
||||
====
|
||||
|
|
|
|||
Loading…
Reference in New Issue