diff --git a/src/asciidoc/appendix.adoc b/src/asciidoc/appendix.adoc index 466e1f88a00..72e916fde23 100644 --- a/src/asciidoc/appendix.adoc +++ b/src/asciidoc/appendix.adoc @@ -30,7 +30,7 @@ For the currently recommended usage patterns for Hibernate see <> [[orm-hibernate-template]] -===== the HibernateTemplate +===== The HibernateTemplate The basic programming model for templating looks as follows, for methods that can be part of any custom data access object or business service. There are no restrictions on diff --git a/src/asciidoc/core-beans.adoc b/src/asciidoc/core-beans.adoc index 860906ff315..6d126c503a9 100644 --- a/src/asciidoc/core-beans.adoc +++ b/src/asciidoc/core-beans.adoc @@ -82,6 +82,7 @@ image::images/container-magic.png[width=250] [[beans-factory-metadata]] === Configuration metadata + As the preceding diagram shows, the Spring IoC container consumes a form of __configuration metadata__; this configuration metadata represents how you as an application developer tell the Spring container to instantiate, configure, and assemble @@ -158,6 +159,7 @@ referring to collaborating objects is not shown in this example; see [[beans-factory-instantiation]] === Instantiating a container + Instantiating a Spring IoC container is straightforward. The location path or paths supplied to an `ApplicationContext` constructor are actually resource strings that allow the container to load configuration metadata from a variety of external resources such @@ -239,6 +241,7 @@ collaborating objects. For details of configuring an object's dependencies, see [[beans-factory-xml-import]] ==== Composing XML-based configuration metadata + It can be useful to have bean definitions span multiple XML files. Often each individual XML configuration file represents a logical layer or module in your architecture. @@ -291,6 +294,7 @@ system properties at runtime. [[beans-factory-client]] === Using the container + The `ApplicationContext` is the interface for an advanced factory capable of maintaining a registry of different beans and their dependencies. Using the method `T getBean(String name, Class requiredType)` you can retrieve instances of your beans. @@ -398,6 +402,7 @@ lead to concurrent access exceptions and/or inconsistent state in the bean conta [[beans-beanname]] === Naming beans + Every bean has one or more identifiers. These identifiers must be unique within the container that hosts the bean. A bean usually has only one identifier, but if it requires more than one, the extra ones can be considered aliases. @@ -435,6 +440,7 @@ by name. [[beans-beanname-alias]] ==== Aliasing a bean outside the bean definition + In a bean definition itself, you can supply more than one name for the bean, by using a combination of up to one name specified by the `id` attribute, and any number of other names in the `name` attribute. These names can be equivalent aliases to the same bean, @@ -483,6 +489,7 @@ see <> for details. [[beans-factory-class]] === Instantiating beans + A bean definition essentially is a recipe for creating one or more objects. The container looks at the recipe for a named bean when asked, and uses the configuration metadata encapsulated by that bean definition to create (or acquire) an actual object. @@ -521,6 +528,7 @@ the outer class name. [[beans-factory-class-ctor]] ==== Instantiation with a constructor + When you create a bean by the constructor approach, all normal classes are usable by and compatible with Spring. That is, the class being developed does not need to implement any specific interfaces or to be coded in a specific fashion. Simply specifying the bean @@ -552,6 +560,7 @@ and setting object instance properties after the object is constructed, see [[beans-factory-class-static-factory-method]] ==== Instantiation with a static factory method + When defining a bean that you create with a static factory method, you use the `class` attribute to specify the class containing the `static` factory method and an attribute named `factory-method` to specify the name of the factory method itself. You should be @@ -592,6 +601,7 @@ see <>, instantiation with an instance factory method invokes a non-static method of an existing bean from the container to create a new bean. To use this @@ -695,7 +705,8 @@ application where objects collaborate to achieve a goal. [[beans-factory-collaborators]] -=== Dependency injection +=== Dependency Injection + __Dependency injection__ (DI) is a process whereby objects define their dependencies, that is, the other objects they work with, only through constructor arguments, arguments to a factory method, or properties that are set on the object instance after it is @@ -717,6 +728,7 @@ dependency injection>> and <` or `` definition element. Here you set the value of the specified property of a bean to be a reference to another bean (a collaborator) managed by the container. The referenced bean @@ -1361,6 +1379,7 @@ your existing `ref local` references to `ref bean` when upgrading to the 4.0 sch [[beans-inner-beans]] ==== Inner beans + A `` element inside the `` or `` elements defines a so-called __inner bean__. @@ -1386,6 +1405,7 @@ beans into collaborating beans other than into the enclosing bean. [[beans-collection-elements]] ==== Collections + In the ``, ``, ``, and `` elements, you set the properties and arguments of the Java `Collection` types `List`, `Set`, `Map`, and `Properties`, respectively. @@ -1437,6 +1457,7 @@ following elements:__ [[beans-collection-elements-merging]] ===== Collection merging + The Spring container also supports the __merging__ of collections. An application developer can define a parent-style ``, ``, `` or `` element, and have child-style ``, ``, `` or `` elements inherit and @@ -1503,6 +1524,7 @@ uses internally. [[beans-collection-merge-limitations]] ===== Limitations of collection merging + You cannot merge different collection types (such as a `Map` and a `List`), and if you do attempt to do so an appropriate `Exception` is thrown. The `merge` attribute must be specified on the lower, inherited, child definition; specifying the `merge` attribute on @@ -1510,6 +1532,7 @@ a parent collection definition is redundant and will not result in the desired m [[beans-collection-elements-strongly-typed]] ===== Strongly-typed collection + With the introduction of generic types in Java 5, you can use strongly typed collections. That is, it is possible to declare a `Collection` type such that it can only contain `String` elements (for example). If you are using Spring to dependency-inject a @@ -1555,6 +1578,7 @@ various value elements as being of type `Float`, and the string values `9.99, 2. [[beans-null-element]] ==== Null and empty string values + Spring treats empty arguments for properties and the like as empty `Strings`. The following XML-based configuration metadata snippet sets the email property to the empty `String` value (""). @@ -1598,6 +1622,7 @@ The above configuration is equivalent to the following Java code: [[beans-p-namespace]] ==== XML shortcut with the p-namespace + The p-namespace enables you to use the `bean` element's attributes, instead of nested `` elements, to describe your property values and/or collaborating beans. @@ -1680,6 +1705,7 @@ three approaches at the same time. [[beans-c-namespace]] ==== XML shortcut with the c-namespace + Similar to the <>, the __c-namespace__, newly introduced in Spring 3.1, allows usage of inlined attributes for configuring the constructor arguments rather then nested `constructor-arg` elements. @@ -1741,6 +1767,7 @@ through-out your configuration. [[beans-compound-property-names]] ==== Compound property names + You can use compound or nested property names when you set bean properties, as long as all components of the path except the final property name are not `null`. Consider the following bean definition. @@ -1807,6 +1834,7 @@ itself being destroyed. Thus `depends-on` can also control shutdown order. [[beans-factory-lazy-init]] === Lazy-initialized beans + By default, `ApplicationContext` implementations eagerly create and configure all <> beans as part of the initialization process. Generally, this pre-instantiation is desirable, because errors in the @@ -1850,6 +1878,7 @@ You can also control lazy-initialization at the container level by using the [[beans-factory-autowire]] === Autowiring collaborators + The Spring container can __autowire__ relationships between collaborating beans. You can allow Spring to resolve collaborators (other beans) automatically for your bean by inspecting the contents of the `ApplicationContext`. Autowiring has the following @@ -1913,6 +1942,7 @@ autowiring completes. [[beans-autowired-exceptions]] ==== Limitations and disadvantages of autowiring + Autowiring works best when it is used consistently across a project. If autowiring is not used in general, it might be confusing to developers to use it to wire only one or two bean definitions. @@ -1948,6 +1978,7 @@ In the latter scenario, you have several options: [[beans-factory-autowire-candidate]] ==== Excluding a bean from autowiring + On a per-bean basis, you can exclude a bean from autowiring. In Spring's XML format, set the `autowire-candidate` attribute of the `` element to `false`; the container makes that specific bean definition unavailable to the autowiring infrastructure @@ -1968,8 +1999,10 @@ using autowiring. Rather, the bean itself is not a candidate for autowiring othe + [[beans-factory-method-injection]] === Method injection + In most application scenarios, most beans in the container are <>. When a singleton bean needs to collaborate with another singleton bean, or a non-singleton bean needs to collaborate @@ -2033,6 +2066,7 @@ https://spring.io/blog/2004/08/06/method-injection/[this blog entry]. [[beans-factory-lookup-method-injection]] ==== Lookup method injection + Lookup method injection is the ability of the container to override methods on __container managed beans__, to return the lookup result for another named bean in the container. The lookup typically involves a prototype bean as in the scenario described @@ -2128,6 +2162,7 @@ these classes for additional information. [[beans-factory-arbitrary-method-replacement]] ==== Arbitrary method replacement + A less useful form of method injection than lookup method injection is the ability to replace arbitrary methods in a managed bean with another method implementation. Users may safely skip the rest of this section until the functionality is actually needed. @@ -2272,6 +2307,7 @@ For instructions on how to register this or any other custom scope, see [[beans-factory-scopes-singleton]] === The singleton scope + Only one __shared__ instance of a singleton bean is managed, and all requests for beans with an id or ids matching that bean definition result in that one specific bean instance being returned by the Spring container. @@ -2306,6 +2342,7 @@ in Spring__. To define a bean as a singleton in XML, you would write, for exampl [[beans-factory-scopes-prototype]] === The prototype scope + The non-singleton, prototype scope of bean deployment results in the __creation of a new bean instance__ every time a request for that specific bean is made. That is, the bean is injected into another bean or you request it through a `getBean()` method call on the @@ -2347,6 +2384,7 @@ container, see <>.) [[beans-factory-scopes-sing-prot-interaction]] === Singleton beans with prototype-bean dependencies + When you use singleton-scoped beans with dependencies on prototype beans, be aware that __dependencies are resolved at instantiation time__. Thus if you dependency-inject a prototype-scoped bean into a singleton-scoped bean, a new prototype bean is instantiated @@ -2364,6 +2402,7 @@ runtime more than once, see <> [[beans-factory-scopes-other]] === Request, session, and global session scopes + The `request`, `session`, and `global session` scopes are __only__ available if you use a web-aware Spring `ApplicationContext` implementation (such as `XmlWebApplicationContext`). If you use these scopes with regular Spring IoC containers @@ -2373,22 +2412,23 @@ complaining about an unknown bean scope. [[beans-factory-scopes-other-web-configuration]] ==== Initial web configuration + To support the scoping of beans at the `request`, `session`, and `global session` levels (web-scoped beans), some minor initial configuration is required before you define your -beans. (This initial setup is __not__ required for the standard scopes, singleton and -prototype.) +beans. (This initial setup is __not__ required for the standard scopes, `singleton` and +`prototype`.) -How you accomplish this initial setup depends on your particular Servlet environment.. +How you accomplish this initial setup depends on your particular Servlet environment. If you access scoped beans within Spring Web MVC, in effect, within a request that is -processed by the Spring `DispatcherServlet`, or `DispatcherPortlet`, then no special +processed by the Spring `DispatcherServlet` or `DispatcherPortlet`, then no special setup is necessary: `DispatcherServlet` and `DispatcherPortlet` already expose all relevant state. If you use a Servlet 2.5 web container, with requests processed outside of Spring's -DispatcherServlet (for example, when using JSF or Struts), you need to register the +`DispatcherServlet` (for example, when using JSF or Struts), you need to register the `org.springframework.web.context.request.RequestContextListener` `ServletRequestListener`. -For Servlet 3.0+, this can done programmatically via the `WebApplicationInitializer` +For Servlet 3.0+, this can be done programmatically via the `WebApplicationInitializer` interface. Alternatively, or for older containers, add the following declaration to your web application's `web.xml` file: @@ -2406,7 +2446,7 @@ your web application's `web.xml` file: ---- -Alternatively, if there are issues with your listener setup, consider the provided +Alternatively, if there are issues with your listener setup, consider using Spring's `RequestContextFilter`. The filter mapping depends on the surrounding web application configuration, so you have to change it as appropriate. @@ -2427,7 +2467,7 @@ application configuration, so you have to change it as appropriate. ---- -`DispatcherServlet`, `RequestContextListener` and `RequestContextFilter` all do exactly +`DispatcherServlet`, `RequestContextListener`, and `RequestContextFilter` all do exactly the same thing, namely bind the HTTP request object to the `Thread` that is servicing that request. This makes beans that are request- and session-scoped available further down the call chain. @@ -2435,6 +2475,7 @@ down the call chain. [[beans-factory-scopes-request]] ==== Request scope + Consider the following bean definition: [source,xml,indent=0] @@ -2454,6 +2495,7 @@ bean that is scoped to the request is discarded. [[beans-factory-scopes-session]] ==== Session scope + Consider the following bean definition: [source,xml,indent=0] @@ -2475,6 +2517,7 @@ HTTP `Session` is eventually discarded, the bean that is scoped to that particul [[beans-factory-scopes-global-session]] ==== Global session scope + Consider the following bean definition: [source,xml,indent=0] @@ -2497,6 +2540,7 @@ error is raised. [[beans-factory-scopes-application]] ==== Application scope + Consider the following bean definition: [source,xml,indent=0] @@ -2516,6 +2560,7 @@ and it is actually exposed and therefore visible as a `ServletContext` attribute [[beans-factory-scopes-other-injection]] ==== Scoped beans as dependencies + The Spring IoC container manages not only the instantiation of your objects (beans), but also the wiring up of collaborators (or dependencies). If you want to inject (for example) an HTTP request scoped bean into another bean, you must inject an AOP proxy in @@ -2616,6 +2661,7 @@ Thus you need the following, correct and complete, configuration when injecting [[beans-factory-scopes-other-injection-proxies]] ===== Choosing the type of proxy to create + By default, when the Spring container creates a proxy for a bean that is marked up with the `` element, __a CGLIB-based class proxy is created__. @@ -2653,6 +2699,7 @@ see <>. [[beans-factory-scopes-custom]] === Custom scopes + The bean scoping mechanism is extensible; You can define your own scopes, or even redefine existing scopes, although the latter is considered bad practice and you __cannot__ override the built-in `singleton` and `prototype` scopes. @@ -2660,6 +2707,7 @@ and you __cannot__ override the built-in `singleton` and `prototype` scopes. [[beans-factory-scopes-custom-creating]] ==== Creating a custom scope + To integrate your custom scope(s) into the Spring container, you need to implement the `org.springframework.beans.factory.config.Scope` interface, which is described in this section. For an idea of how to implement your own scopes, see the `Scope` @@ -2715,6 +2763,7 @@ identifier can be the session identifier. [[beans-factory-scopes-custom-using]] ==== Using a custom scope + After you write and test one or more custom `Scope` implementations, you need to make the Spring container aware of your new scope(s). The following method is the central method to register a new `Scope` with the Spring container: @@ -2812,6 +2861,7 @@ bean itself that is scoped, not the object returned from `getObject()`. [[beans-factory-lifecycle]] === Lifecycle callbacks + To interact with the container's management of the bean lifecycle, you can implement the Spring `InitializingBean` and `DisposableBean` interfaces. The container calls `afterPropertiesSet()` for the former and `destroy()` for the latter to allow the bean @@ -2844,6 +2894,7 @@ The lifecycle callback interfaces are described in this section. [[beans-factory-lifecycle-initializingbean]] ==== Initialization callbacks + The `org.springframework.beans.factory.InitializingBean` interface allows a bean to perform initialization work after all necessary properties on the bean have been set by the container. The `InitializingBean` interface specifies a single method: @@ -2905,6 +2956,7 @@ but does not couple the code to Spring. [[beans-factory-lifecycle-disposablebean]] ==== Destruction callbacks + Implementing the `org.springframework.beans.factory.DisposableBean` interface allows a bean to get a callback when the container containing it is destroyed. The `DisposableBean` interface specifies a single method: @@ -2977,6 +3029,7 @@ default behavior with Java config. [[beans-factory-lifecycle-default-init-destroy-methods]] ==== Default initialization and destroy methods + When you write initialization and destroy method callbacks that do not use the Spring-specific `InitializingBean` and `DisposableBean` callback interfaces, you typically write methods with names such as `init()`, `initialize()`, `dispose()`, and so @@ -3056,6 +3109,7 @@ interacts directly to the raw target bean. [[beans-factory-lifecycle-combined-effects]] ==== Combining lifecycle mechanisms + As of Spring 2.5, you have three options for controlling bean lifecycle behavior: the <> and <> callback interfaces; custom @@ -3088,6 +3142,7 @@ Destroy methods are called in the same order: [[beans-factory-lifecycle-processor]] ==== Startup and shutdown callbacks + The `Lifecycle` interface defines the essential methods for any object that has its own lifecycle requirements (e.g. starts and stops some background process): @@ -3215,6 +3270,7 @@ above. [[beans-factory-shutdown]] ==== Shutting down the Spring IoC container gracefully in non-web applications + [NOTE] ==== This section applies only to non-web applications. Spring's web-based @@ -4292,6 +4348,7 @@ any). These types must be 'wired up' explicitly via XML or using a Spring `@Bean [[beans-autowired-annotation-primary]] === Fine-tuning annotation-based autowiring with @Primary + Because autowiring by type may lead to multiple candidates, it is often necessary to have more control over the selection process. One way to accomplish this is with Spring's `@Primary` annotation. `@Primary` indicates that a particular bean should be given @@ -4369,6 +4426,7 @@ The corresponding bean definitions appear as follows. [[beans-autowired-annotation-qualifiers]] === Fine-tuning annotation-based autowiring with qualifiers + `@Primary` is an effective way to use autowiring by type with several instances when one primary candidate can be determined. When more control over the selection process is required, Spring's `@Qualifier` annotation can be used. You can associate qualifier values @@ -4722,6 +4780,7 @@ the following example. [[beans-generics-as-qualifiers]] === Using generics as autowiring qualifiers + In addition to the `@Qualifier` annotation, it is also possible to use Java generic types as an implicit form of qualification. For example, suppose you have the following configuration: @@ -4939,18 +4998,18 @@ For details about the effects of combining various lifecycle mechanisms, see [[beans-classpath-scanning]] == Classpath scanning and managed components -Most examples in this chapter use XML to specify the configuration metadata that -produces each `BeanDefinition` within the Spring container. The previous section +Most examples in this chapter use XML to specify the configuration metadata that produces +each `BeanDefinition` within the Spring container. The previous section (<>) demonstrates how to provide a lot of the configuration metadata through source-level annotations. Even in those examples, however, the "base" -bean definitions are explicitly defined in the XML file, while the annotations only -drive the dependency injection. This section describes an option for implicitly -detecting the __candidate components__ by scanning the classpath. Candidate components -are classes that match against a filter criteria and have a corresponding bean -definition registered with the container. This removes the need to use XML to perform -bean registration, instead you can use annotations (for example @Component), AspectJ -type expressions, or your own custom filter criteria to select which classes will have -bean definitions registered with the container. +bean definitions are explicitly defined in the XML file, while the annotations only drive +the dependency injection. This section describes an option for implicitly detecting the +__candidate components__ by scanning the classpath. Candidate components are classes that +match against a filter criteria and have a corresponding bean definition registered with +the container. This removes the need to use XML to perform bean registration; instead you +can use annotations (for example `@Component`), AspectJ type expressions, or your own +custom filter criteria to select which classes will have bean definitions registered with +the container. [NOTE] ==== @@ -4966,7 +5025,7 @@ than using the traditional XML files. Take a look at the `@Configuration`, `@Bea === @Component and further stereotype annotations The `@Repository` annotation is a marker for any class that fulfills the role or -__stereotype__ (also known as Data Access Object or DAO) of a repository. Among the uses +__stereotype__ of a repository (also known as Data Access Object or DAO). Among the uses of this marker is the automatic translation of exceptions as described in <>. @@ -4988,15 +5047,16 @@ supported as a marker for automatic exception translation in your persistence la [[beans-meta-annotations]] === Meta-annotations + Many of the annotations provided by Spring can be used as "meta-annotations" in -your own code. A meta-annotation is simply an annotation, that can be applied to another -annotation. For example, The `@Service` annotation mentioned above is meta-annotated with +your own code. A meta-annotation is simply an annotation that can be applied to another +annotation. For example, the `@Service` annotation mentioned above is meta-annotated with with `@Component`: [source,java,indent=0] [subs="verbatim,quotes"] ---- - @Target({ElementType.TYPE}) + @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented **@Component** // Spring will see this and treat @Service in the same way as @Component @@ -5011,11 +5071,11 @@ Meta-annotations can also be combined together to create __composed annotations_ example, the `@RestController` annotation from Spring MVC is __composed__ of `@Controller` and `@ResponseBody`. -With the exception of `value()`, meta-annotated types may redeclare attributes from the -source annotation to allow user customization. This can be particularly useful when you -want to only expose a subset of the source annotation attributes. For example, here is a -custom `@Scope` annotation that defines `session` scope, but still allows customization -of the `proxyMode`. +With the exception of the `value` attribute, composed annotations may redeclare +attributes from meta-annotations to allow user customization. This can be particularly +useful when you want to only expose a subset of the meta-annotation's attributes. For +example, here is a custom `@Scope` annotation that hardcodes the scope name to `session` +but still allows customization of the `proxyMode`. [source,java,indent=0] @@ -5037,6 +5097,7 @@ of the `proxyMode`. [[beans-scanning-autodetection]] === Automatically detecting classes and registering bean definitions + Spring can automatically detect stereotyped classes and register corresponding ++BeanDefinition++s with the `ApplicationContext`. For example, the following two classes are eligible for such autodetection: @@ -5140,6 +5201,7 @@ with a value of false. [[beans-scanning-filters]] === Using filters to customize scanning + By default, classes annotated with `@Component`, `@Repository`, `@Service`, `@Controller`, or a custom annotation that itself is annotated with `@Component` are the only detected candidate components. However, you can modify and extend this behavior @@ -5217,6 +5279,7 @@ will in effect disable automatic detection of classes annotated with `@Component [[beans-factorybeans-annotations]] === Defining bean metadata within components + Spring components can also contribute bean definition metadata to the container. You do this with the same `@Bean` annotation used to define bean metadata within `@Configuration` annotated classes. Here is a simple example: @@ -5347,6 +5410,7 @@ inheritance being possible through Java 8 default methods as of Spring 4.2. [[beans-scanning-name-generator]] === Naming autodetected components + When a component is autodetected as part of the scanning process, its bean name is generated by the `BeanNameGenerator` strategy known to that scanner. By default, any Spring stereotype annotation ( `@Component`, `@Repository`, `@Service`, and @@ -5412,6 +5476,7 @@ auto-generated names are adequate whenever the container is responsible for wiri [[beans-scanning-scope-resolver]] === Providing a scope for autodetected components + As with Spring-managed components in general, the default and most common scope for autodetected components is singleton. However, sometimes you need other scopes, which Spring 2.5 provides with a new `@Scope` annotation. Simply provide the name of the scope @@ -5484,6 +5549,7 @@ the following configuration will result in standard JDK dynamic proxies: [[beans-scanning-qualifiers]] === Providing qualifier metadata with annotations + The `@Qualifier` annotation is discussed in <>. The examples in that section demonstrate the use of the `@Qualifier` annotation and custom qualifier annotations to provide fine-grained control when you resolve autowire @@ -5680,6 +5746,7 @@ component-scanning in the exact same way as when using Spring annotations: [[beans-standard-annotations-limitations]] === Limitations of the standard approach + When working with standard annotations, it is important to know that some significant features are not available as shown in the table below: @@ -5796,6 +5863,7 @@ Java-based configuration. [[beans-java-instantiating-container]] === Instantiating the Spring container using AnnotationConfigApplicationContext + The sections below document Spring's `AnnotationConfigApplicationContext`, new in Spring 3.0. This versatile `ApplicationContext` implementation is capable of accepting not only `@Configuration` classes as input, but also plain `@Component` classes and classes @@ -5812,6 +5880,7 @@ used within those classes where necessary. [[beans-java-instantiating-container-contstructor]] ==== Simple construction + In much the same way that Spring XML files are used as input when instantiating a `ClassPathXmlApplicationContext`, `@Configuration` classes may be used as input when instantiating an `AnnotationConfigApplicationContext`. This allows for completely @@ -6005,6 +6074,7 @@ You can use the `@Bean` annotation in a `@Configuration`-annotated or in a [[beans-java-declaring-a-bean]] ==== Declaring a bean + To declare a bean, simply annotate a method with the `@Bean` annotation. You use this method to register a bean definition within an `ApplicationContext` of the type specified as the method's return value. By default, the bean name will be the same as @@ -6046,6 +6116,7 @@ transferService -> com.acme.TransferServiceImpl [[beans-java-dependencies]] ==== Bean dependencies + A `@Bean` annotated method can have an arbitrary number of parameters describing the dependencies required to build that bean. For instance if our `TransferService` requires an `AccountRepository` we can materialize that dependency via a method @@ -6071,6 +6142,7 @@ injection, see <> for more det [[beans-java-lifecycle-callbacks]] ==== Receiving lifecycle callbacks + Any classes defined with the `@Bean` annotation support the regular lifecycle callbacks and can use the `@PostConstruct` and `@PreDestroy` annotations from JSR-250, see <> for further @@ -6233,6 +6305,7 @@ link) to our `@Bean` using Java, it would look like the following: [[beans-java-customizing-bean-naming]] ==== Customizing bean naming + By default, configuration classes use a `@Bean` method's name as the name of the resulting bean. This functionality can be overridden, however, with the `name` attribute. @@ -6253,6 +6326,7 @@ resulting bean. This functionality can be overridden, however, with the `name` a [[beans-java-bean-aliasing]] ==== Bean aliasing + As discussed in <>, it is sometimes desirable to give a single bean multiple names, otherwise known as__bean aliasing__. The `name` attribute of the `@Bean` annotation accepts a String array for this purpose. @@ -6274,6 +6348,7 @@ annotation accepts a String array for this purpose. [[beans-java-bean-description]] ==== Bean description + Sometimes it is helpful to provide a more detailed textual description of a bean. This can be particularly useful when beans are exposed (perhaps via JMX) for monitoring purposes. @@ -6308,6 +6383,7 @@ inter-bean dependencies. See <> for a general introdu [[beans-java-injecting-dependencies]] ==== Injecting inter-bean dependencies + When ++@Bean++s have dependencies on one another, expressing that dependency is as simple as having one bean method call another: @@ -6343,6 +6419,7 @@ using plain `@Component` classes. [[beans-java-method-injection]] ==== Lookup method injection + As noted earlier, <> is an advanced feature that you should use rarely. It is useful in cases where a singleton-scoped bean has a dependency on a prototype-scoped bean. Using Java for this @@ -6396,6 +6473,7 @@ the abstract `createCommand()` method is overridden in such a way that it looks [[beans-java-further-information-java-config]] ==== Further information about how Java-based configuration works internally + The following example shows a `@Bean` annotated method being called twice: [source,java,indent=0] @@ -6730,10 +6808,11 @@ than the usual process of navigating interface-based code. [[beans-java-conditional]] -==== Conditionally including @Configuration classes or @Beans -It is often useful to conditionally enable to disable a complete `@Configuration` class, +==== Conditionally include @Configuration classes or @Bean methods + +It is often useful to conditionally enable or disable a complete `@Configuration` class, or even individual `@Bean` methods, based on some arbitrary system state. One common -example of this it to use the `@Profile` annotation to active beans only when a specific +example of this is to use the `@Profile` annotation to activate beans only when a specific profile has been enabled in the Spring `Environment` (see <> for details). @@ -6773,6 +6852,7 @@ See the {javadoc-baseurl}/org/springframework/context/annotation/Conditional.htm [[beans-java-combining]] ==== Combining Java and XML configuration + Spring's `@Configuration` class support does not aim to be a 100% complete replacement for Spring XML. Some facilities such as Spring XML namespaces remain an ideal way to configure the container. In cases where XML is convenient or necessary, you have a @@ -6796,7 +6876,7 @@ Remember that `@Configuration` classes are ultimately just bean definitions in t container. In this example, we create a `@Configuration` class named `AppConfig` and include it within `system-test-config.xml` as a `` definition. Because `` is switched on, the container will recognize the -`@Configuration` annotation, and process the `@Bean` methods declared in `AppConfig` +`@Configuration` annotation and process the `@Bean` methods declared in `AppConfig` properly. [source,java,indent=0] @@ -6821,10 +6901,11 @@ properly. } ---- +*system-test-config.xml*: + [source,xml,indent=0] [subs="verbatim,quotes"] ---- - system-test-config.xml @@ -6840,10 +6921,11 @@ properly. ---- +*jdbc.properties*: + [literal] [subs="verbatim,quotes"] ---- -jdbc.properties jdbc.url=jdbc:hsqldb:hsql://localhost/xdb jdbc.username=sa jdbc.password= @@ -6861,11 +6943,11 @@ jdbc.password= [NOTE] ==== -In `system-test-config.xml` above, the `AppConfig` does not declare an `id` +In `system-test-config.xml` above, the `AppConfig` `` does not declare an `id` element. While it would be acceptable to do so, it is unnecessary given that no other bean will ever refer to it, and it is unlikely that it will be explicitly fetched from the container by name. Likewise with the `DataSource` bean - it is only ever autowired -by type, so an explicit bean id is not strictly required. +by type, so an explicit bean `id` is not strictly required. ==== -- @@ -6875,13 +6957,14 @@ Because `@Configuration` is meta-annotated with `@Component`, `@Configuration`-a classes are automatically candidates for component scanning. Using the same scenario as above, we can redefine `system-test-config.xml` to take advantage of component-scanning. Note that in this case, we don't need to explicitly declare -``, because `` enables all the same +``, because `` enables the same functionality. +*system-test-config.xml*: + [source,xml,indent=0] [subs="verbatim,quotes"] ---- - system-test-config.xml @@ -7043,9 +7126,9 @@ this need. ==== @Profile The {javadoc-baseurl}/org/springframework/context/annotation/Profile.html[`@Profile`] -annotation allows to indicate that a component is eligible for registration +annotation allows you to indicate that a component is eligible for registration when one or more specified profiles are active. Using our example above, we -can rewrite the _dataSource_ configuration as follows: +can rewrite the `dataSource` configuration as follows: [source,java,indent=0] [subs="verbatim,quotes"] @@ -7081,9 +7164,9 @@ can rewrite the _dataSource_ configuration as follows: ---- -`@Profile` can be used as a meta-annotation, for the purpose of composing -custom stereotype annotations. The following example defines a `@Production` -custom annotation that can be used as a drop-in replacement of +`@Profile` can be used as a <> for the purpose +of creating a custom _composed annotation_. The following example defines a custom +`@Production` annotation that can be used as a drop-in replacement for `@Profile("production")`: [source,java,indent=0] @@ -7096,8 +7179,8 @@ custom annotation that can be used as a drop-in replacement of } ---- -`@Profile` can also be specified at method-level to include only one particular -bean of a configuration class: +`@Profile` can also be declared at the method level to include only one particular bean +of a configuration class: [source,java,indent=0] [subs="verbatim,quotes"] @@ -7126,22 +7209,21 @@ bean of a configuration class: [TIP] ==== -If a `@Configuration` class is marked with `@Profile`, all of the `@Bean` methods -and `@Import` annotations associated with that class will be bypassed unless one -or more of the specified profiles are active. If a `@Component` or `@Configuration` -class is marked with `@Profile({"p1", "p2"})`, that class will not be registered/ -processed unless profiles 'p1' and/or 'p2' have been activated. If a given profile -is prefixed with the NOT operator (`!`), the annotated element will be registered -if the profile is **not** active. e.g., for `@Profile({"p1", "!p2"})`, registration -will occur if profile 'p1' is active or if profile 'p2' is not active. +If a `@Configuration` class is marked with `@Profile`, all of the `@Bean` methods and +`@Import` annotations associated with that class will be bypassed unless one or more of +the specified profiles are active. If a `@Component` or `@Configuration` class is marked +with `@Profile({"p1", "p2"})`, that class will not be registered/processed unless +profiles 'p1' and/or 'p2' have been activated. If a given profile is prefixed with the +NOT operator (`!`), the annotated element will be registered if the profile is **not** +active. For example, given `@Profile({"p1", "!p2"})`, registration will occur if profile +'p1' is active or if profile 'p2' is not active. ==== [[beans-definition-profiles-xml]] -=== XML Bean definition profiles +=== XML bean definition profiles -The XML counterpart is an update of the `beans` element that accepts a -`profile` attribute. Our sample configuration above can be rewritten in two XML -files as follows: +The XML counterpart is the `profile` attribute of the `` element. Our sample +configuration above can be rewritten in two XML files as follows: [source,xml,indent=0] [subs="verbatim,quotes"] @@ -7203,15 +7285,16 @@ last ones in the file. This should help provide flexibility without incurring clutter in the XML files. [[beans-definition-profiles-enable]] -==== Enabling a profile +==== Activating a profile -Now that we have updated our configuration, we still need to instruct which +Now that we have updated our configuration, we still need to instruct Spring which profile is active. If we started our sample application right now, we would see a `NoSuchBeanDefinitionException` thrown, because the container could not find the Spring bean named `dataSource`. -Activating a profile can be done in several ways, but the most straightforward -is to do it programmatically against the `ApplicationContext` API: +Activating a profile can be done in several ways, but the most straightforward is to do +it programmatically against the `Environment` API which is available via an +`ApplicationContext`: [source,java,indent=0] [subs="verbatim,quotes"] @@ -7222,10 +7305,12 @@ is to do it programmatically against the `ApplicationContext` API: ctx.refresh(); ---- -In addition, profiles may also be activated declaratively through the `spring.profiles.active` -property which may be specified through system environment variables, JVM system properties, -servlet context parameters in `web.xml` or even as an entry in JNDI (see -<>). +In addition, profiles may also be activated declaratively through the +`spring.profiles.active` property which may be specified through system environment +variables, JVM system properties, servlet context parameters in `web.xml`, or even as an +entry in JNDI (see <>). In integration tests, active +profiles can be declared via the `@ActiveProfiles` annotation in the `spring-test` module +(see <>). Note that profiles are not an "either-or" proposition; it is possible to activate multiple profiles at once. Programmatically, simply provide multiple profile names to the @@ -7248,7 +7333,7 @@ Declaratively, `spring.profiles.active` may accept a comma-separated list of pro [[beans-definition-profiles-default]] ==== Default profile -The _default_ profile represents the profile that is enabled by default. Consider the +The _default_ profile represents the profile that is enabled by default. Consider the following: [source,java,indent=0] @@ -7272,13 +7357,13 @@ If no profile is active, the `dataSource` above will be created; this can be seen as a way to provide a _default_ definition for one or more beans. If any profile is enabled, the _default_ profile will not apply. -The name of that default profile can be changed using `setDefaultProfiles` on +The name of the default profile can be changed using `setDefaultProfiles()` on the `Environment` or declaratively using the `spring.profiles.default` property. [[beans-property-source-abstraction]] -=== PropertySource Abstraction +=== PropertySource abstraction -Spring's Environment abstraction provides search operations over a configurable +Spring's `Environment` abstraction provides search operations over a configurable hierarchy of property sources. To explain fully, consider the following: [source,java,indent=0] @@ -7695,6 +7780,7 @@ out the `ReloadableResourceBundleMessageSource` javadocs for details. [[context-functionality-events]] === Standard and Custom Events + Event handling in the `ApplicationContext` is provided through the `ApplicationEvent` class and `ApplicationListener` interface. If a bean that implements the `ApplicationListener` interface is deployed into the context, every time an @@ -8058,6 +8144,7 @@ an event. [[context-functionality-resources]] === Convenient access to low-level resources + For optimal usage and understanding of application contexts, users should generally familiarize themselves with Spring's `Resource` abstraction, as described in the chapter <>. @@ -8124,6 +8211,7 @@ in any subdirectory of "WEB-INF". [[context-deploy-rar]] === Deploying a Spring ApplicationContext as a Java EE RAR file + It is possible to deploy a Spring ApplicationContext as a RAR file, encapsulating the context and all of its required bean classes and library JARs in a Java EE RAR deployment unit. This is the equivalent of bootstrapping a standalone ApplicationContext, just hosted @@ -8269,6 +8357,7 @@ important functionality such as property placeholder replacement and AOP. [[beans-servicelocator]] === Glue code and the evil singleton + It is best to write most application code in a dependency-injection (DI) style, where that code is served out of a Spring IoC container, has its own dependencies supplied by the container when it is created, and is completely unaware of the container. However, diff --git a/src/asciidoc/web-cors.adoc b/src/asciidoc/web-cors.adoc index 3a9ab413c2c..51759229f24 100644 --- a/src/asciidoc/web-cors.adoc +++ b/src/asciidoc/web-cors.adoc @@ -96,7 +96,7 @@ then combine attributes from both annotations to create merged CORS configuratio @RequestMapping("/account") public class AccountController { - @CrossOrigin(origins = "http://domain2.com") + @CrossOrigin("http://domain2.com") @RequestMapping("/{id}") public Account retrieve(@PathVariable Long id) { // ... diff --git a/src/asciidoc/web-mvc.adoc b/src/asciidoc/web-mvc.adoc index 52d65466150..7108c72cbd0 100644 --- a/src/asciidoc/web-mvc.adoc +++ b/src/asciidoc/web-mvc.adoc @@ -627,7 +627,7 @@ to narrow the mapping. [[mvc-ann-requestmapping-proxying]] -==== ++@Controller++'s and AOP Proxying +==== @Controller and AOP Proxying In some cases a controller may need to be decorated with an AOP proxy at runtime. One example is if you choose to have `@Transactional` annotations directly on the @@ -1910,7 +1910,8 @@ which case they apply to matching controllers. This provides an alternative to u [[mvc-ann-controller-advice]] -==== Advising controllers with the `@ControllerAdvice` annotation +==== Advising controllers with @ControllerAdvice + The `@ControllerAdvice` annotation is a component annotation allowing implementation classes to be auto-detected through classpath scanning. It is automatically enabled when using the MVC namespace or the MVC Java config. @@ -2518,11 +2519,6 @@ directly on `RequestMappingHandlerAdapter`. - - - - - [[mvc-viewresolver]] == Resolving views All MVC frameworks for web applications provide a way to address views. Spring provides diff --git a/src/asciidoc/web-websocket.adoc b/src/asciidoc/web-websocket.adoc index 6acdc1731ee..87c6d32b090 100644 --- a/src/asciidoc/web-websocket.adoc +++ b/src/asciidoc/web-websocket.adoc @@ -1554,7 +1554,7 @@ the TCP connection is established is different from the host providing the cloud-based STOMP service. [[websocket-stomp-destination-separator]] -=== Using Dot as Separator in `@MessageMapping` Destinations +=== Using Dot as Separator in @MessageMapping Destinations Although slash-separated path patterns are familiar to web developers, in messaging it is common to use a "." as the separator, for example in the names of topics, queues,