Spring Study Notes - Copyright © 2010 Gavin Lasnitzki Index   Notes   Objectives
Spring Basics

Preface

Introduction Key

Objectives: 1.1 Goals of the Spring Framework

1.1. Overview Key

Objectives: 1.2 Spring's role in enterprise application architecture , 1.3 Web application development support

Package Desc
Core
  • IoC and Dependency Injection features
  • Sophisticated implementation of the factory pattern which removes the need for programmatic singletons
  • Allows you to decouple the configuration and specification of dependencies from your actual program logic
Context
  • Adds support for internationalization (I18N)
  • Event-propagation
  • Resource-loading
  • Transparent creation of contexts
DAO
  • JDBC-abstraction layer
ORM
  • Integration layers for popular object-relational mapping
AOP
  • AOP Alliance-compliant aspect-oriented programming implementation
Web
  • Basic web-oriented integration features, such as multipart file-upload functionality
  • The initialization of the IoC container using servlet listeners and a web-oriented application context
MVC
  • a Model-View-Controller (MVC) implementation
  • Clean separation between domain model code and web forms

1.2. Usage scenarios

2. What's new in Spring 2.0 and 2.5?

  • The Inversion of Control (IoC) container
    • New bean scopes
    • Easier XML configuration
    • Extensible XML authoring
    • Annotation-driven configuration
    • Autodetecting components in the classpath
  • Aspect Oriented Programming (AOP)
    • Easier AOP XML configuration
    • Support for @AspectJ aspects
    • Support for bean name pointcut element
    • Support for AspectJ load-time weaving
  • The Middle Tier
    • Easier configuration of declarative transactions in XML
    • Full WebSphere transaction management support
    • JPA
    • Asynchronous JMS
    • JDBC
  • The Web Tier
    • Sensible defaulting in Spring MVC
    • Portlet framework
    • Annotation-based controllers
    • A form tag library for Spring MVC
    • Tiles 2 support
    • JSF 1.2 support
    • JAX-WS support
  • Everything else
    • Dynamic language support
    • Enhanced testing support
    • JMX support
    • Deploying a Spring application context as JCA adapter
    • Task scheduling
    • Java 5 (Tiger) support

 

2.7. Migrating to Spring 2.5

2.8. Updated sample applications

2.9. Improved documentation

I. Core Technologies

3. The IoC container

3.1. Introduction

The BeanFactory interface provides an advanced configuration mechanism.

The ApplicationContext interface builds on top of the BeanFactory and adds other functionality such as easier integration with Spring's AOP features, message resource handling (for use in internationalization), event propagation, and application-layer specific contexts such as the WebApplicationContext for use in web applications

3.2. Basics - containers and beans Key

Objectives: 1.4 Writing bean definitions

3.2.1. The container

IoC container responsibilities include instantiating or sourcing application objects, configuring such objects, and assembling the dependencies between these objects.

The most commonly used BeanFactory implementation is the XmlBeanFactory class

3.2.1.1. Configuration metadata

IoC container consumes some form of configuration metadata.
IoC container itself is totally decoupled from the format in which this configuration metadata is actually written.
XML-based metadata (consumed by the XmlBeanFactory) is by far the most commonly used form of configuration metadata.
Annotations are another popular form of metadata that the Spring container can consume.

Basic structure of XML-based configuration metadata:

 

3.2.2. Instantiating a container

3.2.2.1. Composing XML-based configuration metadata

Objectives: 1.8 Importing configuration files

Use the application context constructor which takes multiple Resource locations.
Preferred because container configuration files are unaware of the fact that they are being combined with others.

 

Use one or more occurrences of the <import/> element to load bean definitions from another file (or files).
All location paths are considered relative to the definition file doing the importing.
You can always use fully qualified resource locations instead of relative paths: e.g."file:C:/config/services.xml" or "classpath:/config/services.xml".

3.2.3. The beans

These bean definitions are represented as BeanDefinition objects and have the following metadata:

  • a package-qualified class name: typically this is the actual implementation class of the bean being defined. bean
  • behavioral configuration elements, which state how the bean should behave in the container (scope, lifecycle callbacks, and so forth).
  • references to other beans which are needed for the bean to do its work; these references are also called collaborators or dependencies.
  • other configuration settings

3.2.3.1. Naming beans Key Question

Objectives: 1.7 Bean Naming

Use the standard Java convention for instance field names when naming beans.
Ids must be unique within the container the bean is hosted in.
Use the 'id' or 'name' attributes.

The 'id' attribute allows you to specify exactly one id, and as it is a real XML element ID attribute, the XML parser is able to do some extra validation when other elements reference the id; as such, it is the preferred way to specify a bean id.
The XML specification does limit the characters which are legal in XML IDs.

You may also or instead specify one or more bean ids, separated by a comma, semicolon, or whitespace in the 'name' attribute.

You are not required to supply a name for a bean. If no name is supplied explicitly, the container will generate a unique name for that bean.

Alias allows you to supply more than one name.
The bean may be referred using the 'toName'

 

3.2.3.2. Instantiating beans

Configure a bean definition for a static inner class, you must include the $ character (i.e. com.example.Foo$Bar).

The 'class' attribute (which internally eventually boils down to being a Class property on a BeanDefinition instance) is normally mandatory.

It either specifies:

  • The class of the bean to be constructed where the container itself directly creates the bean by calling its constructor reflectively (somewhat equivalent to Java code using the 'new' operator)
  • The actual class containing the static factory method that is to be invoked by the container to create the object. The type of the object returned from the invocation of the static factory method may be of any type.

Instantiation using a constructor
Only the class attribute is needed.
The class being created does not need to implement any specific interfaces or be coded in a specific fashion.

 

Instantiation using a static factory method
The factory-method attribute is needed in addition to the class attribute.
In the example below, the createInstance() method must be a static method.

 

Instantiation using an instance factory method
A non-static method of an existing bean from the container is invoked to create a new bean.

 

3.2.4. Using the container

The BeanFactory interface has just a few other methods (like #getBean), but ideally your application code should never use them..

3.3. Dependencies

Objectives: 1.4 Writing bean definitions

3.3.1. Injecting dependencies Question

The basic principle behind Dependency Injection (DI) is that objects define their dependencies (that is to say the other objects they work with).
This is either through constructor arguments (Constructor Injection), arguments to a factory method, or properties which are set on the object instance after it has been constructed (Setter Injection) or returned from a factory method. This is fundamentally the inverse, hence the name Inversion of Control (IoC), of the bean itself being in control of instantiating or locating its dependencies on its own using direct construction of classes, or something like the Service Locator pattern.

DI results in cleaner code and reaching a higher grade of decoupling is much easier.

3.3.1.1. Constructor Injection Key

Effected by invoking a constructor with a number of arguments, each representing a dependency.

Constructor Argument Resolution

No Ambiguity:

If there is no potential for ambiguity in the constructor arguments of a bean definition, then the order in which the constructor arguments are defined in a bean definition is the order in which those arguments will be supplied to the appropriate constructor when it is being instantiated.

 

 

Constructor Argument Type Matching:

You can use type matching with simple types.

 

Constructor Argument Index:

The index is 0 based.

3.3.1.2. Setter Injection Key

Setter-based DI is realized by calling setter methods on your beans after invoking a no-argument constructor or no-argument static factory method to instantiate your bean.

Constructor- or Setter-based DI

Constructor:
(Pro) Favored by some purists.
(Pro) Object is never returned to client (calling) code in a less than totally initialized state.
(Con) A large number of constructor arguments can get unwieldy.

Setter:
(Pro) Objects of that class amenable to being re-configured at a later time.

BeanFactory supports injecting setter-based dependencies after some dependencies have already been supplied via the constructor approach.

Bean dependency resolution

  • The BeanFactory is created and initialized with a configuration.
  • Dependencies will be provided to the bean, when the bean is actually created.
  • Each property or constructor argument which is a value must be able to be converted.
  • The configuration of each bean is validated as it is created.
  • Singleton-scoped beans (set to be pre-instantiated ... which is the default) are created when the container is created, otherwise the bean is created when it is requested.

The container tries to set properties and resolve dependencies as late as possible.
Circular dependencies can result in beans to be injected into the other beans prior to being fully initialized.

3.3.1.3. Some examples

Setter injection

 

Constructor injection

 

Static factory (arguments to the static factory method are supplied via <constructor-arg/> elements)

 

3.3.2. Dependencies and configuration in detail

Dependencies can be defined as either references to other managed beans (collaborators), or values defined inline.

3.3.2.1. Straight values (primitives, Strings, etc.)

Value element

 

Value attribute

 

The idref element
The idref element is simply an error-proof way to pass the id of another bean.
Allows the container to validate at deployment time that the referenced, named bean actually exists.

 

Using the "local" attribute allows the bean id to be validated even earlier (at document parse time).

 

3.3.2.2. References to other beans (collaborators)

Specifying the target bean by using the bean attribute of the <ref/> tag is the most general form, and will allow creating a reference to any bean in the same container (whether or not in the same XML file), or parent container.
The "local" attribute leverages the ability of the XML parser to validate XML id references within the same file.
The 'parent' attribute allows a reference to be created to a bean which is in a parent container of the current container.

3.3.2.3. Inner beans

A <bean/> element inside the <property/> or <constructor-arg/> elements is used to define a so-called inner bean.
The "scope" flag and any "id" or "name" attribute are effectively ignored.
Inner beans are always anonymous and they are always scoped as prototypes.

3.3.2.4. Collections

The <list/>, <set/>, <map/>, and <props/> elements.

 

Collection merging
Define a parent-style <list/>, <map/>, <set/> or <props/> element, and have child-style <list/>, <map/>, <set/> or <props/> elements inherit and override values from the parent collection.

 

Strongly-typed collections
If you are using Java 5 or Java 6, you will be aware that it is possible to have strongly typed collections (using generic types).
instances will be converted to the appropriate type prior to being added to the Collection

 

3.3.2.5. Nulls

Set a property to an empty string ("")

 

Set a property to null

3.3.2.6. Shortcuts and other convenience options for XML-based configuration metadata

The <property/> and <constructor-arg/> elements support the "value" and "ref" attributes.
There is no shortcut for <ref local="xxx">

The entry elements supports the "key-ref" and "value-ref" shortcut attributes.

p-namespace
Support for extensible configuration formats using namespaces.
the p-namespace is not defined in an XSD file, and only exists in the core of Spring itself.
Not as flexible as standard format. May clash with properties ending in "Ref"

 

3.3.2.7. Compound property names

Compound or nested property names are perfectly legal when setting bean properties, as long as all components of the path except the final property name are not null.
A NullPointerException will be thrown if a property other than the final one is null.

 

3.3.3. Using depends-on

The "depends-on" attribute may be used to explicitly force one or more beans to be initialized before the bean using this element is initialized.
Applies to both creation and destruction of the beans. Bean with the "depends-on" attribute is created last and destroyed first.

3.3.4. Lazily-instantiated beans

The default behavior for ApplicationContext implementations is to eagerly pre-instantiate all singleton beans at startup.
This can be controlled by the "lazy-init" attribute.
If the lazy-initialized bean is a dependency of a singleton that is not lazy-initialized, the "lazy-init" attribute will be ignored and the bean will be created at start-up.

 

To change the default at a container level

3.3.5. Autowiring collaborators Key

It is possible to automatically let Spring resolve collaborators.
Specified on a per bean basis using the "autowire" attribute of the <bean/> element.

Mode Explanation
no No autowiring at all.
Default mode.
byName Autowiring by property name.
Look for a bean named exactly the same as the property which needs to be autowired
byType Allows a property to be autowired if there is exactly one bean of the property type.
If there is more than one, a fatal exception is thrown.
If there are no matching beans, nothing happens; the property is not set (unless the dependency-check="objects" attribute is set, in which case an error is thrown).
constructor byType for constructor arguments.
autodetect Chooses constructor or byType.

(Pro) Autowiring can significantly reduce the volume of configuration required.
(Pro) Autowiring can cause configuration to keep itself up to date as your objects evolve.
(Con) Autowiring is more magical than explicit wiring.
(Con) Wiring information may not be available to tools that generate documentation.

Multiple matching bean definitions Question
For dependencies that are arrays, collections, or Maps, this is not necessarily a problem as all beans will be wired.

3.3.5.1. Excluding a bean from being available for autowiring

For dependencies that expect a single value,
  • Exclude beans by setting the "autowire-candidate" attribute on the bean element to "false".
  • Specify a single bean by setting the "primary" attribute to "true" on its bean element.
  • Set the "default-autowire-candidates" attribute on the beans element to a pattern that matches the names of the candidate beans.

The "auto-wire" attribute takes precedence over the "default-autowire-candidates" settings.

3.3.6. Checking for dependencies

The "dependency-check" attribute in a bean definition can be used to ensure all properties on a bean are set.

Valid values are: Question

  • "none" - No dependency checking.
  • "simple" - Dependency checking is performed for primitive types and collections (everything except collaborators).
  • "object" - Dependency checking is performed for collaborators only.
  • "all" - Dependency checking is done for collaborators, primitive types and collections.

 

3.3.7. Method Injection

There is a problem when collaborating beans have different lifecycles (i.e. singleton vs prototype). The singleton bean property is only set once and there is no opportunity for the prototype bean to provide a new instance to the singleton bean.

One solution is to use the BeanFactoryAware interface and programmatically get the new instance from the prototype bean.

3.3.7.1. Lookup method injection

Lookup method injection refers to the ability of the container to override methods on container managed beans, to return the result of looking up another named bean in the container.

In the client class containing the method to be injected, the method that is to be 'injected' must have a signature of the following form:

 

An example of lookup method injection:

 

 

You will need to have the CGLIB jar(s) on your classpath.
The class that the container will subclass (to inject the method) cannot be final, and the method that is being overridden cannot be final either.
Objects that have been the target of method injection cannot be serialized.

3.3.7.2. Arbitrary method replacement

3.4. Bean scopes Key

The scopes supported out of the box are listed below:

Scope Description

singleton

Scopes a single bean definition to a single object instance per Spring IoC container.

prototype

Scopes a single bean definition to any number of object instances.

request

Scopes a single bean definition to the lifecycle of a single HTTP request; that is each and every HTTP request will have its own instance of a bean created off the back of a single bean definition. Only valid in the context of a web-aware Spring ApplicationContext.

session

Scopes a single bean definition to the lifecycle of a HTTP Session. Only valid in the context of a web-aware Spring ApplicationContext.

global session

Scopes a single bean definition to the lifecycle of a global HTTP Session. Typically only valid when used in a portlet context. Only valid in the context of a web-aware Spring ApplicationContext.

3.4.1. The singleton scope Question

The Gang of Four (GoF) patterns book's Singleton hard codes the scope of an object such that one and only one instance of a particular class will ever be created per ClassLoader.
The scope of the Spring singleton is best described as per container and per bean.

3.4.2. The prototype scope Question

Use the prototype scope for all beans that are stateful, while the singleton scope should be used for stateless beans.

 

 

The container instantiates, configures, decorates and otherwise assembles a prototype object, hands it to the client and then has no further knowledge of that prototype instance. Therefore the destruction lifecycle callbacks will not be called.

3.4.3. Singleton beans with prototype-bean dependencies

When using singleton-scoped beans that have dependencies on beans that are scoped as prototypes, please be aware that dependencies are resolved at instantiation time.

3.4.4. The other scopes

Only available if you are using a web-aware Spring ApplicationContext implementation.

3.4.4.1. Initial web configuration

Within Spring Web MVC, i.e. within a request that is processed by the Spring DispatcherServlet, or DispatcherPortlet, then no special setup is necessary.

When using a Servlet 2.4+ web container

 

When using a Servlet 2.3 web container

 

3.4.4.2. The request scope

3.4.4.3. The session scope

3.4.4.4. The global session scope

3.4.4.5. Scoped beans as dependencies

Use <aop:scoped-proxy/> to inject session / request scoped bean into another bean.
A proxy is required to provide the correct instance of the session / request scoped bean instead of a single instance when the singleton scoped bean was created.
Set the "proxy-target-class" attribute of the <aop:scoped-proxy/> element to "false" to use the standard JDK interface-based proxies.

3.4.5. Custom scopes

Scopes are defined by the org.springframework.beans.factory.config.Scope interface.
Call the ConfigurableBeanFactory#registerScope() to register the new scope or use the following xml:

3.4.5.1. Creating your own custom scope

3.4.5.2. Using a custom scope

3.5. Customizing the nature of a bean Key

3.5.1. Lifecycle callbacks

Spring provides callback interfaces to change the behavior of your bean in the container.

3.5.1.1. Initialization callbacks

Implementing 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. Question

As an (preferred) alternative, use the bean elements "init-method" attribute.

 

3.5.1.2. Destruction callbacks

Similar to initializing callbacks.
Use org.springframework.beans.factory.DisposableBean interface or "destroy-method" attribute.

3.5.1.3. Default initialization & destroy methods

Use the "default-init-method", "default-destroy-method" on the beans element to invoke the callbacks on any bean that defines the matching method.
Can be over-ridden on a per bean basis using the "init-method" or "destroy-method" attribute.

3.5.1.4. Combining lifecycle mechanisms Question

Three options for controlling bean lifecycle behavior:

  • the InitializingBean and DisposableBean callback interfaces
  • custom init() and destroy() methods
  • the @PostConstruct and @PreDestroy annotations

For initialization, they are called in the following order: @PostConstruct, InitializingBean callback interface, custom configured init() method.

If multiple lifecycle mechanisms are configured for a given bean, and each mechanism is configured with a different method name, then each configured method will be executed in the order listed above; however, if the same method name is configured for more than one of the aforementioned lifecycle mechanisms, that method will only be executed once.

3.5.1.5. Shutting down the Spring IoC container gracefully in non-web applications

Call the AbstractApplicationContext#registerShutdownHook()

3.5.2. Knowing who you are

Implement the BeanFactoryAware interface to get a reference to the BeanFactory.

3.5.2.1. BeanFactoryAware

3.5.2.2. BeanNameAware

3.6. Bean definition inheritance Key

Objectives: 1.5 Bean definition inheritance

A child bean definition is a bean definition that inherits configuration data from a parent definition.
If any init-method, destroy-method and/or static factory method settings are specified, they will override the corresponding parent settings.
The remaining settings will always be taken from the child definition: depends on, autowire mode, dependency check, singleton, scope, lazy init.
Use the "abstract" attribute if the parent definition does not specify a class. This attribute can also be used to prevent the container instantiating singleton parent beans.

 

3.7. Container extension points

3.7.1. Customizing beans using BeanPostProcessors

BeanPostProcessors operate on bean (or object) instances.
An ApplicationContext will automatically detect any beans which are defined in the configuration metadata which is supplied to it that implement the BeanPostProcessor interface.
A BeanFactory implementation, the bean post-processors need to be explicitly registered.
All BeanPostProcessors and their directly referenced beans need to be instantiated on startup. Ensure these beans are not lazy initialized.

Interface has the following methods: #postProcessBeforeInitialization(), #postProcessAfterInitialization()

3.7.1.1. Example: Hello World, BeanPostProcessor-style

3.7.1.2. Example: The RequiredAnnotationBeanPostProcessor

3.7.2. Customizing configuration metadata with BeanFactoryPostProcessors

BeanFactoryPostProcessors are scoped per-container.
Use the Ordered interface to control the calling order.
Ensure these beans are not lazy initialized.

3.7.2.1. Example: the PropertyPlaceholderConfigurer

 

3.7.2.2. Example: the PropertyOverrideConfigurer

Similar to the PropertyPlaceholderConfigurer, but in contrast to the latter, the original definitions can have default values or no values at all for bean properties.

3.7.3. Customizing instantiation logic using FactoryBeans

3.8. The ApplicationContext Key

Objectives: 1.10 The Application Context

The ApplicationContext enhances BeanFactory functionality in a more framework-oriented style.
Normally it is automatically instantiate as part of the normal startup process of a J2EE web-app.

It provides the following (in addition to that provided by the BeanFactory):

  • MessageSource, providing access to messages in i18n-style.
  • Access to resources, such as URLs and files.
  • Event propagation to beans implementing the ApplicationListener interface.
  • Loading of multiple (hierarchical) contexts, allowing each to be focused on one particular layer, for example
    the web layer of an application.

3.8.1. BeanFactory or ApplicationContext?

Feature BeanFactory ApplicationContext
Bean instantiation/wiring
Yes
Yes
Automatic BeanPostProcessor registration
No
Yes
Automatic BeanFactoryPostProcessor registration
No
Yes
Convenient MessageSource access (for i18n)
No
Yes
ApplicationEvent publication
No
Yes

 

3.8.2. Internationalization using MessageSources

When an ApplicationContext gets loaded, it automatically searches for a MessageSource bean defined in the context. The bean has to have the name 'messageSource'.
The following implementations are provided:

  • StaticMessageSource - Provides programmatic ways to add messages to the source
  • ResourceBundleMessageSource - Uses resource bundles defined on your classpath
  • ReloadableResourceBundleMessageSource - Same as ResourceBundleMessageSource, but can read resources from any Spring location and provides hot-reloading.

 

MessageResource implementations follow the same locale resolution and fallback rules as the standard JDK ResourceBundle

ApplicationContext implements the MessageSource interface.
The MessageSourceAware interface can also be used to acquire a reference to any MessageSource that has been defined.

3.8.3. Events

If a bean which implements the ApplicationListener interface is deployed into the context, every time an ApplicationEvent gets published to the ApplicationContext, that bean will be notified.

Event Explanation
ContextRefreshedEvent Published when the ApplicationContext is initialized (all beans are loaded, post-processor beans are detected and activated, singletons are pre-instantiated, and the ApplicationContext object is ready for use) or refreshed (if the ApplicationContext supports hot-refreshes) using the refersh() method.
ContextStartedEvent Published when the ApplicationContext is started, using the start() method.
ContextStoppedEvent Published when the ApplicationContext is stopped, using the stop() method.
ContextClosedEvent Published when the ApplicationContext is closed (all singleton beans are destroyed), using the close() method.
RequestHandledEvent A web-specific event telling all beans that an HTTP request has been serviced (this will be published after the request has been finished).

Event listeners receive events synchronously.

Implementation of an event listener:

 

3.8.4. Convenient access to low-level resources

A Resource is essentially a java.net.URL on steroids.
A bean may implement ResourceLoaderAware callback interface, to be automatically called back at initialization time with the application context itself passed in as the ResourceLoader.
A bean may also expose properties of type Resource that will be injected by the container.

3.8.5. Convenient ApplicationContext instantiation for web applications

 

 

The listener or servlet inspects the 'contextConfigLocation' parameter.
If the parameter does not exist, the listener will use /WEB-INF/applicationContext.xml as a default.
When it does exist, it will separate the String using predefined delimiters (comma, semicolon and whitespace) and use the values as locations where application contexts will be searched for.

 

3.9. Glue code and the evil singleton

3.10. Deploying a Spring ApplicationContext as a J2EE RAR file

RAR deployment is intended as a more 'natural' alternative to the not uncommon scenario of deploying a headless WAR file.
See SpringContextResourceAdapter class JavaDoc for the configuration details involved in RAR deployment

3.11. Annotation-based configuration Key Question

Objectives: 1.12 Annotation-based Dependency injection

The RequiredAnnotationBeanPostProcessor”, using a BeanPostProcessor in conjunction with annotations is a common means of extending the Spring IoC container.

 

The implicitly registered post-processors include: AutowiredAnnotationBeanPostProcessor, CommonAnnotationBeanPostProcessor, PersistenceAnnotationBeanPostProcessor and RequiredAnnotationBeanPostProcessor.
<context:annotation-config/> only looks for annotations on beans in the same application context it is defined in.

3.11.1. @Required

This annotation applies to bean property setter methods.
The targeted bean property must be populated at configuration time: either through an explicit property value in a bean definition or through autowiring.
The container will throw an exception if the affected bean property has not been populated.

3.11.2. @Autowired Question

@Autowired is fundamentally about type-driven injection.

This annotation applies to bean property setter methods, fields, constructors and to methods with arbitrary names and/or multiple arguments. Question
Use with an array or typed collection (including a Map as long as the key type is a String) to provide all beans of a particular type.

By default, the autowiring will fail whenever zero candidate beans are available. Use "required=false" to change this behavior.

Only one annotated constructor per-class may be marked as required, but multiple non-required constructors can be annotated. In that case, each will be considered among the candidates and Spring will use the greediest constructor whose dependencies can be satisfied.

@Required vs Autowired(required=true)
Prefer the use of @Autowired's required attribute over the @Required annotation. The required attribute indicates that the property is not required for autowiring purposes, simply skipping it if it cannot be autowired.
@Required, on the other hand, is stronger in that it enforces the property to have been set in any of the container's supported ways; if no value has been injected, a corresponding exception will be raised.

Well-known "resolvable dependencies"
@Autowired may also be used for well-known "resolvable dependencies" (and their extended interfaces): BeanFactory, ApplicationContext, ResourceLoader, ApplicationEventPublisher, MessageSource interface.

3.11.3. Fine-tuning annotation-based autowiring with qualifiers

The @Qualifier annotation can also be specified on individual constructor arguments or method parameters.
For a fallback match, the bean name is considered as a default qualifier value.

 

@Autowired vs @Resource Question
Injection by name use the JSR-250 @Resource annotation which is semantically defined to identify a specific target component by its unique name, with the declared type being irrelevant for the matching process.
@Resource is only supported for fields and bean property setter methods with a single argument.

@Autowired is fundamentally about type-driven injection (even if is technically capable of referring to a bean name through @Qualifier values).
It is applicable to fields, constructors and multi-argument methods.

Custom qualifier annotations

3.11.4. CustomAutowireConfigurer

This allows you to register your own custom qualifier annotation types even if they are not themselves annotated with Spring's @Qualifier annotation.

3.11.5. @Resource Question

Supports injection using the JSR-250 @Resource annotation on fields or bean property setter methods using by-name semantics.
If no name is specified explicitly, then the default name will be derived from the name of the field or setter method.
@Resource may fall back to standard bean type matches (i.e. find a primary type match instead of a specific named bean) as well as resolve well-known "resolvable dependencies".

3.11.6. @PostConstruct and @PreDestroy Question

These are the JSR-250 lifecycle annotations and are an alternative to the initialization and destruction callbacks.

3.12. Classpath scanning for managed components

Beans can be defined using XML or (Since Spring 2.0) by implicitly detecting the candidate components ('stereotyped' classes) by scanning the classpath and matching against filters.

3.12.1. @Component and further stereotype annotations

@Repository, @Component, @Service and @Controller are used to identify Spring components (i.e. BeanDefinitions).

3.12.2. Auto-detecting components

To autodetect these classes and register the corresponding beans, use the following:
This implicitly includes: AutowiredAnnotationBeanPostProcessor, CommonAnnotationBeanPostProcessor

3.12.3. Using filters to customize scanning

Detecting candidate components can be customized using either include-filter or exclude-filter elements.

Filter Type Example Expression Description
annotation org.example.SomeAnnotation An annotation to be present at the type level in target components.
assignable org.example.SomeClass A class (or interface) that the target components are assignable to (extend/implement).
aspectj org.example..*Service+ An AspectJ type expression to be matched by the target components.
regex org\.example\.Default.* A regex expression to be matched by the target components' class names.
custom org.example.MyCustomTypeFilter A custom implementation of the org.springframework.core.type.TypeFilter interface.

Disable default filters by using the use-default-filters="false" attribute of the "component-scan" element.

3.12.4. Naming autodetected components

When a component is autodetected as part of the scanning process, its bean name will be generated by the BeanNameGenerator strategy.
If the annotation contains no name value, the default bean name generator will return the uncapitalized non-qualified class name.

 

A custom bean-naming strategy can be provided by implementing the BeanNameGenerator and using the "name-generator" attribute on the "component-scan" element.

3.12.5. Providing a scope for autodetected components

Use @Scope("prototype") to define the scope.
For custom scopes, implement the ScopeMetadataResolver interface and register using the "scope-resolver" attribute on the "component-scan" element.
When mixing scopes, use the "scoped-proxy" attribute on the "component-scan" element to generate a proxy. Valid values are "no", "interfaces" and "targetClass".

3.12.6. Providing qualifier metadata with annotations

Note: Annotation metadata is bound to the class definition itself, while the use of XML allows for multiple beans of the same type to provide variations in their qualifier metadata since that metadata is provided per-instance rather than per-class.

3.13. Registering a LoadTimeWeaver

4. Resources

Resource is essentially a java.net.URL on steroids.

4.1. Introduction

4.2. The Resource interface

Important methods:

  • getInputStream(): locates and opens the resource
  • exists(): returns a boolean indicating whether this resource actually exists in physical form.
  • isOpen(): returns a boolean indicating whether this resource represents a handle with an open stream.
  • getDescription(): returns a description for this resource, to be used for error output when working with the resource. This is often the fully qualified file name or the actual URL of the resource.

4.3. Built-in Resource implementations

Objectives: 1.10 The Application Context

4.3.1. UrlResource

The UrlResource wraps a java.net.URL and supports file:, http: and ftp: protocols.

4.3.2. ClassPathResource

This class represents a resource which should be obtained from the classpath.
The container will recognize the special prefix classpath: and create a ClassPathResource in that case.

4.3.3. FileSystemResource

This is a Resource implementation for java.io.File handles.

4.3.4. ServletContextResource

This is a Resource implementation for ServletContext resources, interpreting relative paths within the relevant web application's root directory.

4.3.5. InputStreamResource

A Resource implementation for a given InputStream. This should only be used if no specific Resource implementation is applicable. In particular, prefer ByteArrayResource or any of the file-based Resource implementations where possible.

4.3.6. ByteArrayResource

4.4. The ResourceLoader Key

When you call getResource() on a specific application context, and the location path specified doesn't have a specific prefix, you will get back a Resource type that is appropriate to that particular application context.
For example, if executed against a ClassPathXmlApplicationContext, a ClassPathResource would be returned.

Prefix Example Explanation
classpath: classpath:com/myapp/config.xml Loaded from the classpath.
file: file:/data/config.xml Loaded as a URL, from the filesystem.
http: http://myserver/logo.png Loaded as a URL.
(none) /data/config.xml Depends on the underlying ApplicationContext.

 

4.5. The ResourceLoaderAware interface

The ResourceLoaderAware interface is a special marker interface, identifying objects that expect to be provided with a ResourceLoader reference.

4.6. Resources as dependencies

4.7. Application contexts and Resource paths

4.7.1. Constructing application contexts

4.7.1.1. Constructing ClassPathXmlApplicationContext instances - shortcuts

4.7.2. Wildcards in application context constructor resource paths

The resource paths in application context constructor values:

  • may be a simple path which has a one-to-one mapping to a target Resource
  • may contain internal Ant-style regular expressions (matched using Spring's PathMatcher utility)
  • may contain the special "classpath*:" prefix

4.7.2.1. Ant-style Patterns

This produces a Resource for the path up to the last non-wildcard segment and obtains a URL from it.
If this URL is not a "jar:" URL or container-specific variant (e.g. "zip:" in WebLogic, "wsjar" in WebSphere, etc.), then a java.io.File is obtained from it and used to resolve the wildcard by traversing the filesystem.
In the case of a jar URL, the resolver either gets a java.net.JarURLConnection from it or manually parses the jar URL and then traverses the contents of the jar file to resolve the wildcards.

4.7.2.2. The classpath*: prefix

All classpath resources that match the given name must be obtained.
Behavior depends on the underlying classloader.

4.7.2.3. Other notes relating to wildcards

4.7.3. FileSystemResource caveats

5. Validation, Data-binding, the BeanWrapper, and PropertyEditors

5.1. Introduction

Validation should not be tied to the web tier, should be easy to localize and it should be possible to plug in any validator available.
The Validator and the DataBinder make up the validation package.

5.2. Validation using Spring's Validator interface

Important methods:

  • supports(Class) - Can this Validator validate instances of the supplied Class?
  • validate(Object, org.springframework.validation.Errors) - validates the given object and in case of validation errors, registers those with the given Errors object

Use the he ValidationUtils helper class to implement a custom Validator.

5.3. Resolving codes to error messages

5.4. Bean manipulation and the BeanWrapper

Objectives: 1.6 Property Editors

5.4.1. Setting and getting basic and nested properties

Expression Explanation
name Indicates the property name corresponding to the methods getName() or isName() and setName(..)
account.name Indicates the nested property name of the property account corresponding e.g. to the methods getAccount().setName() or getAccount().getName()
account[2] Indicates the third element of the indexed property account. Indexed properties can be of type array, list or other naturally ordered collection
account[COMPANYNAME] Indicates the value of the map entry indexed by the key COMPANYNAME of the Map property account

 

5.4.2. Built-in PropertyEditor implementations Key

Class Explanation
ByteArrayPropertyEditor Editor for byte arrays. Strings will simply be converted to their corresponding byte representations. Registered by default by BeanWrapperImpl.
ClassEditor Parses Strings representing classes to actual classes and the other way around. When a class is not found, an IllegalArgumentException is thrown. Registered by default by BeanWrapperImpl.
CustomBooleanEditor Customizable property editor for Boolean properties. Registered by default by BeanWrapperImpl, but, can be overridden by registering custom instance of it as custom editor.
CustomCollectionEditor Property editor for Collections, converting any source Collection to a given target Collection type.
CustomDateEditor Customizable property editor for java.util.Date, supporting a custom DateFormat. NOT registered by default. Must be user registered as needed with appropriate format.
CustomNumberEditor Customizable property editor for any Number subclass like Integer, Long, Float, Double. Registered by default by BeanWrapperImpl, but can be overridden by registering custom instance of it as a custom editor.
FileEditor Capable of resolving Strings to java.io.File objects. Registered by default by BeanWrapperImpl.
InputStreamEditor One-way property editor, capable of taking a text string and producing (via an intermediate ResourceEditor andResource) an InputStream, so InputStream properties may be directly set as Strings. Note that the default usage will not close the InputStream for you! Registered by default by BeanWrapperImpl.
LocaleEditor Capable of resolving Strings to Locale objects and vice versa (the String format is [language]_[country]_[variant], which is the same thing the toString() method of Locale provides). Registered by default by BeanWrapperImpl.
PatternEditor Capable of resolving Strings to JDK 1.5 Pattern objects and vice versa.
PropertiesEditor Capable of converting Strings (formatted using the format as defined in the Javadoc for the java.lang.Properties class) to Properties objects. Registered by default by BeanWrapperImpl.
StringTrimmerEditor Property editor that trims Strings. Optionally allows transforming an empty string into a null value. NOT registered by default; must be user registered as needed.
URLEditor Capable of resolving a String representation of a URL to an actual URL object. Registered by default by BeanWrapperImpl.

Registration of Property Editors
Standard JavaBeans infrastructure will automatically discover PropertyEditor classes (without you having to register them explicitly) if they are in the same package as the class they handle, and have the same name as that class, with 'Editor' appended.
The standard BeanInfo JavaBeans mechanism can also be used.

5.4.2.1. Registering additional custom PropertyEditors Question

Use the registerCustomEditor() method of the ConfigurableBeanFactory interface (not recommended).


Use a special bean factory post-processor called CustomEditorConfigurer.

Create and use a PropertyEditorRegistrar (which is injected into the CustomEditorConfigurer "propertyEditorRegistrars" property)
A PropertyEditorRegistrar is expected to create fresh PropertyEditor instances for each bean creation attempt.

8. Testing

Objectives: 1.11 Testing

8.1. Introduction Key

Unit Tests
In computer programming, unit testing is a software verification and validation method in which a programmer tests if individual units of source code are fit for use.
A unit is the smallest testable part of an application.
Ideally, each test case is independent from the others: substitutes like method stubs, mock objects, fakes and test harnesses can be used to assist testing a module in isolation.
Unit tests are typically written and run by software developers to ensure that code meets its design and behaves as intended.

Integration Tests
Integration testing is the phase in software testing in which individual software modules are combined and tested as a group.
It occurs after unit testing and before system testing. Integration testing takes as its input modules that have been unit tested, groups them in larger aggregates, applies tests defined in an integration test plan to those aggregates, and delivers as its output the integrated system ready for system testing.

 

8.2. Unit testing Key

One of the main benefits of Dependency Injection is that your code should really depend far less on the container than in traditional J2EE development.
For tests, Objects can be instantiated using the new operator, without Spring or any other container.
Following Spring architecture recommendations will result in clean layering and componentization of your codebase will naturally facilitate easier unit testing.

Stubs
A stub is a piece of code used to stand in for some other programming functionality.
A stub is a routine that doesn't actually do anything other than declare itself and the parameters it accepts and returns something that is usually the values expected in one of the "happy scenarios" for the caller.

Mocks
A mock object is a simulated object that mimics the behavior of the real object in controlled ways.

8.2.1. Mock objects

8.2.1.1. JNDI

The org.springframework.mock.jndi package contains an implementation of the JNDI SPI, which is useful for setting up a simple JNDI environment for test suites or stand-alone applications.

8.2.1.2. Servlet API

The org.springframework.mock.web package contains a comprehensive set of Servlet API mock objects, targeted at usage with Spring's Web MVC framework, which are useful for testing web contexts and controllers.

8.2.1.3. Portlet API

8.2.2. Unit testing support classes

8.2.2.1. General utilities

The org.springframework.test.util package contains ReflectionTestUtils, which is a collection of reflection-based utility methods that can be used to test non-public methods.

8.2.2.2. Spring MVC

8.3. Integration testing

8.3.1. Overview

Support for unit and integration testing in the form of the Spring TestContext Framework.
Spring TestContext Framework requires Java 5.
Agnostic of the actual testing framework (i.e. can be used with JUnit 3.8, JUnit 4.4 and TestNG)

8.3.2. Which support framework to use

8.3.3. Common goals Key

Spring testing support offers:

  • Spring IoC container caching between test execution.
  • Dependency Injection of test fixture instances.
  • Transaction management appropriate to integration testing.
  • Spring-specific support classes that are really useful when writing integration tests.

8.3.3.1. Context management and caching Key

Spring integration testing support frameworks provide consistent loading of Spring ApplicationContexts and caching of those contexts (loaded once per test fixture).

8.3.3.2. Dependency Injection of test fixtures Key

Configure instances of your test classes via Dependency Injection.

8.3.3.3. Transaction management Key

By default, they create and roll back a transaction for each test.
Transactionally proxied objects in your tests will behave correctly, according to their transactional semantics.

8.3.3.4. Integration testing support classes Key

Abstract support classes provide well defined hooks into the testing framework as well as convenient instance variables and methods (such as the ApplicationContext and SimpleJdbcTemplate)

8.3.4. JDBC testing support

8.3.5. Common annotations Key

@IfProfileValue - Indicates that the annotated test is enabled for a specific testing environment. Can be applied to a class or to individual methods.

@ProfileValueSourceConfiguration - Class-level annotation which is used to specify what type of ProfileValueSource to use when retrieving profile values configured via the @IfProfileValue annotation.

@DirtiesContext - indicates that the underlying Spring container is 'dirtied' during the execution of the test method, and thus must be rebuilt after the test method finishes execution. Question

@ExpectedException - Indicates that the annotated test method is expected to throw an exception during execution.

@Timed - Indicates that the annotated test method has to finish execution in a specified time period (in milliseconds).

@Repeat - Indicates that the annotated test method must be executed repeatedly.

@Rollback - Indicates whether or not the transaction for the annotated test method should be rolled back after the test method has completed.

@NotTransactional - The presence of this annotation indicates that the annotated test method must not execute in a transactional
context.

8.3.6. JUnit 3.8 legacy support

8.3.6.1. Context management and caching

Extend AbstractSingleSpringContextTests

8.3.6.2. Dependency Injection of test fixtures

Extend AbstractDependencyInjectionSpringContextTests

8.3.6.3. Transaction management

Extend AbstractTransactionalDataSourceSpringContextTests.

8.3.6.4. JUnit 3.8 legacy support classes

8.3.6.5. Java 5+ specific support

Extend AbstractAnnotationAwareTransactionalTests to use Spring common annotations.

8.3.7. Spring TestContext Framework

8.3.7.1. Key abstractions Key

The core of the framework consists of the TestContext and TestContextManager classes and the TestExecutionListener interface.

TestContext - encapsulates the context in which a test is executed. Question

TestContextManager - the main entry point into the Spring TestContext Framework, which is responsible for managing a single TestContext and signaling events to all registered TestExecutionListeners at well defined test execution points: test instance preparation, prior to any before methods of a particular testing framework, and after any after methods of a particular testing framework.

TestExecutionListener - defines a listener API for reacting to test execution events published by the TestContextManager with which the listener is registered.

@TestExecutionListeners - Defines class-level metadata for configuring which TestExecutionListeners should be registered with a TestContextManager.

8.3.7.2. Context management and caching Key

If a test class implements the ApplicationContextAware interface, a reference to the ApplicationContext will be supplied to the test instance.

Use the @ContextConfiguration annotation at the class level to inject the TestContext. Question
If no locations are defined, the default location is based on the name of the test class (i.e. MyTest-context.xml).

8.3.7.3. Dependency Injection of test fixtures

Use @Autowired or @Resource to inject dependencies into your test instances.

8.3.7.4. Transaction management Key

To enable support for transactions, provide a PlatformTransactionManager bean in the application context loaded via @ContextConfiguration semantics.
Also @Transactional must be declared at either the class or method level.
@TransactionConfiguration can be used to customise the bean name for the transaction manager and the default rollback flag.
@BeforeTransaction and @AfterTransaction allows for the execution of code outside the transaction.

Note: JUnit @Before and @After methods are executed within the transaction.

8.3.7.5. TestContext support classes

@Runwith(SpringJUnit4ClassRunner.class) allows developers to implement standard JUnit 4.4 unit and integration tests and simultaneously reap the benefits of the TestContext framework such as support for loading application contexts, dependency injection of test instances, transactional test method execution, etc.

This is an alternative to extending the Spring Test Framework support classes.

8.3.7.6. TestContext framework annotation support

8.3.8. PetClinic example

8.4. Further Resources

A. XML Schema-based configuration

A.1. Introduction

DTD vs Schema-based approach: Ends up as same object model, but Schema-based approach allows you to have more succinct and clearer configuration.

A.2. XML Schema-based configuration Key

DTD-based

 

Schema-based

A.2.1. Referencing the schemas

A.2.2. The util schema Key

Objectives: 1.9 The util namespace

A.2.2.1. <util:constant/>

Used to set a value of a property using a static constant.

DTD-based

 

Scheme-based

 

Injecting enum values is automatically handled by Spring.
FieldRetrievingFactoryBean is a FactoryBean which retrieves a static (using the staticField property) or non-static field value.

A.2.2.2. <util:property-path/>

Uses the PropertyPathFactoryBean, to create a bean from the "age" property of the "testBean" bean.

DTD-based

 

Scheme-based

A.2.2.3. <util:properties/>

Creates a java.util.Properties instance (using the PropertiesFactoryBean) with values loaded from the supplied location

Schema-based

A.2.2.4. <util:list/>

Creates a java.util.List instance (using ListFactoryBean) with values loaded from the supplied 'sourceList'
The "list-class" attribute is optional and allows you to explicitly control the exact type of List that will be instantiated and populated.

Schema-based

A.2.2.5. <util:map/>

Creates a java.util.Map instance (using MapFactoryBean) with values loaded from the supplied 'sourceMap'.

Schema-based

A.2.2.6. <util:set/>

Creates a java.util.Set instance (using SetFactoryBean) with values loaded from the supplied 'sourceSet'.

Schema-based