This chapter delves deeper into Spring Core’s capabilities beyond basic Inversion of Control (IoC), exploring various services that supplement and extend its core functionalities.

Specifically, it will cover:

  • Managing the bean life cycle: Strategies for beans to receive notifications from the Spring container at different life cycle points, using interfaces, reflection, or JavaBeans annotations.

  • Making beans "Spring aware": How beans can interact with their ApplicationContext instance using interfaces like BeanNameAware and ApplicationContextAware.

  • Using FactoryBeans: Implementing beans that act as factories for other beans, integrating with the Spring BeanFactory.

  • Working with JavaBeans PropertyEditor implementations: Understanding how Spring uses PropertyEditors for type conversion, including supplied and custom implementations.

  • Learning more about the Spring ApplicationContext: A detailed look at `ApplicationContext’s additional features beyond IoC, such as internationalized message support, resource loading, and event publishing, including its use in web applications.

  • Testing Spring applications: Methods for creating Spring test contexts to effectively test Spring applications.

  • Using Spring Boot: How Spring Boot simplifies the creation of stand-alone, production-grade Spring applications.

  • Using configuration enhancements: Features like profile management and environment/property source abstraction to streamline application configuration.

  • Using Groovy for configuration: Exploring Groovy as an alternative or supplement to XML and Java-based bean configuration.

  1. What are the three distinct strategies presented in this chapter for enabling Spring beans to receive notifications from the container at various points throughout their life cycles?

  2. Which two specific interfaces does Spring offer to make a bean "Spring aware" by allowing it to obtain its assigned name and reference its ApplicationContext instance, as discussed in this chapter?

  3. According to this chapter, which specific Spring version introduced the ability to configure bean definitions using the Groovy language, and how is this approach positioned as an alternative or supplement to existing configuration styles?

Spring’s Impact on Application Portability

The text discusses the trade-off between using Spring-specific features and ensuring application portability across different IoC containers. While avoiding Spring-specific features might seem to enhance portability, it means sacrificing the extensive functionality Spring offers.

The author advises against creating unnecessary portability requirements, as end-users typically prioritize functionality over the ability to run on multiple IoC containers, and building on the "lowest common denominator" can disadvantage an application.

However, the text argues that coupling an application to Spring can paradoxically increase its portability in a wider scope. As a freely available, open-source, vendor-agnostic framework, Spring allows applications to run wherever Java runs. It provides capabilities similar to JEE and simplifies many aspects of it, enabling sophisticated web applications to run in simpler servlet containers by replacing vendor-specific or configuration-dependent JEE features with Spring’s equivalents.

  1. According to the text, what is the primary trade-off when prioritizing application portability between different IoC containers over using Spring-specific features?

  2. Which specific book is cited in the text as providing a more detailed discussion on "phantom requirements" related to project development?

  3. In what ways does the text argue that coupling an application to the Spring Framework can actually increase its portability in a wider scope, despite being specific to Spring?

Bean Life-Cycle Management

Spring IoC containers, including Spring, allow beans to receive notifications at specific points in their lifecycle to perform relevant processing. The two key events are post-initialization and pre-destruction.

  • Post-initialization occurs after Spring has set all property values and completed any configured dependency checks.

  • Pre-destruction is fired just before Spring destroys the bean instance.

A notable exception is that beans with prototype scope will not receive the pre-destruction event, although they do receive post-initialization notifications.

Spring provides three mechanisms for beans to hook into these lifecycle events:

  1. Interface-based mechanism: The bean implements a Spring-specific interface (e.g., InitializingBean, DisposableBean), and Spring invokes a defined callback method.

  2. Method-based mechanism: You specify the names of initialization and destruction methods in your ApplicationContext configuration.

  3. Annotation-based mechanism: You use JSR-250 annotations (@PostConstruct for post-initialization, @PreDestroy for pre-destruction) on methods within the bean class.

While all three achieve the same goal, the choice depends on application requirements. Interface-based mechanisms are widely used within Spring itself and can be convenient for many beans of the same type or when coupling to Spring is already present. However, for your own beans, method-based or annotation-based (especially JSR-250, which is a standard) approaches offer better portability as they don’t require implementing Spring-specific interfaces. If a bean is intended to be self-contained and used across different Spring projects, the interface-based mechanism is recommended. When using annotations, ensure your IoC container supports the JSR-250 standard.

  1. What is the specific exception regarding pre-destruction life-cycle events for beans with prototype scope in Spring?

  2. According to the text, what are the specific scenarios or application requirements that would lead a developer to choose the interface-based mechanism over method-based or annotation-based mechanisms for Spring bean life-cycle notifications?

  3. What is a key advantage of using JSR-250 annotations for Spring bean life-cycle callbacks compared to Spring’s interface-based mechanism, and what is a prerequisite for using them?

Hooking into Bean Creation

Spring bean initialization callbacks allow a bean to verify if all its required dependencies are met and apply custom logic to dependency resolution, such as providing defaults for optional dependencies. This is crucial because Spring’s automatic dependency checking is an all-or-nothing approach.

These callbacks are invoked after Spring has finished injecting all possible dependencies, making them suitable for checks that cannot be performed in the constructor (as dependencies aren’t available yet). Beyond dependency validation, initialization callbacks are also ideal for triggering actions that a bean must perform automatically based on its configuration, such as starting a scheduler.

  1. Beyond Spring’s all-or-nothing dependency checking, what specific opportunities does an initialization callback offer for applying custom logic to dependency resolution, such as handling optional dependencies with defaults?

  2. Why is a bean’s constructor an unsuitable place to verify if all its required dependencies are satisfied, and when does Spring’s initialization callback execute to make such checks feasible?

  3. In addition to validating dependencies, what other primary purpose does Spring’s initialization callback serve, especially regarding a bean’s automatic actions triggered by its configuration?

Executing a Method When a Bean Is Created

Spring allows you to define an initialization method for a bean, which is invoked after the bean’s properties have been set. This callback mechanism is beneficial for:

  • Decoupling your application from Spring.

  • Integrating pre-built or third-party beans.

  • Managing a small number of similar beans.

To designate an initialization method, you specify its name using the initMethod attribute within the @Bean annotation in Java configuration classes.

The provided example demonstrates this with a Singer bean that includes an init() method. This init() method performs validation and sets default values:

  • If the name property is null, it assigns a DEFAULT_NAME.

  • If the age property is not set (i.e., Integer.MIN_VALUE), it throws an IllegalArgumentException.

In the SingerConfiguration, three Singer beans are defined, all using init() as their initialization method:

  1. singerOne: Has both name and age set, so init() makes no changes.

  2. singerTwo: Lacks a name, so init() assigns the DEFAULT_NAME.

  3. singerThree: Lacks an age, causing init() to throw an IllegalArgumentException, which Spring wraps in a BeanCreationException, preventing the bean’s creation.

This approach ensures that beans are correctly configured and validated before they are used. The initialization method must not accept any arguments, though its return type is ignored. While static initialization methods are possible, non-static methods are generally preferred for validating instance-specific state.


  1. According to the Singer class’s init() method, what specific actions are taken if the name property is null or if the age property is Integer.MIN_VALUE during bean initialization?

  2. When the singerThree bean is processed by Spring, as configured in Listing 4-2, what is the specific reason for its failure, and what type of exception does Spring wrap the underlying error in?

  3. What is the primary constraint on an initialization method designated via the initMethod attribute in the @Bean annotation, and why is using a static initialization method generally discouraged for validating a bean’s state?

Implementing the InitializingBean Interface

The InitializingBean interface in Spring allows developers to execute custom code within a bean immediately after Spring has finished configuring it. This interface defines a single method, afterPropertiesSet(), which serves the same purpose as a traditional initialization method.

This post-configuration hook is useful for:

  • Validating the bean’s configuration to ensure it’s in a valid state.

  • Providing default values for properties if they haven’t been explicitly set.

The provided example demonstrates a Singer class implementing InitializingBean. Its afterPropertiesSet() method checks if the name property is null and sets a default if so, and it throws an IllegalArgumentException if the age property is not set. Using InitializingBean eliminates the need to specify an initMethod attribute in the bean’s configuration, yielding identical results to the initMethod approach.


  1. According to the Singer class implementation in Listing 4-4, what specific exception is thrown if the age property is not set for a Singer bean?

  2. What is the default name value assigned to a Singer bean by its afterPropertiesSet() method if no name is explicitly provided?

  3. How does the afterPropertiesSet() method in the Singer class (Listing 4-4) handle the name and age properties to ensure valid configuration?

Using the JSR-250 @PostConstruct Annotation

JSR-250 annotations, specifically @PostConstruct, are supported by Spring (starting from version 2.5) to define bean lifecycle initialization methods.

Key Points:

  • Purpose: @PostConstruct marks a method that Spring should call after a bean’s properties have been set but before the bean is fully ready for use.

  • Example (Singer class): The provided Singer class uses @PostConstruct on a postConstruct() method to perform initialization logic, such as setting a default name or validating the age property.

  • Alternatives: @PostConstruct is an alternative to:

    • Using initMethod attribute with @Bean (e.g., @Bean(initMethod="myInitMethod")).

    • Implementing the InitializingBean interface.

  • Method Naming: The method annotated with @PostConstruct can have any name (e.g., postConstruct is just a convention).

  • Comparison of Approaches:

    • @Bean(initMethod=..):

      • Benefit: Decouples application from Spring.

      • Drawback: Requires configuring the initialization method for each bean.

    • InitializingBean interface:

      • Benefit: Specifies initialization callback once for all instances of a class.

      • Drawback: Couples the application to Spring.

    • @PostConstruct annotation:

      • Benefit: Applied directly to the method, clear intent.

      • Drawback: Requires the IoC container to support JSR-250.

  • Choosing an Approach:

    • For portability (less coupling to Spring), use @Bean(initMethod=..) or @PostConstruct.

    • To reduce configuration and potential errors, use InitializingBean.

  • Private Initialization Methods: Both @Bean(initMethod=..) and @PostConstruct allow initialization methods to be declared as private. Spring can still call them via reflection, preventing accidental external calls and ensuring they are only invoked once during bean creation.


  1. According to the text, what specific access right advantage do @Bean(initMethod=..) and @PostConstruct offer for initialization methods, and why is this considered beneficial?

  2. In the Singer class example (Listing 4-5), what specific conditions does the postConstruct() method check for, and what actions does it take if those conditions are not met?

  3. When comparing bean initialization approaches, what is the main benefit of using the InitializingBean interface, and what is its primary drawback regarding application coupling?

Understanding Order of Resolution

The provided text details the specific order in which Spring invokes various initialization mechanisms on a single bean instance. This order is a fundamental part of the Spring bean creation lifecycle:

  1. Constructor Call: The bean instance is first created by calling its constructor.

  2. Dependency Injection: Dependencies are injected, typically via setters (e.g., methods annotated with @Autowired), which is handled by infrastructure beans like AutowiredAnnotationBeanPostProcessor.

  3. Pre-Initialization Callbacks (@PostConstruct): Before the main initialization, pre-initialization BeanPostProcessor-s are consulted. The @PostConstruct annotated method is invoked at this stage (managed by CommonAnnotationBeanPostProcessor). This happens after construction and dependency injection, but before afterPropertiesSet() and the initMethod.

  4. InitializingBean.afterPropertiesSet(): If the bean implements the InitializingBean interface, its afterPropertiesSet() method is executed next, once all bean properties have been set.

  5. Custom Initialization Method (initMethod): Finally, the method specified by the initMethod attribute in the @Bean annotation is executed. This is considered the "actual" initialization method of the bean.

The AllInitMethodsDemo example, including the MultiInit class and MultiInitConfiguration, clearly demonstrates this precise order in its console output: Constructor → Setter (@Autowired) → @PostConstructafterPropertiesSet()initMethod. Spring leverages internal BeanPostProcessor infrastructure beans (like CommonAnnotationBeanPostProcessor for @PostConstruct and AutowiredAnnotationBeanPostProcessor for @Autowired) to manage these steps.

  1. When a single Spring bean instance utilizes all available initialization mechanisms (constructor, @Autowired setters, @PostConstruct, InitializingBean.afterPropertiesSet(), and a method specified by @Bean(initMethod)), what is the precise order in which these methods are invoked by Spring?

  2. Which specific Spring infrastructure BeanPostProcessor is responsible for processing the @PostConstruct annotation, and at what stage of the bean creation process (relative to dependency injection and afterPropertiesSet()) does it execute the annotated method?

  3. According to the AllInitMethodsDemo example and its console output (Listing 4-7), what is the exact sequence of log messages indicating the execution order of the MultiInit bean’s lifecycle methods, from its constructor call to its final initialization method?

Making Your Beans “Spring Aware”

Using the BeanNameAware Interface

The BeanNameAware interface in Spring allows a bean to obtain its own name within the Spring container.

Key aspects:

  • Method: It has a single method, setBeanName(String beanName).

  • Invocation: Spring calls this method after the bean has been configured but before any lifecycle callbacks (like initialization or destruction methods).

  • Implementation: Typically, the setBeanName() method simply stores the provided bean name in a private field for later use by the bean.

  • Usage: No special configuration is required to use BeanNameAware. It’s often used to enhance log messages by including the bean’s name.

  • Caution: While useful for internal purposes like logging, it’s advised not to give bean names business meaning solely to leverage BeanNameAware. If a bean requires an internal "name" with business significance, it’s better to define a custom interface (e.g., Nameable) and inject the name via dependency injection, keeping Spring configuration names concise and separate from business logic.

  1. According to the text, at what precise point in the Spring bean lifecycle is the setBeanName() method of the BeanNameAware interface invoked, relative to bean configuration and other lifecycle callbacks?

  2. What is a common practical application for using the BeanNameAware interface highlighted in the provided example, and what specific temptation should developers avoid when assigning names to beans via this mechanism?

  3. Does the BeanNameAware interface require any special Spring configuration to be utilized, and what is the typical, minimal implementation pattern for its setBeanName() method as demonstrated in the NamedSinger example?

Using the ApplicationContextAware Interface

The ApplicationContextAware interface allows a Spring bean to obtain a reference to its configuring ApplicationContext instance. While it enables programmatic access to other beans via getBean(), this practice is generally discouraged in favor of dependency injection to avoid unnecessary coupling and complexity.

A key use case for ApplicationContextAware is demonstrated by automatically registering a shutdown hook. By implementing ApplicationContextAware and its setApplicationContext() method, a bean (like ShutdownHookBean) can check if the ApplicationContext is a GenericApplicationContext and then call registerShutdownHook() on it. This eliminates the need for manual ctx.registerShutdownHook() calls during application bootstrap, ensuring that preDestroy() methods on singletons are automatically invoked when the application shuts down.

  1. How does the ShutdownHookBean implementation in Listing 4-15 determine if it can register a shutdown hook, and what specific method does it call to perform this registration?

  2. What is the key advantage of configuring the ShutdownHookBean as shown in Listing 4-16, specifically regarding the need for explicit shutdown hook registration in the AwareDemo application?

  3. What was the primary reason given for the creation of the ApplicationContextAware interface, and what specific practice is strongly advised against when using it to obtain other beans?

Use of FactoryBeans

FactoryBean Example - The MessageDigestFactoryBean

The provided text explains how to integrate Java’s MessageDigest class, which requires creation via a static factory method (MessageDigest.getInstance()), into a Spring application using a FactoryBean.

Here’s a summary of the key points:

  1. Problem Statement: Java’s MessageDigest class cannot be instantiated directly with new; it requires MessageDigest.getInstance("algorithm"). Managing such objects in Spring without a FactoryBean would necessitate an algorithmName property on the bean and an initialization callback to invoke getInstance().

  2. Solution: FactoryBean: Spring’s FactoryBean interface provides a way to encapsulate complex object creation logic. It allows other beans to declare a dependency on the product of the FactoryBean (e.g., MessageDigest), rather than the FactoryBean itself.

  3. MessageDigestFactoryBean Implementation:

    • It implements FactoryBean<MessageDigest> and InitializingBean.

    • afterPropertiesSet(): This callback method is used to create the actual MessageDigest instance by calling MessageDigest.getInstance(algorithmName). The algorithmName defaults to "MD5" but can be configured.

    • getObject(): Returns the MessageDigest instance created in afterPropertiesSet(). This is the object that Spring injects into other beans.

    • getObjectType(): Specifies that the factory produces objects of type MessageDigest.class.

    • isSingleton(): Indicates that the produced MessageDigest instance is a singleton.

  4. Consuming the `FactoryBean’s Product:

    • A MessageDigester bean is introduced, which has two MessageDigest dependencies (digest1 and digest2).

    • In the Spring configuration (MessageDigestConfig), two MessageDigestFactoryBean beans are defined (one for SHA1, one for MD5).

    • The MessageDigester bean then explicitly obtains the MessageDigest instances by calling getObject() on the configured MessageDigestFactoryBean beans, demonstrating how the factory provides the actual MessageDigest objects for injection.

  5. Benefits of FactoryBean:

    • It’s ideal for integrating classes that cannot be created directly using the new operator (e.g., those requiring static factory methods or complex setup).

    • It acts as an adapter, allowing such objects to fully leverage Spring’s Inversion of Control (IoC) capabilities.

    • It simplifies the configuration for consuming beans, as they only need to declare a dependency on the product type, while the FactoryBean handles the underlying creation complexity.

  1. What is the primary benefit of using a FactoryBean over a simple property-based initialization callback when creating a MessageDigest object in Spring? This question targets the core reason for using the FactoryBean pattern as explained in the text – encapsulating the MessageDigest.getInstance() logic.

  2. According to the provided code, what default algorithm is used by the MessageDigestFactoryBean if the algorithmName property is not explicitly set? This question requires a close reading of the MessageDigestFactoryBean class to identify the default value assigned to algorithmName.

  3. In the context of Spring’s IoC container, what is the difference between setting the scope of a FactoryBean itself versus the objects it returns? This question focuses on a nuanced point about the isSingleton() method and the @Scope annotation, which is specifically addressed in the text.

Accessing a FactoryBean Directly

This text explains how to directly access a FactoryBean in Spring. While Spring automatically provides the object produced by a FactoryBean, you can access the FactoryBean itself by prefixing the bean name with an ampersand (&) when calling getBean().

However, the text strongly advises against directly accessing the FactoryBean and manually calling getObject(). The FactoryBean is intended as internal infrastructure to support IoC, and directly interacting with it creates unnecessary coupling and extra work, potentially leading to issues if Spring’s implementation details change. It’s best to let Spring manage the object creation process.

  1. How does Spring allow direct access to a FactoryBean instance, and what prefix is required when using getBean() to achieve this? (Answer is directly stated: prefix the bean name with an ampersand – &.)

  2. In the provided code example (FactoryBeanDemo), what is being cast to MessageDigestFactoryBean when retrieving it from the application context? (Answer: ctx.getBean("&shaDigest") is cast to MessageDigestFactoryBean.)

  3. According to the text, what is the primary intended purpose of a FactoryBean, and why is directly accessing it and calling getObject() discouraged? (Answer: It’s intended as supporting infrastructure for IoC, and direct access creates unnecessary coupling to implementation details.)

JavaBeans PropertyEditors

Using the Built-in PropertyEditors

The provided content demonstrates a Spring bean, DiverseValuesContainer, which declares 14 properties of various types supported by Spring’s built-in PropertyEditor implementations. Although the properties are not Strings, their values are injected as simple String literals, and Spring automatically converts these Strings to the appropriate types using the built-in editors.

Key points include:

  • The bean properties cover types like byte arrays, Character, Class, Boolean, List, Date, Float, File, InputStream, Locale, Pattern, Properties, trimmed String, and URL.

  • Custom editors such as CustomDateEditor (with a specified date format) and StringTrimmerEditor are registered explicitly via a PropertyEditorRegistrar implementation because they are not registered by default.

  • The example includes a ValuesHolder component providing some values (like a list and an InputStream) injected via Spring Expression Language (SpEL).

  • Running the example shows Spring converting the String values to their respective types and injecting them, with logging output confirming the conversions.

  • Table 4-1 summarizes the main built-in Spring `PropertyEditor`s, describing their purpose, such as converting Strings to byte arrays, Characters, Classes, Booleans, Collections, Dates, Files, InputStreams, Locales, Patterns, Properties, trimmed Strings, and URLs.

Overall, this example illustrates how Spring’s built-in `PropertyEditor`s simplify configuration by automatically converting String property values to complex types, easing application setup with common components like files, URLs, and dates.

  1. What specific date format is used by the CustomDateEditor registered in the DiverseValuesContainer? Answer: The CustomDateEditor is registered with the format "MM/dd/yyyy".

  2. Besides CustomDateEditor and StringTrimmerEditor, what other PropertyEditors are explicitly mentioned as not being registered by default in Spring? Answer: The context states that these two editors "were not registered by default in Spring". No others are explicitly mentioned as lacking default registration.

  3. What values are used in the ValuesHolder class to populate the stringList and the inputStream properties? Answer: The stringList is populated with "Mayer", "Psihoza", and "Mazikeen". The inputStream is initialized to read from a file named "test.txt" located in the system’s temporary directory.

Creating a Custom PropertyEditor

  • When Spring’s built-in PropertyEditors are insufficient, you can create your own by extending java.beans.PropertyEditorSupport and overriding only setAsText().

  • Example domain class: FullName with firstName and lastName fields.

  • Custom editor (NamePropertyEditor):

    • Extends PropertyEditorSupport.

    • In setAsText(), splits the incoming string on the space and builds a new FullName instance, then calls setValue().

  • Registration:

    • Use a CustomEditorConfigurer bean.

    • Supply a Map where the key is the target type (FullName.class) and the value is the custom editor class (NamePropertyEditor.class).

  • Usage demo:

    • Person component has a FullName property.

    • @Value("John Mayer") triggers Spring to feed the string through NamePropertyEditor and inject the resulting FullName.

    • Running the application logs the correctly populated FullName object.

  • Key points:

    • Only one method (setAsText) needs implementation when you extend PropertyEditorSupport.

    • Custom editors are registered globally through CustomEditorConfigurer.

    • Since Spring 3, a newer Type Conversion API and Field Formatting SPI offer a more modern alternative for type conversion.

  1. In Listing 4-26, which property of the CustomEditorConfigurer bean is populated with a Map to register the custom PropertyEditor?

  2. What exact string value is supplied via the @Value annotation to the Person.setName method, causing the custom editor to run?

  3. What fully qualified class name is used as the key in the customEditors Map to associate NamePropertyEditor with its target type?