This post is below my usual quality standards, it’s just
bunch of notes that I made while reading “Spring in Action”.
Still I publish it mostly for myself but I hope someone may
find it helpful too.
Registering and using beans via Spring
Let’s start with simple StdOutNotificationService bean:
To register it with Spring we must add the following configuration
file as a resource to our application:
NOTE: The id attribute of bean element is optional - we can refer to beans
either by their name or their type.
Now we may create ApplicationContext from our configuration file
and finally use our beans:
Injection using constructor
Let’s start with a simple example ConstructorDemo bean requires two
other beans (NotificationService and SystemUserNameProvider) to work:
In this case we should use Spring constructor-arg element to
tell Spring how it should resolve constructor arguments:
We must provide all constructor arguments
otherwise Spring will throw UnsatisfiedDependencyException.
The order of constructor-arg elements is not important because
arguments are matched by type.
In these rare cases when ambiguity arise we may use name and index attributes
of constructor-arg element to specify to which parameter dependency should
be bound, for example:
When providing constructor arguments we are not limited to
references to other beans, we may also provide standard Java types like
String. For example given bean:
We may register it as follows (Spring will take care of converting strings
to apropriate types):
Sometimes we want to set some constructor arguments to null,
we may use <null /> element to do exactly that:
Injection using setters
The most popular industry convention is that all required bean dependencies should
be injected via constructor and optional dependencies via setters.
Let’s see how it works on example: FooService bean
requires BarService and has optional dependency on BazService.
This means that even without BazServiceFooService will work but
some features will not be accessible.
And here is configuration for our example:
Property injection can also be used to populate JavaBeans,
for example given bean:
As with constructor-arg we use ref attribute to refer to other beans and
value attribute to provide inline value. We can set property value to null
Since writing property may be tiring (at least in case of JavaBeans) there
is a shortcut, first we must add XML p namespace to configuration file:
Then we may use p:<propertyName>=value syntax in configuration:
There is also short cut for <property name="" ref="" />, just add -ref to
the end of property name e.g. p:bazService-ref="baz".
Sometime we want to inject not single beans but collections of beans, for
example given bean:
To wire list of selected MessageFilters into MessageFilterService
we must use list element:
To wire list of values we may write:
When injecting collections we are not limited to list,
we may also inject set, map and
props (instance of java.util.Properties):
By default Spring tread are registered beans as singletons, to change
lifetime of bean use scope attribute:
Two most useful Spring scopes in console applications are
singleton - only single instance of bean will exists per ApplicationContext
prototype - create new bean instance per usage (if we inject bean three times
we will get three instances)
Springs also supports request and session scopes, they are
mainly used in Spring MVC/Spring Boot applications.
Sometimes we want to create bean just to inject it in one place,
instead of writing:
We may write:
Init and Destroy events
Sometimes we want Spring to call initialization method after bean
instance is created, and likewise to call bean cleanup method just
before ApplicationContext is destroyed.
To specify such methods we may use bean element
init-method and destroy-method attributes:
And a bean:
Creating beans using factory method
Given singleton implementation:
We may register it in Spring as a bean using configuration:
Here we are just telling Spring to create mySingleton bean
by invoking method getInstance() on MySingleton class.