Objectives: 1.1 Goals of the Spring Framework
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
Objectives: 1.4 Writing bean definitions
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
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:
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".
These bean definitions are represented as BeanDefinition objects and have the following metadata:
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'
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:
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.
The BeanFactory interface has just a few other methods (like #getBean), but ideally your application code should never use them..
Objectives: 1.4 Writing bean definitions
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.
Effected by invoking a constructor with a number of arguments, each representing a dependency.
Constructor Argument Resolution
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.
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
(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.
(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
Bean dependency resolution
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.
Static factory (arguments to the static factory method are supplied via <constructor-arg/> elements)
Dependencies can be defined as either references to other managed beans (collaborators), or values defined inline.
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).
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.
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.
The <list/>, <set/>, <map/>, and <props/> elements.
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.
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
Set a property to an empty string ("")
Set a property to null
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.
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"
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.
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.
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
possible to automatically let Spring resolve collaborators.
Specified on a per bean basis using the "autowire" attribute of the <bean/> element.
|no||No autowiring at all.
|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
For dependencies that are arrays, collections, or Maps, this is not necessarily a problem as all beans will be wired.
The "auto-wire" attribute takes precedence over the "default-autowire-candidates" settings.
The "dependency-check" attribute in a bean definition can be used to ensure all properties on a bean are set.
Valid values are:
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.
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
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.
The scopes supported out of the box are listed below:
Scopes a single bean definition to a single object instance per Spring IoC container.
Scopes a single bean definition to any number of object instances.
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
Scopes a single bean definition to the lifecycle of a HTTP
Scopes a single bean definition to the lifecycle of a
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.
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.
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.
Only available if you are using a web-aware Spring ApplicationContext implementation.
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
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.
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:
Spring provides callback interfaces to change the behavior of your bean in the container.
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.
As an (preferred) alternative, use the bean elements "init-method" attribute.
Similar to initializing callbacks.
Use org.springframework.beans.factory.DisposableBean interface or "destroy-method" attribute.
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.
Three options for controlling bean lifecycle behavior:
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.
Call the AbstractApplicationContext#registerShutdownHook()
Implement the BeanFactoryAware interface to get a reference to the BeanFactory.
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.
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()
BeanFactoryPostProcessors are scoped per-container.
Use the Ordered interface to control the calling order.
Ensure these beans are not lazy initialized.
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.
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):
|Automatic BeanPostProcessor registration||
|Automatic BeanFactoryPostProcessor registration||
|Convenient MessageSource access (for i18n)||
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:
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.
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.
|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:
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.
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.
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
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.
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.
@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.
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.
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
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
This allows you to register your own custom qualifier annotation types even if
they are not themselves annotated with Spring's @Qualifier annotation.
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".
These are the JSR-250 lifecycle annotations and are an alternative to the initialization and destruction callbacks.
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.
@Repository, @Component, @Service and @Controller are used to identify Spring components (i.e. BeanDefinitions).
To autodetect these classes and register the corresponding beans, use the following:
This implicitly includes: AutowiredAnnotationBeanPostProcessor, CommonAnnotationBeanPostProcessor
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.
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.
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".
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.
Resource is essentially a java.net.URL on steroids.
Objectives: 1.10 The Application Context
The UrlResource wraps a java.net.URL and supports file:, http: and ftp: protocols.
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.
This is a Resource implementation for java.io.File handles.
This is a Resource implementation for ServletContext resources, interpreting relative paths within the relevant web application's root directory.
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.
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.
|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.|
The ResourceLoaderAware interface is a special marker interface, identifying objects that expect to be provided with a ResourceLoader reference.
The resource paths in application context constructor values:
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.
All classpath resources that match the given name must be obtained.
Behavior depends on the underlying classloader.
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.
Use the he ValidationUtils helper class to implement a custom Validator.
Objectives: 1.6 Property Editors
|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||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|
|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.
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.
Objectives: 1.11 Testing
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 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.
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.
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.
A mock object is a simulated object that mimics the behavior of the real object in controlled ways.
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.
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.
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.
Support for unit and integration testing in the form of the Spring TestContext
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)
Spring testing support offers:
Spring integration testing support frameworks provide consistent loading of Spring ApplicationContexts and caching of those contexts (loaded once per test fixture).
Configure instances of your test classes via Dependency Injection.
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.
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)
@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.
@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
Extend AbstractAnnotationAwareTransactionalTests to use Spring common annotations.
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.
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.
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.
If no locations are defined, the default location is based on the name of the test class (i.e. MyTest-context.xml).
Use @Autowired or @Resource to inject dependencies into your test instances.
To enable support for transactions,
provide a PlatformTransactionManager bean in the application context loaded via @ContextConfiguration
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.
@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.
DTD vs Schema-based approach: Ends up as same object model, but Schema-based approach allows you to have more succinct and clearer configuration.
Objectives: 1.9 The util namespace
Used to set a value of a property using a static constant.
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.
Uses the PropertyPathFactoryBean, to create a bean from the "age" property of the "testBean" bean.
Creates a java.util.Properties instance (using the PropertiesFactoryBean) with values loaded from the supplied location
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.
Creates a java.util.Map instance (using MapFactoryBean) with values loaded from the supplied 'sourceMap'.
Creates a java.util.Set instance (using SetFactoryBean) with values loaded from the supplied 'sourceSet'.