Introduction to Spring Framework 3
Introduction to Spring Framework 3
Currently, the development of enterprise applications is simpler as there are many tools, APIs, and
Frameworks; which, although optional, learning to use them will help us develop our applications in less time.
and for them to be more robust and contain fewer errors.
It also becomes a bit more complicated because our applications must be able to connect with other applications and
services. In addition, as developers, we are responsible for coordinating each part of our application so that
all function correctly.
As if that weren't enough, we must take into account that we need to maintain our applications, and that in some cases
It will be necessary for us to change entire modules or layers of it to improve it; for example, to replace our queries.
JDBC with Hibernate in cases where it is prudent.
Fortunately, there are super-frameworks that help us by taking care of all or almost all the 'complications'
mentioned [Link] is the most popular of these Java super-frameworks. It provides us with several modules which
they encompass most of the things we need to do in any of the layers of our applications, from templates for
working with JDBC or invoking Web Services and JMS, through their own solutions, ORM or MVC (web), up to integration
with other frameworks like Struts 2, Hibernate, JSF, etc. All this in an elegant way and making use of many good
programming principles. Additionally, Spring manages the application's infrastructure, so we will only need to
to worry about its logic (and the configuration of Spring).
In this series of tutorials, we will learn how to use Spring, in its version 3, to make our lives easier in the development of our
Java applications. To learn how to use Spring correctly, you need to see a lot of theory, so in this first tutorial
We will only talk about the basic concepts of Spring and I will explain each part, along with its corresponding theory, in the post.
corresponding.
Spring is, as its authors define it, a lightweight framework for building enterprise applications. Although Spring is found
divided into different modules, each of which is responsible for different parts of our application, is still a
monster, since it is so large that someone could never use all these modules in small or medium applications; but in
Large or really large applications can save us a lot of work as they can coordinate all parts of the application.
This separation into modules allows us to use only the parts we need, without carrying the burden of those we do not use.
Spring is designed to be non-intrusive, which means that it is not necessary for our application to extend or implement any
class or interface of Spring (if we do not want it), so our logic code will remain free and completely reusable for a
project without Spring, or in case we need to remove it from an application that is already using it. Thanks to this, it is possible to use a POJO or a
Java object to do things that could only be done with EJBs before. However, the utility of Spring is not only for development.
of web applications, or not only on the server. Any Java application can benefit from using Spring.
Additionally, if we use Spring correctly (which is not difficult), our application will be divided into well-defined layers, and
with good programming practices.
The core of Spring is based on a principle or design pattern called Inversion of Control (IoC for its acronym in English). The
Applications that use the IoC principle are based on their configuration (which in this case can be in XML files or with
annotations like in Hibernate) to describe the dependencies between its components, that is, the other objects with which
interact. In this case, 'inversion' means that the application does not control its structure; it allows the IoC framework to do so.
(Spring case) whoever does it.
For example, let's assume we have a class 'UserStore', which depends on an instance of a class 'UsersDAO' to
complete your task. 'AlmacenUsuario' creates an instance of 'UsuariosDAO' using the 'new' operator or obtains one of some type of
Factory. Using the IoC technique, an instance of 'UsuariosDAO', or a subclass of it, is provided to 'AlmacenUsuario' in
runtime by the Spring engine. In this case, 'UsuariosDAO' could also be an interface, and Spring will take care of
provide us with an instance of a class that implements that interface. This dependency injection at runtime has
fact that this type of IoC is given the more descriptive name of dependency injection (DI for its initials in English). The
An important concept is that the components do not know which specific implementation of other components they are using; they only see their
interfaces.
The use of interfaces and DI are mutually beneficial, as it makes our application more flexible and robust and is much easier.
perform unit tests. But the complexity of writing code that handles the dependencies between the components of a
application designed to use interfaces can become a lot and this, besides, makes developers have to write
still more code.
Fortunately, by using DI we reduce the amount of extra code we need to write for an interface-based design to almost
zero.
In the context of DI, Spring acts as a container that provides instances of the classes of our application all the time.
dependencies it needs, but in a non-intrusive and automatic way. All we have to do is create a file of
configuration what describe the dependencies; Spring he will do cargo of restaurant
As I said before: Spring is a container because it not only creates the components of our application but also contains and manages.
the life cycle and configuration of these components. In Spring, we can declare how each of the objects should be created.
our application how must to be configured, y how must to associate with the others.
The implementation of Spring DI focuses on loose coupling: the components of our application should assume the least.
possible regarding other components. The easiest way to achieve this low coupling in Java is through the use of Interfaces.
Since each component of the application is only aware of the interface of other components, we can change the
implementation of the component without affecting the components that use the new component. I will talk a little more about this when
let's see the examples.
The use of DI has benefits, in addition to what I have already mentioned above, the following:
• Reduce glue code: This means it dramatically reduces the amount of code we have to write to
join the different components. Although sometimes this code can be as simple as using the 'new' operator to
instantiate a new object, others can be more complex, such as performing a search for that dependency in a
repository through JNDI, as in the case of remote resources. In this case, the use of DI can reduce significantly
dramatic the amount of glue code providing automated searches.
• Externalize dependencies: Since it is possible to place the dependency configuration in XML files, we can achieve
an easy reconfiguration, without the need to recompile our code. Thanks to this, it is possible to change the
implementation of one dependency on another (like in the Hibernate example I mentioned earlier)
• Dependencies are managed in one place: All dependency information is the responsibility of one person.
component, the IoC container of Spring, making this dependency management simpler and less prone to
errors.
• Makes testing easier: Again, as our classes will be designed to make replacement easy
dependencies, we can provide mocks or dummies that return test data from services or any dependency
that needs the component we are testing.
As we can see, the use of DI provides us with many benefits, but not without its corresponding disadvantages. In particular, it is
it's hard to see which particular implementation of a dependency is being used for which object, especially for someone who does not
You are familiar with this way of working.
And why so much talk about DI? Well, because these two concepts (IoC and DI) are the central points around which everything revolves.
Spring, so it's better to understand them from the beginning ^_^.
As I said: Spring is divided into about 20 modules and placed in the following groups:
• Core Container
• Data Access / Integration
• WEB
• AOP (Aspect-Oriented Programming)
• Instrumentation
• Tests
Version 3 of Spring is a revised and improved version of the previous stable version (2.5), which includes new features, among which are
include:
• Support for Java 5: Provides annotation-based configuration and supports features like varargs and generics, plus the part
the web is compatible with versions 1.4 and 5 of Java EE. Due to this new feature, it is now necessary to have the JRE version 5 or
superior.
• Expression Language (SpEL): This new version includes an expression language that can be used when defining
beans, both in XML and with annotations, and also provides support across all Spring modules.
• Support for REST Web Services: Now Spring supports REST-type web services.
• Support for Java EE6: Offers support for features like JPA 2.0, JSF 2.0, and JRS 303 (Bean validations).
• Support for embedded databases: A convenient support for embedded databases like HSQL, H2, and Derby.
• Support for data formatting through annotations: Now date fields, currencies, etc., will be automatically formatted and
converted using annotations.
• New organization of the modules: The modules have been reviewed and separated into different, more organized packages, according to their
functionality. To give you an idea, these are the new packages:
o [Link]
o [Link]
o [Link]
o [Link]
o [Link]
o [Link]
o [Link]
o [Link]
o [Link]
o [Link]
o [Link]
o [Link]
o [Link]
o [Link]
o [Link]
o [Link]
Throughout these tutorials we will see some of these packages. Although this post, as you may have realized, is only theoretical, we will create the
library forNetBeansof Spring that we will be using in this series of tutorials.
So the first thing we will do is open NetBeans. In fact, NetBeans 9 already has a Spring 3 library, version 3.0.2.
But there have been updates since this version (currently the newest version is 3.0.4). So what we will do is create a new one.
library that will use the jars we need (which we will be increasing in each tutorial).
Once we have downloaded the Spring file, we unzip it and we will see that it has a subdirectory 'dist' which contains all the jars of
Spring for each of its modules. Let's go to NetBeans and navigate to the menu 'Tools -> Libraries'.
In the window that opens, we press the button 'New Library...':
In this new window, we set the name of the library as "Spring3" and leave the type as "Class Libraries":
Now that we have our library, we press the "Add Jar/Folder" button to add the new files that will make up the library:
We added the following files to the library:
• [Link]
• [Link]
• [Link]
• [Link]
• [Link]
• [Link] (which we downloaded separately)
With these, it's enough to make our initial hello worlds :D. Once these files are selected, our library should look like this:
We press the "OK" button and our library will be ready to use... in the following tutorials ^_^.
For now we have covered a very small part of the theory regarding Spring 3, which we will expand on in the following posts, so do not
Despair, we will soon start using this framework, which will bring joy (and headaches) to more than one of us.
Don't forget to leave any comments, questions, or suggestions in the comments section.
Greetings.
As we saw inthe first tutorial of the seriesThe core of Spring is based on the concept of Inversion of Control (IoC for its acronym in English), more
specifically in Dependency Injection (DI). This is a process in which objects define their dependencies (that is, the other objects
with whom they work) only through the arguments of its constructor, arguments to a factory method, or setter methods that are invoked
after the object has been built. In this case, instead of the object itself being responsible for instantiating or locating the dependencies.
with which it works (using either its constructor directly or a service locator), it is the container that injects these dependencies when
create the bean. This process, as we can observe, is the opposite of what is normally done, and hence the name Inversion of Control (it is the
the framework does the work, not the programmer ^_^).
In this tutorial, we will see how to configure Spring in 4 different ways to carry out this Dependency Injection process.
automatic
Spring places the basic classes of its IoC container in two packages:
• [Link]
• [Link]
These packages contain two interfaces that are the ones that perform the 'magic' of object instantiation. The first is
"[Link], which provides an advanced configuration mechanism capable of handling any type of
object. It also provides a sub-interface of the latter,[Link], which adds one more integration
easy with some of the most interesting features of Spring, such as its module ofAspect-Oriented Programmingresource management of
messages (for internationalization), event publishing, and specific contexts for certain layers of applications (such as web applications),
among others.
"BeanFactory" provides the configuration framework and basic functionality, while "ApplicationContext" adds more functionality.
specific to certain business products. Both interfaces represent containers of beans, just of different types.
BeanFactory represents the bean factories and is the simplest type of container. It provides basic support for DI.
"ApplicationContext" represents... the application context, these are built with the same notions of bean factories, but
they provide additional services to the application.
In Spring, the objects that form the backbone of applications, and that are managed by the Spring IoC container, are
called 'Beans'. A bean is an object that is instantiated, assembled (when its dependencies are injected), and generally managed by the
IoC container. In other words: a bean is simply one of many objects in our application. The Beans, and the dependencies between
we declare them in the metadata of the IoC container (which can be done through annotations or mapping files).
As I said before: the 'ApplicationContext' interface represents a type of IoC container in Spring, and it is responsible for instantiating, configuring, and
assemble the aforementioned beans. The container retrieves information on which objects to create by reading the configuration metadata.
which, as I said before, can be placed in XML files, annotations, or within Java code.
Spring provides many implementations of 'ApplicationContext'. In particular, in applications that are NOT web, we use
"[Link], which searches for configuration files within the classpath, or
"[Link], which looks for them in the file system of the machine where it is executed
the application.
To exemplify all this, we will create an application that will have a test class that will invoke a "RemoteService". This service will not
something special, it will only return a random number between 0 and 10; the interesting thing about this is that the client will get an instance of
RemoteService without having to create it directly, but using Spring's DI.
The first thing we will do is create a new project in NetBeans. For this, we go to the Menu 'File->New Project...'. In the window that opens
we select the category 'Java' and in the project type 'Java Application'. We give a location and a name to the project, in my case it will be
"SpringIoC". We make sure that the options "Create Main Class" and "Set as Main Project" are enabled. We press the "Finish" button and
we will see our class "Main" appear in the editor.
Note: I will use two projects, one for using mapping files and another for using annotations so that the code of both does not mix.
We added the 'Spring 3' library that we created inthe first tutorial of the seriesWe right-click on the 'Libraries' node of the project, in
In the menu that appears, we choose the option 'Add Library...'
And we press the "Add Library" button. This should add the library files to our project:
Now we will create a new package that will contain our beans, this package will be called "beans". We click
right in the package where our class "Main" is located (which in my case is "[Link]") and in the
in the menu that opens we select the option "New -> Java package..." and we add "beans" to the package name.
We press the 'Finish' button and with this our new package will appear:
We will create our class "RemoteService" inside the "beans" package. This class will be very simple, and will only have a
method called 'consultaDato' which will not receive any parameters and will return a random 'int' between 1 and 10.
class "RemoteService" looks like this:
As you can see, it is a very simple class, so there is no need to explain much.
Normally, to obtain a new instance of 'RemoteService' we would have to place the following line in
some part of the test class:
As I mentioned before: the client should not be responsible for the instantiation of this RemoteService, since it is
a task that does not correspond to him. Thanks to DI we will be able to avoid writing the previous line, and therefore (as
we will see a little later) many potential problems that may arise with it. In Spring, the objects do not
are responsible for finding or creating the other objects they need to do their job. Instead of that, the
the container gives them the references of the objects they will collaborate with.
The act of creating these associations between application objects, using DI, is called 'wiring'.
(Spanish). In the rest of the tutorial, we will see the basic configuration of this wiring with Spring, and we will see the
possibilities that this offers us.
In Spring-based applications, the application's objects live within the bean container.
the container is responsible for creating the objects and 'wiring' them, configuring them, and managing their complete lifecycle.
Understanding how this container works will allow us to understand how our objects
They will be managed, and therefore how we can make better use of them within our application.
As I mentioned at the beginning: there are basically two ways to configure beans and their dependencies in Spring,
the first is through a configuration file in XML, the second is through annotations provided by
Spring. As always, each has its advantages and disadvantages. We will see both ways of
configuration. We will start by looking at the configuration with XML files and later we will see it with
annotations.
The Spring configuration consists of, at least, the definition of a bean that will be managed by the container.
The XML-based configuration metadata shows these beans configured as "<bean />" elements (without
s) inside a "<beans />" element (with s).
These definitions of beans correspond to the objects that make up our application. When we create a
application, we typically define a service layer, a data access layer (or DAOs) a layer of
presentation, and an infrastructure layer (with objects like the "SessionFactory" ofHibernate. In Spring
we normally declare objects that define these 4 layers (and not very specific domain objects), since they are
the previous layers are responsible for creating and managing the domain objects.
We will create the configuration file in our project, so we right-click on the 'Source' node.
In the 'Packages' of our project, and in the contextual menu that opens, we select 'new -> Other...':
In the window that opens, we select the category "Other" and the file type "Spring XML Configuration File":
We give a name to the file, in my case it will be 'applicationContext'. We click the 'Next' button. In the
On the next screen we must select the namespaces we want our file to have. No
we will select none. Later in this same tutorial I will explain what this is. We press the 'Finish' button and
With that, the file '[Link]' will appear in our editor with the following content:
</beans>
The file contains only the root element "<beans>" within which we will declare each of our beans.
using a '<bean>' element for each one ^_^.
The next thing we will do is declare our bean 'RemoteService' so that the Spring container can manage it.
For this, we declare a '<bean>' element in our configuration file:
<bean />
The <bean> element is the most basic configuration unit in Spring, telling it to create and manage an object.
We must assign an identifier to each of our beans within the application; this is not mandatory, but if not
we will not be able to distinguish the beans we work with (we usually do NOT specify a
identifier when we use them as internal beans). These must be uniquely identified within the
container that holds the bean. A bean usually only has an identifier (although there are ways to assign more)
if necessary). In this XML-based configuration, we use the "id" attribute or the "name" attribute to
specify the identifier of the bean. The "id" attribute allows us to specify exactly one identifier, this is
because it uses the real 'id' element from the XML specification, which allows us some extra validations with
normal XML parsers, however, it limits us to the use of characters that are legal in XML to define this
identifier. If we need to use any special character as an identifier, or if we want to indicate an alias for
our bean, we can use the "name" attribute, separating the aliases with a comma (,), a semicolon (;), or a
space in white.
remoteService
Now our bean can be referenced by the name 'remoteService'.
The last step we must take in our configuration file is to tell Spring what type the bean is, this
Yes, the class from which we want to create objects. To do this, we use the attribute "class". In this case, the bean
will be of type "[Link]". Therefore, the configuration of our bean remains as
next form:
Now that we have our configuration file ready, the long-awaited moment has arrived, now we will use one.
of the Spring containers to create our beans. As I mentioned, there are two types of containers
"BeanFactory" and "ApplicationContext". We will see how to use these two types of containers.
BeanFactory does more than just create objects. As a BeanFactory knows the objects that make up our
application (those declared in the configuration file) is capable of creating associations between these objects in the
moment of being instantiated. Furthermore, as the BeanFactory has control over the lifecycle of the bean, it can make
calls to custom initialization and destruction methods (if these methods are defined).
There are many implementations of the 'BeanFactory' interface (supposedly, because I only know one). The most
used (and the only one I know) [Link], which loads the beans
based on the configuration of the XML file we just created.
To create an 'XmlBeanFactory' we must specify from where this XML will be read, since we can obtain it from a
stream, from a file in our classpath, even from an array of bytes. For this, we use an instance of
"[Link]".
We we will use ClassPathResource for to load our configuration yes what the file
"[Link]" that we created is within the classpath of our application (more specifically at the root
of the same). To this "ClassPathResource" we pass a string that contains the path (within the classpath) of
our configuration file, in this way:
Now that we have this 'BeanFactory', we will be able to obtain our bean.
As an important note, it should be said that at the moment we create our BeanFactory, it reads the
definitions of the beans from the indicated file, however the beans are NOT created at that moment. The beans are
They are created only when needed (when we request them in our code).
Now, with our 'BeanFactory' we can get a bean using the identifier we gave it in the file.
XML, in this case 'remoteService'. For this, we use the 'getBean' method of the BeanFactory. To this method we can
(optionally) indicate the class that we expect the method to return (and with this save ourselves a cast ^_^).
At the moment we invoke 'getBean', the factory will instantiate the bean and set its values.
properties using DI. This is when the lifecycle of a bean in the Spring container begins. We will see
this cycle of life more forward.
Now that we have an instance of "RemoteService," we can invoke its methods as we do
normally
All of this is done within our 'main' method, which looks like this:
run
XX-xxx-XXXX XX:XX:XX [Link]
loadBeanDefinitions
INFO: Loading XML bean definitions from class path resource [[Link]]
The value is 7
BUILD SUCCESSFUL (total time: 0 seconds)
As we can see, we receive a message indicating that the bean definitions from the file
"[Link]". We also get the value that our remote service is returning (in my case "7").
We achieved all of this without making a single 'new'. This example, although very simple (not to say silly ^_^) allows us
show the foundations of Spring. A little later we will see, in this same tutorial, where the real advantage lies.
of Spring (just trust me and keep reading).
Now we will see how to do the same using an 'ApplicationContext.'
Using 'ApplicationContext' is similar to using 'BeanFactory'. Both load bean definitions, wire the beans, and
They are sent to those who request them. But "ApplicationContext" offers more things:
• Provide a means to resolve text messages (no, they are not SMSs), including support for
internationalization (I18N) of these messages.
• Provide a generic way to load resource files, such as images.
• You can publish events to beans that are registered as listeners.
Because 'ApplicationContext' provides more functionalities, its use is preferred over 'BeanFactory'.
in almost all types of applications, the only exception is when we are running an application where the resources
son scarce, how in a device mobile.
Although there are many implementations of 'ApplicationContext' (of this one =), there are 3 that are the most used.
commonly:
We will talk about 'XmlWebApplicationContext' when we discuss web applications in one of the following.
tutorials.
In this case, we will use 'ClassPathXmlApplicationContext'. In this case, the constructor receives a string (or strings).
indicating the location of this file (or files):
With this ApplicationContext created, we can now retrieve beans in the same way we did when
we use the 'BeanFactory', using the 'getBean' method, since 'ApplicationContext' is an interface that extends from
BeanFactory
In addition to the extra functionality mentioned a moment ago, there is another difference between 'ApplicationContext' and
BeanFactory, and it is the way in which they load the beans. It should be noted that by default all managed beans
Spring beans are Singletons, which means there is only one instance of them per application. As I said before: 'BeanFactory'
create the beans at the moment they are requested (with the invocation of 'getBean'). 'ApplicationContext' works with
a slightly better way, it loads all the singletons when the context starts, and this way it ensures that
they will be ready at the moment they are requested.
Now that we have our instance of 'ServicioRemoto', provided by Spring, we can make use of its
normal form methods:
When the content of our configuration file begins to grow, we can separate our configuration.
in various files (for example, one for each layer of our application) and then refer to these files
in a "master" file using the element "<import>", for example, in our "[Link]" file
we could have:
<beans>
<import resource="[Link]" />
<import resource="[Link]" />
<import resource="[Link]" />
</beans>
This can also help us when we want to better organize the beans of our application to group them.
some way, and continue loading only one XML configuration file.
There is an alternative to using these XML files, which is to configure through the annotations that
provides us with Spring, which is what we will see next.
The use of annotations allows us to eliminate the need to have the definition of our beans in an XML file, and this is "useful".
when we have many beans declared and our file becomes cumbersome (although we can always
combine both forms of declaration.
Spring provides a relatively large set of annotations with which we can indicate exactly
how we want to handle the DI of each of the components. In reality, there are several ways to manage
these annotations, but right now we will only focus on annotating our beans. For this, there are three
basic annotations, which are known as 'stereotypes':
• RepositoryIndicates that the classes marked with this annotation are related in some way to a
data persistence layer.
• @ServiceIndicates that the classes marked with this annotation are in a service or logic layer.
businesses.
• ControllerIndicates that the classes marked with this annotation are the controller of a web application.
The three previous notes extend from "Component, which indicates that the class is a component, and therefore
they are likely to be self-detected when we use an annotation-based configuration.
We will see two configuration methods with annotations, in the first one (ironically) we will use an XML file to
indicate where our classes are noted. In the second way, we will see how to do the same thing, but without
need for the XML file.
</beans>
Now we will add a special namespace to this configuration file that refers to the elements of
Spring context configuration. In XML, a namespace is a way used to provide elements.
with unique names. Spring uses these namespaces to separate sets of tags that are related and
that offer certain special functionalities. Additionally, this makes reading and writing the configuration files be
easier. Sometimes you will hear them referred to a these namespaces like "schemas"
Each of these namespaces refers to a different XML schema. For example, we have a namespace
for aspect-oriented programming ('aop'), another for managing configuration of jee elements ('jee'), another
for management of messages ("jme") another for transactions ("tx") etc.
The 'context' namespace is responsible for the configuration of the 'ApplicationContext'. To indicate that we will use
we only added the following line within the 'beans' element of the file
[Link]
xmlns:context="[Link]
</beans>
Now we will indicate, using the namespace 'context', that we want to activate Spring's configuration so that
detect the annotations (specific to Spring) in the classes. For that we use the element "annotation-config":
<context:annotation-config/>
Now we must indicate where (in which packages) the classes we have annotated are located. If we do not indicate
this Spring package will not automatically look for classes (I really don ’t know why). We use the element
"component-scan" to indicate, through its element "base-package", the root package in which they are located
our annotated beans. For this example, the root package is '[Link]'. So the element
falls in the following way:
<context:annotation-config/>
<context:component-scan base-package="[Link]" />
</beans>
As we see, we have not defined a single bean in the file, so now we should specify it directly in the
classes that will become our beans (which in this case is only "RemoteService". To indicate this we will use
the annotations I mentioned earlier ("@Repository", "@Service", "@Controller"). As "RemoteService" belongs to
the service layer, we will mark it with the annotation "@Service", like this:
@Service
public class RemoteService
{
}
If you remember, we reference beans by their identifier. But 'RemoteService' is not specified.
none. Spring assigns a default name to its beans, which is the name of the class but with the first letter in lowercase.
lowercase. So in this case the name of the bean will be 'remoteService'. If we wanted to give our bean a
a different name we can do it through the 'value' attribute of the '@Service' annotation, as follows:
@Service(value="remoteService")
So our class 'RemoteService' is as follows:
@Service(value="remoteService")
public class RemoteService
{
public int queryData()
{
return (int) ([Link]() * 10.0);
}
}
No changes need to be made to the code of the "Main" class. We continue obtaining an instance of
"ApplicationContext" (or "BeanFactory") and we specify the location of the file that contains the configuration of
Spring, which in this case is '[Link]'. In the same way, we continue to obtain the bean.
"remoteService" invoking the "getBean" method of the "ApplicationContext" object. Finally, we call the method
"consultaDato" of the bean "servicioRemoto". Our "main" method looks as follows:
run:
XX/xx/XXXX XX:XX:XX PM [Link]
prepareRefresh
INFO: Refreshing [Link]@19c26f5:
startup date [Xxx Xxx XX XX:XX:XX CST XXXX]; root of context hierarchy
XX/xx/XXXX XX:XX:XX PM [Link]
loadBeanDefinitions
INFO: Loading XML bean definitions from class path resource [[Link]]
XX/xx/XXXX XX:XX:XX PM [Link]
preInstantiateSingletons
INFO: Pre-instantiating singletons in
[Link]@5329c5: defining beans
[Link], [Link]
[Link],[Link]
ternalRequiredAnnotationProcessor,[Link]
processor, remoteService]; root of factory hierarchy
The value is: 3
BUILD SUCCESSFUL (total time: 0 seconds)
We can see that there is now more information in the console but ultimately our code executes and
we get the expected output. So our application has been set up properly ^_^.
As we can see, using annotations, our configuration file has become even smaller. However, it is still
we continue to depend on an XML file for our application to function correctly. Now we will see how
configure our application but sine to depend of none XML.
2.2. Annotations without XML File
Since we will not use the '[Link]' file for this last configuration, we can remove it from the
application. We will use the "RemoteService" class again with the annotation "@Service", like this:
@Service(value="remoteService")
public class RemoteService
For this configuration, the only necessary change is in the code that creates the "ApplicationContext" object (in the
method "main"). In this case, we need a special object since, as there is no XML file, we must
to indicate which ones son the classes noted (o the package what the contains).
The "special" object we need to create is an implementation of "ApplicationContext" (and therefore of
"BeanFactory"), the class "AnnotationConfigApplicationContext". This class has two constructors that interest us;
The first receives a list, separated by commas, of the classes that we have annotated with @Component (or any of
its subclasses), as is the case with "RemoteService". Therefore, we would create a new object of this class from the
next way:
new AnnotationConfigApplicationContext([Link]);
This is very convenient if we only have two or three classes noted, but what happens if we have more?
Well, in this case we can use the second constructor of 'AnnotationConfigApplicationContext' in which
we indicate the root package(s) where the annotated classes are found, as in the case of the element
"context:component-scan" of the XML file, in the following way:
new AnnotationConfigApplicationContext("[Link]");
If we run our application, we will see the following output in the console:
run
XX-xxx-XXXX XX:XX:XX [Link] prepareRefresh
INFO: Refreshing [Link]@d1e604:
startup date [Xxx Xxx XX XX:XX:XX CST XXXX]; root of context hierarchy
XX-xxx-XXXX XX:XX:XX [Link]
preInstantiateSingletons
INFO: Pre-instantiating singletons in
[Link]@186d4c1: defining beans
[Link], [Link]
[Link], [Link]
ternalRequiredAnnotationProcessor, [Link]
processor, remoteService]; root of factory hierarchy
The value is 4
BUILD SUCCESSFUL (total time: 0 seconds)
In this way, we can declare all the dependencies and the (almost all) configuration of our beans.
directly in the classes. This way of configuring beans, although it is more convenient and easier for us
as developers when we are writing the code, it is much less clear and (to be honest) we do not
allows us to use all the power that Spring provides us. This is why in these tutorials we will focus more on
how to do things using the configuration file, following the respective instructions to do the same
with annotations (if it is possible to do so).
Now that we have seen 4 different ways to configure the Spring bean container to indicate which are the
beans that should be handled, we will see some details that are a bit more interesting about this framework regarding the
dependency injection.
Dependency Injection
A typical business application does not consist of a single object or bean (as in the case of our test with
RemoteService). Even the simplest application has a few objects that work together to carry out its
Processes in a coherent manner. As I said before, Spring provides us with the way to link these objects.
without having to state it explicitly in the code. Now we will finally see (^_^) how to do this in a way
quick and easy.
When we use Spring's DI mechanism, the code is cleaner and more decoupled.
effective. The object does not look for its dependencies; in fact, it does not even know the location or class of its dependency.
For this same reason, classes become easier to test, especially when we define the dependencies.
like interfaces or abstract classes, since we can use mock objects (which we will see in some other tutorial about
tests) to carry out tests.
The first thing we will do is create a new interface called 'Process'. This interface will represent... well the
process that will be carried out within the remote service. It will have a method called 'execute()', which will be the one that
will be responsible for carrying out the process. We place this interface in the package of our beans. "Process" remains of the
next form:
As we see, 'executes' returns an 'Object'. This will change according to the implementations we make.
from this interface, of which we will certainly make 3. The first implementation will be the class 'Calculo'. Which only
it will return a random number between 0 and 100 (which is what the 'RemoteService' class is currently doing),
remaining as follows:
The following implementation of 'Process' will be called 'Concatenation' and will simply concatenate the strings 'Hello '
and 'world' and it will return this chain to us. The class is as follows:
The third and final implementation of 'Process' will be called 'Sorting' and what it will do is return a list of
Ordered integers. The class 'Sorting' is as follows:
[Link](9);
[Link](3);
[Link](1);
[Link](6);
[Link](5);
[Link](10);
[Link](integerList);
return integerList;
}
}
Now that we have our three 'Processes', let's modify our 'RemoteService' class a bit so that instead
If he is to implement the functionality, delegate this task to one of the 'Process' implementations.
"ServicioRemoto" can receive the Process it will execute in two ways, the first is through its constructor, and the
second is passing this process through a setter.
As now "ServicioRemoto" will delegate the execution of the Processes to other classes, its only function will be to invoke the
method 'execute' of the corresponding Process, and since they return Objects, it will change their return type.
public RemoteService()
{
}
Now yes, we will see how to make Spring inject these dependencies automatically, using its two
forms of DI.
In this type of dependency injection, the container invokes a constructor of the class, which receives a certain number
of arguments, each of which represents a dependency.
Spring will invoke the corresponding constructor depending on the number and type of dependencies we pass, whether it is
through the configuration files in XML (which will be the first way we will see) or making use of
annotations.
The first thing we will do is instead of having the element self-close, we will add a closing tag, that is
because we will add content in the body of the tag:
To indicate that we will perform constructor-based dependency injection, we use the element "<constructor-arg>".
If we do not specify this element, the default constructor of the class is used (as in the previous examples), but if
it is used, Spring will look for a constructor that receives the indicated type of object in it. We have two ways to use this
element, the first is indicating the value that we will pass to the constructor (useful for 'constants') using the attribute
"value". For example, if "RemoteService" had a constructor that received a string, we could use
"<constructor-arg>" in the following way:
But since this is not the case, we will use the other form of "<constructor-arg>" that takes a reference to another bean.
declared in the configuration file, using its "ref" element, in this way:
In 'ref' we indicate the identifier of the bean we will reference, in this case it is the 'process' bean that we created.
Before. The declaration of the bean 'remoteService' is as follows:
</bean>
But to make things clearer we will leave it declared as we had it ^_^. Our configuration file
falls in the following way:
If our constructor had more than one argument, it would be enough to add another element "<constructor-arg>".
Now we will run our application normally. With the following content in the 'main' method:
It is the same code that we already had. When we run our code, we will get the following output (I have removed something
from the 'junk' that Spring generates, to focus on the important part):
run:
El valor es [1, 3, 5, 6, 9, 10]
BUILD SUCCESSFUL (total time: 0 seconds)
As we can see, we have obtained the expected output without having to write a single line of code to solve the
dependencies that the class 'ServicioRemoto' uses, which in this case is the process. Furthermore, 'ServicioRemoto' doesn't even...
You know what type of 'Process' is running, nor how to find it, it is the IoC engine of Spring, which by doing
the use of DI is responsible for creating an instance of the appropriate class and injecting it, in this case through the constructor,
a "RemoteService".
Now we will see another of the charms of Spring. Without touching a single line of our code (or rather, without moving
in no class) we will make "RemoteService" obtain a different dependency. To do this, we will change the line:
For
run:
The value is Hello world
BUILD SUCCESSFUL (total time: 0 seconds)
Now an instance of "Concatenation" has been injected and "RemoteService" uses it to execute its Process. Why?
Is this useful? Well, imagine the case where we have our application already compiled and in production. If we wanted to
making a change would only be a matter of modifying the XML configuration file (which is always in plain text) and
restart the application for there to be a change. This is one of the advantages of configuration in XML over
the annotations.
But, for academic purposes, let's see how to perform constructor injection using annotations.
@Service
public class Calculation implements Process
{
}
@Service
public class Concatenation implements Process
{
}
@Service
public class Sorting implements Process
{
}
Now we will modify our class "RemoteService". The first thing we will do is indicate that we want Spring
automatically perform the wiring for the constructor of 'RemoteService' that receives the instance as a parameter
From 'Process'. The annotation '@Autowired' allows us to do this.
@Autowired
public RemoteService(Process process)
{
[Link]
}
If we run our application right now, we will see that in the console we get the following message
error
What this error is subtly trying to tell us is that Spring does not know which of the classes that implement the
interface 'Process' must be injected as it finds 3 candidate classes: 'calculation', 'concatenation', and
"ordering". We must indicate which of these three classes we want an instance to be injected from. To do
this Spring provides the annotation "@Qualifier" to refer to a bean by its name (which if
we remember, when we use annotations, by default it is the same name as the class, but starting with the first
lowercase letter). We place this annotation directly inside the parentheses that represent the parameter
to which we will refer (this annotation can also be placed at the field level) and we indicate the name of the
bean we want to use, which in this case will be 'ordering':
Autowired
public RemoteService(@Qualifier("sorting") Process process)
{
[Link]
}
@Service(value="remoteService")
public class RemoteService
{
private Process process;
public RemoteService()
{
}
@Autowired
public RemoteService(@Qualifier("sorting") Process process)
{
[Link] = process;
}
Now yes, if we run our application we will see the following output in the console:
run
El valor es: [1, 3, 5, 6, 9, 10]
BUILD SUCCESSFUL (total time: 0 seconds)
As we can see, it has also proven quite simple to perform constructor-based injection using annotations.
In the same way that, using the XML file, we were able to make our application use an instance of
a class or another moving only one line, here we can do the same; if we change the value of the annotation
@Qualifier from 'ordering' to 'calculation', in this way:
run:
The value is: 49
BUILD SUCCESSFUL (total time: 0 seconds)
As we can see, everything has gone perfectly using constructor dependency injection. Now let's see the
second form of dependency injection provided by Spring: setter-based dependency injection.
The properties of JavaBeans are typically declared as private and have a pair of access methods.
a setter and a getter. The setter-based dependency injection is performed when the container calls the
setter methods of the beans, to inject their required dependencies.
To demonstrate this example, we will modify our "RemoteService" class so that it now executes the Process.
corresponding to a certain number of times. This number of times will be represented by an object of type Integer,
what it will be inserted doing use of the injection of dependency for setter.
We will add this variable, called 'repetitions', along with its setter, in the following way:
Now we will modify the method 'consultaDato' to add a loop that will execute the method the number of times
indicated, through the variable "repetitions":
Setter injection is performed using the <property> element of the configuration file. <property>, when
similar to "<constructor-arg>", it allows receiving a value through the "value" attribute or using a reference to another
bean declared in the file, through the 'ref' attribute. In this element we must indicate which attribute, or property,
it is what we want to be injected, for this we use the 'name' attribute of the '<property>' element. As
we will pass a constant value to the 'repetitions' property of the 'remoteService' we will use the attribute
value
We will place the element "<property>" inside the "<bean>" tags that define the bean "servicioRemoto", right
below the "<constructor-arg>" that we placed a moment ago, in this way:
This is the only change we need to make to perform dependency injection via setter. Remember that
if they wanted to inject an object, instead of a constant, they must declare the bean (or use an internal bean), and the attribute
"ref" of "<property>".
run
The value is 1 - [1, 3, 5, 6, 9, 10]
2 - [1, 3, 5, 6, 9, 10]
3 - [1, 3, 5, 6, 9, 10]
4 - [1, 3, 5, 6, 9, 10]
5 - [1, 3, 5, 6, 9, 10]
If you change the value of 'repetitions' in the configuration file, you should see this change reflected accordingly.
immediate, in the application.
Now let's see how to do this same dependency injection, but using annotations.
If we wanted to inject a reference to an object, we would do it as we saw in the case of constructor-based DI.
Using the annotations "@Autowired" and "@Qualifier." When we are going to inject a constant value, we use the
@Value annotation and we indicate in its attribute "value" the value we will inject.
In the setter-based DI, we can place these annotations in two places. The first is directly on the
setter of the attribute that we are going to set, in the case of 'repetitions' it would be in this way:
5
public void setRepetitions(Integer repetitions)
{
[Link]
}
The second is directly in the attribute that we want to set, in this way:
@Value(value="5")
private Integer repetitions;
I will use this second form, as it seems a bit clearer to me than the previous one. In the end, our class
"Remote Service" is annotated as follows:
@Service(value="remoteService")
public class RemoteService
{
private Process process;
@Value(value="5")
private Integer repetitions;
public RemoteService()
{
}
@Autowired
public RemoteService(@Qualifier("calculation") Process process)
{
[Link]
}
return [Link]();
}
If we run this code, we will see the following output in the console:
As we can see, it has once again been very easy to modify our application to add this type of injection.
dependencies.
The choice between which form of dependency injection, by setter or by constructor, to choose is not easy, as
both they have suspicious advantages y sus disadvantages.
Spring allows us to choose the method we like (or that suits us best), in addition to allowing us to mix both.
ways, as we have done in the example. However, there is a 'rule' or advice we can follow: use DI
based on constructor for mandatory dependencies and setter-based DI for optional dependencies.
The Spring development team (and I as well) generally suggests using setter injection, because having
constructors with a large number of arguments can be cumbersome, especially if some of the
arguments are optional. Setter methods also make objects of those classes easier to
reconfigure or reinject later.
The best thing is to use the type of DI that makes the most sense for the class we are working on.
We will leave this tutorial here. We have learned how to perform dependency injection in both ways that we
provides Spring: constructor-based and setter-based, and to inject references to other objects and values
constants, both with configuration files in XML and with annotations. We have only seen a couple of examples
very simple, but remember that using this same logic you can extend these examples to build applications
big.
It is also important to remember that it is possible to combine both forms of configuration, by annotating some beans, and
declaring others in the XML configuration file.
I hope the tutorial is useful to you. In the following tutorials, we will see how to inject collections into our
beans, in addition to their scope and lifecycle, to know how to take greater advantage of them.
Don't forget to leave your questions, comments, and suggestions. Everything is welcome ^_^.
Greetings.
Spring 3 - Part 3: Injection of Collections
Inthe previous tutorialwe saw how to configure Spring to be able to wire simple properties, whether a value
constant or a reference to an object.
This is very useful when we only expect a reference or a value, but what happens in the case where we need to inject several?
objects? Java provides a set of classes that allow us to handle sets of objects. These classes are known as collections.
In this tutorial, we will learn how to perform dependency injection in 3 types of collections ('List', 'Set', and 'Map') and, additionally,
we will learn to inject properties and arrays. We will also see how to insert null values into the properties of
our beans.
Spring offers five types of elements for configuring collections. The following table shows these elements and a description of where
can be used:
For this example, we will create a class to which we will inject several collections of the different types mentioned above, and it will iterate through them to
able to display them on screen. Some of the items in the collections will be constants and others will be references to objects of a type 'Person',
what we will create in a few moments.
The first thing we will do is create a new project in NetBeans. For this, we go to the Menu 'File->New Project...'. In the window that opens
we select the category 'Java' and in the type of project 'Java Application'. We give a location and a name to the project, in my case it will be
SpringCollections. We make sure that the options 'Create Main Class' and 'Set as Main Project' are enabled. We press the button
Finish
We added the 'Spring 3' library that we created inthe first tutorial of the seriesWe right-click on the "Libraries" node of the project, in the
menu that appears we choose the option "Add Library...". In the window that opens we select the "Spring 3" library and press the button
Add Library. With this, the library files must be added to our project.
Now we will create a new package that will contain our beans, this package will be called 'beans'. We right-click on the package in which we
find our class "Main" (which in my case is "[Link]") and in the menu that opens select the option "New -> Java"
package..." and we add "beans" to the package name. We press the "Finish" button and with this our new package will appear.
Now we can create our XML configuration file, "[Link]", in the root package (default package). To do this, we click
right-click on the 'Source Packages' node of our project, and in the context menu that opens, select 'new -> Other...'. In the window
that opens, we select the category 'Other' and as the file type 'Spring XML Configuration File'. We give a name to the file, in my
it will be "applicationContext". We click on the "Next" button. In the next screen, we must select the namespaces we want.
have our file. We will not select any. We press the 'Finish' button and with that the file will appear in our editor.
[Link]
Now we will create our class 'Person', within the 'beans' package, whose instances will be injected into the collections that we will create in
a few moments. 'Person' will be a very simple class that will only have 2 attributes: 'name', of type String, and 'age', of type int, with its
respective setters and getters. Therefore, 'Person' looks as follows:
We will also override the 'toString' method of the 'Person' class. This is in order to display one of its instances when using
[Link](), we can see the values of its attributes without explicitly calling its getter methods:
@Override
public String toString()
{
return new StringBuilder("name: ").append(name).append(", age: ").append(age).toString();
}
Now we will create a class called 'CollectionHandler' in the 'beans' package. This class will be the one to which we will inject the collections.
we will declare in the configuration file, and it will be responsible for displaying the contents of these collections in the console. This class will have a
variable for each of the types of collections that we will inject (list, array, set, map, and properties), and how we will do injection by setter (if not
Do you all know what this is? [Link] second tutorial of the series), it will have a setter for each of the previous properties, in this way:
As we can see, 'CollectionHandler' has a property for each of the collection types. We can also see that in this case it does not
We have used 'generics' when marking the collections. This is because within the collection we will place objects of different types.
Now we will create a method to display the content of each of these collections. These methods will be very simple; we will just iterate through them.
a for loop, and we will display them with a "[Link]". This is the method to display the list:
As we can see, the previous 5 methods are very simple, so they do not need further explanation. The class 'CollectionHandler' remains
finally in the following way:
Now let's go back to the '[Link]' file to configure the injection of all the objects that will be injected into 'ManejadorBeans'.
The first thing we will do is declare two objects of type 'Person':
Now, using setter injection, we will set the values of the attributes 'name' and 'age' of these two beans. You can place the
values they want:
In general, all our collections (including the arrangements) are declared as internal beans, so they will not have their own identifier.
Let's start by injecting the lists:
List Injection
To declare a list in the configuration file, we use the element "<list>" in the corresponding property, which in this case is called "list":
list
<list>
When we want to declare a reference to a bean within a list, we use the element "<ref>", and inside this we use the attribute "bean" to
indicate the identifier of the bean we want to refer to, in our case they will be the beans 'persona1' and 'persona2':
list
list
<ref bean="persona1" />
<ref bean="persona2" />
When we want to declare a primitive value, such as an int or a String (I know, Strings are objects, not primitive types, but in Java the
we manage as if they were u_u!), we use the element "<value>". Within that element, we declare the value we will use, in this way:
Chain
5
If we leave it in the previous way, Spring will understand both values as if they were Strings, however, if we want to declare a value as something else
For example, in the case of "5" which we want to be an integer, we use the "type" attribute of the "<value>" element to indicate the type of the value. In
this case will be of type "[Link]":
<value type="[Link]">5</value>
lista
<list>
<ref bean="persona1" />
<ref bean="persona2" />
Chain
<value type="[Link]">5</value>
</property>
If we recall, in a list the order in which the elements are located within the collection is important. When we inject a list into a
bean, the elements of it will be injected in the order in which we declare them in the configuration file. This means that in this
in this case, the order of the elements in the list will be: "person1", "person2", "String", "5".
Now we will see how to inject the elements for the next 'collection', the arrays.
Array Injection
Now we will inject an array into our bean "ManejadorColecciones". Spring provides the element "<array>" to declare an array within
from the configuration file:
array
<array>
Just like with lists, we can declare a reference to a bean that will be added to our array, using the <ref> element, or we can
inject a "primitive" value using the "<value>" element.
As in our class "ManejadorColecciones" we have declared the variable "arreglo" of type "Persona[]", we can only pass references of type
"Person" to the array that we will inject. For this, we will pass the references to the beans "persona1" and "persona2" that we have already declared:
We will add one more person to our array, but in this case in the form of an internal bean:
array
<ref bean="persona2" />
<ref bean="persona1" />
<bean class="[Link]">
<property name="nombre" value="Persona Nueva" />
<property name="edad" value="10" />
With this, we have declared an array of 3 elements, of type 'Person', which will be injected when our bean is created.
array
array
<ref bean="persona2" />
<ref bean="persona1" />
<bean class="[Link]">
New Person
<property name="edad" value="10" />
</property>
In arrays, just like in lists, the order in which the elements are found within the collection is important. In this case as well, the
array elements will be injected in the order in which we declare them in the configuration file. This means that in this case, the
orden de los elementos en la lista será: "persona2", "persona1", "Persona Interna".
Injection of Sets
When we want to inject a Set into a bean, we use the '<set>' element of the configuration file:
set
<set>
</property>
Just like in the previous cases, we can pass references to other beans using the <ref> element, or 'primitive' values using the element
We will pass four references to 2 beans: 2 references to the bean 'person1' and 2 references to the bean 'person2', as follows
form:
<set>
<ref bean="persona1" />
<ref bean="persona2" />
<ref bean="persona2" />
<ref bean="persona1" />
Why do we do this? Well, we have done this because Sets are a special type of collection that does NOT allow duplicate elements.
This means that even though we have passed 4 references, since we are actually only passing 2 objects (and 2 duplicated), the collection in the end
it will only have 2 objects, we will see this when showing the values in the console.
set
set
<ref bean="persona1" />
<ref bean="persona2" />
<ref bean="persona2" />
<ref bean="persona1" />
Now let's see how to inject our fourth collection, the maps.
Maps injection
To perform Maps injection, Spring provides the element... yes, you guessed it, the element "<map>":
<property name="mapa">
<map>
</map>
Let us remember that a map is a collection that has key-value type elements, where both the key and the value can be of any type.
To declare the members of the map, we use the <entry> element. Within this element, we can indicate two types of keys, a key that is
a value, using the "key" attribute, which is taken as a String, or a key that is a reference to a bean, using the "key-ref" attribute. From the same
In this way, we can declare two types of values, some that are references to other beans, using 'value-ref', and others that are values that are taken
as String, using 'value'. The following table provides the name and a description of these attributes:
Attribute Purpose
key Specify the entry key of the map as a String.
Specifies the key of the map entry as a reference to a bean.
Value Specifies the value of the map input as a String.
value-ref Specifies the value of the map entry as a reference to a bean.
We will inject 4 entries into our map. We will try to combine various types of objects, both beans and values. The first
the entry will have a key as a string and as a value a reference to one of our beans of type 'Person':
The third entry will have a string as the key and another string as the value:
no people
The fourth and final entry will have as key a reference to a 'Person' object and as value another reference to a 'Person' object:
map
<map>
<entry key="persona1" value-ref="persona1" />
<entry key-ref="persona2" value="otra persona" />
no persons
<entry key-ref="persona1" value-ref="persona2" />
</map>
Property Injection
Properties are very similar to maps; they are collections that have key-value pairs. In fact, the 'Properties' class implements the
interface "Map". The main difference is that, while in maps the key and the value can be of any type, in properties both
elements can only be of type String.
properties
</property>
To add each of the property members we have two ways. The first is using the '<prop>' element, in which we indicate the
key using the "key" attribute, and we place the value as the content of the element. For example, if we wanted to declare four properties:
name, country, site, and facebook, we would do it as follows:
Alex
Mexico
[Link]
[Link]
The second way is by taking advantage of the support that Spring provides us for handling properties using its "PropertyEditorintegrated for
write directly the keys and values of the properties, as the body of the element "<value>" that we place directly inside the
property (without using the element "<props>"), in this way:
properties
value
Alex
Mexico
[Link]
[Link]
translatedText
And that's all, we have configured all the collections of our example. In the end, the configuration file, '[Link]',
falls in the following way:
list
array
<array>
<ref bean="persona2" />
<ref bean="persona1" />
<bean class="[Link]">
<property name="nombre" value="Persona Nueva" />
<property name="edad" value="10" />
set
map
<map>
<entry key="persona1" value-ref="persona1" />
<entry key-ref="persona2" value="otra persona" />
no persons
<entry key-ref="persona1" value-ref="persona2" />
<property name="propiedades">
<props>
Alex
Mexico
[Link]
<prop facebook
Tutorials/121935157864634
The next thing we need to do is, in our "main" method, create an object of type "ApplicationContext" to be able to obtain our beans. For
to see more details on how to do this, you can consultthe second tutorial of the seriesI will summarize everything by saying that we will create an instance of
"ClassPathXmlApplicationContext" and we will pass the location of the configuration file within the classpath as a parameter to its constructor.
in the following way:
The next thing we will do is obtain a reference to the bean 'handler', declared in the configuration file, using the 'getBean' method of
our object 'ApplicationContext':
To conclude, we will invoke, in the object 'handler', each of the methods to display the values of the collections, as follows:
[Link]();
[Link]();
[Link]();
[Link]();
[Link]();
The 'main' method is as follows:
[Link]();
[Link]();
[Link]();
[Link]();
[Link]();
}
---Showing list---
[Link]
[Link]
class [Link]: String
class [Link]: 5
Showing arrangement
Persona2
[Link]
[Link]
---Showing set---
[Link]
[Link]
---Showing map---
[key] class [Link]: person1 [value]class [Link]
Person1
key class [Link] name Persona2, age 62, [value]class
another person
class [Link]: no person
key class [Link] name Person1, age 26, [value]class
Persona2
---Showing properties---
[key] class [Link]: facebook [value]class [Link]:
The provided text is a URL and does not require translation.
country
class [Link]: name
key class [Link]: site, [value]class [Link]:
[Link]
The first one we obtain is the output of the list. In this, we can verify that the elements are in the same order in the
that we declare them in the configuration file. First the two beans of type 'Persona', then the string 'Cadena' that we declared as a
value, and finally the value "5" that we declared as an object of type "[Link]":
In the following part of the output, we have the value of the array. Here again, the elements are in the same order in which they
we declare in the configuration file. First, we have the two beans of type 'Person', and then the internal bean that we declared, with the
New Person
Subsequently, there is the output segment corresponding to the Set. Here we see that although in the configuration file we declared 4
members for this collection, in the end, only 2 objects are inserted here, since Sets are collections that do not allow duplicates:
The following is the output of the map elements. Here we can observe that we indeed have a combination of both keys and
values of types 'Person' and 'String', in the same way as in the configuration file:
The last part of the output corresponds to the properties. In this, we can see that both the keys and the values are of type
String
Perhaps some may have wondered what happens if I want to insert a property with a value of 'null', or an element of the collections such as
"null"? Well, we will answer this question in the last part of the tutorial.
In almost every situation, we will use DI to wire a constant value or a reference to an object within a bean property. However, in
In some cases, it will be necessary to inject a null value into a property.
Although in Java object references are null by default, sometimes assuming this is not enough to achieve our goals.
To set a property as 'null' we use the element... '<null />'. For example, if we wanted to set the property 'name' of a
a bean of type 'Person' as 'null', we would declare it as follows:
persona1
<property name="nombre"><null /></property >
26
</bean>
We have reached the end of this third tutorial on Spring 3, I hope it is useful to you. Don't forget to leave your questions, comments, and suggestions.
Greetings.
In the previous tutorials, we have seen how to work with configuring beans, both with annotations and with configuration files.
configuration in XML, and how to wire them to the properties of other beans.
However, Spring provides us with mechanisms to control the creation of beans and execute certain actions in
the different stages of the life cycle of our beans.
In this tutorial we will learn how to control when the bean instances should be created and to create them at
through a static factory method, in addition to receiving notifications when a bean is created and before
it has been destroyed.
We will create a project in which we will test each of the concepts we see. The first thing we will do
is to create a new project in NetBeans. For this, we go to the Menu "File->New Project...". In the window that opens
we select the category 'Java' and in the project type 'Java Application'. We give it a location and a name.
project. We ensure that the options "Create Main Class" and "Set as Main Project" are enabled.
We press the "Finish" button and we will see our class "Main" appear in the editor.
We added the library "Spring3" that we created inthe first tutorial of the seriesWe right-click on the node
"Libraries" of the project, in the menu that appears we choose the option "Add Library...". In the window that opens
we select the "Spring3" library and press the "Add Library" button. This adds the library files
they must be added to our project.
Now we will create a new package that will contain our beans, this package will be called 'beans'. We click
right in the package where our class 'Main' is located (which in my case is '[Link]') and
In the menu that opens, we select the option "New -> Java package..." and we add to the package name
We press the 'Finish' button and with this our new package will appear.
We will create, in the package "beans", an interface called "Estudiante" that we will use to carry out
our dependency injections and tests. This interface will only have a method called "presentExam()"
that will return an integer between 0 and 10 that will represent the Student's grade in the exam. This interface
it falls in the following way:
We will also create, in that same package, a class that implements this interface. The class will be called
University student". Its implementation of the method "presentExam()" will simply return a random number.
between 0 and 10. This class is as follows:
Now we will create, in the default package, the Spring configuration file,
"[Link]". For this, we right-click on the
In the context menu that opens, we select 'new -> Other...'. In the window that opens, we select the
category 'Other' and file type 'Spring XML Configuration File'. We give a name to the file, in my case
it will be 'applicationContext'. We click on the 'Next' button. In the next screen, we must select the
namespaces that we want our file to have. We will not select any. We press the 'Finish' button and
with that will appear in our editor the file [Link]
We declare a bean called 'student' of type 'University' within the configuration file, as follows
shape:
Let's start by looking at how we can control the moment when the beans are created. This is known as the
scope of the bean.
By default, beans in Spring are Singletons... what is a singleton?... Singleton is a design pattern with the
that ensures there is only one instance of a bean in our application. Yes, you read that right, one and only one instance
from the bean by application (or more precisely byClassLoader). This is usually achieved by making the constructor
the class is private and provides a static factory method that takes care of ensuring that there is only
an instance of the class. I won't go into more details because that is the subject of another tutorial.
The important thing is to emphasize the fact that in Spring, by default, all beans are singletons, meaning that the
the container creates a single instance of a bean, regardless of how many times we call the 'getBean' method
"ApplicationContext" (as long as we call the same bean, of course ^_^) Spring will always return the same one.
instance.
How can we verify that this is true? Very easily ^_^. In Java, every time an object is created,
the constructor of said object is invoked, beans are objects; therefore, each time a bean is created it
invokes its constructor.
Therefore, we can put a message in the constructor so that it shows something in the console every time a
a bean of type "University" is created. We will temporarily modify the "University" class to add a
constructor, which does not receive any parameters, which shows us a message of object creation. We will add the
next constructor to the class 'University Student':
public University()
{
--Building a university student--
}
Now we will obtain, in our "main" method, a bean of this type using an "ApplicationContext" (if not
remember well how to do that you can see how inthe second tutorial of the series):
We will next invoke the "getBean" method of the applicationContext twice to obtain a reference to
bean "student", and we will show it in the console:
We don't do anything special, we just get a reference to the bean 'student' twice and display it in the
console. Our 'main' method is as follows:
If we run our application, we will get the following output in the console:
Student 1: [Link]@a46701
Student 2: [Link]@a46701
As we can see, the constructor of the 'Universitario' class was only invoked once, and therefore, only one was built.
an object of this class. The two times we called the "getBean" method, it returned the same object both times.
instance.
This sounds logical, right? Since we only declare the 'student' bean once, it should only be created once and always.
If we want to use this bean, we should obtain the same instance, right?
While this idea is very correct, there are times when we will need a new instance of a bean each time.
that we ask for it (that we call 'getBean'). Fortunately, there is a way to do this.
When we declare a '<bean>' element in the Spring configuration file, we have the option to declare
a scope for that bean. By default, the value of this element is 'singleton'. Spring provides 5 possible values
for this element:
• singleton - There will be only one instance of the bean per container. This is the default scope.
• prototype - A new instance of the bean will be created for each call to 'getBean', that is, every time that the
bean is going to be used.
• request - There will be a single instance of the bean for each HTTP request; that is, each HTTP request has its
own instance of a bean. This scope is only valid when using a Spring container with
web capabilities like Spring MVC.
• session - There will be an instance of the bean for each HTTP session. This scope is only valid when used with a
Spring container with web capabilities like Spring MVC.
• globalSession - There will be an instance of the bean for each global HTTP session. Typically, it is only valid when
it works with portlets. This scope is only valid when using a Spring container with web capabilities
like Spring MVC.
In Spring 3, there is a new and secret sixth scope called 'thread scope', but it is not registered by default.
You can find more information about this scope inthe Spring documentation.
With this scope, as I mentioned earlier, there is only one instance of the bean per container, and this instance is
obtained every time the "getBean" method is called.
In other words: when we define a bean, and it has a scope defined as singleton (the default), the
Spring's IoC container creates exactly one instance of the defined bean. That unique instance is stored in
a special cache for these singleton beans, and all subsequent calls to obtain that bean will receive the
object that is found in the cache.
This scope is, one could say, the opposite of singleton, since in this case a new instance of the bean is created each time.
each time a specific bean is requested, that is, every time we ask for a bean by invoking the method 'getBean'. As
general rule, we use the prototype scope for all stateful beans, and the singleton scope for all beans
without state.
Unlike other scopes, Spring does not manage the complete lifecycle of prototype beans (this is very
important for what we will see a little later); the container creates an instance, configures it, and assembles it,
it also sends it to the client, but after that, Spring no longer keeps a record of that instance. So,
Although the lifecycle initialization callback methods are called on all objects regardless of their
scope, in the case of prototype objects, the destruction callback methods are NOT called.
The request, session, and globalSession scopes are only available if we use Spring in a web application, and
we use an implementation of 'ApplicationContext' that works on the web (like 'XmlWebApplicationContext'). If
we tried to use these scopes with some other implementation (like with "ClassPathXmlApplicationContext"),
we will encounter an exception of type 'IllegalStateException'.
The beans with this scope live for the duration of the global session of the portlets.
If we are creating a non-portlet web application (based on servlets) and we define some bean with this scope,
then the normal 'session' scope will be used and we will not encounter any error.
Now that we have seen that there are various scopes and the differences between them, let's see how to fix the problem.
that we had previously, where we only obtained an instance of the bean "student", regardless of the
number of times we call the method 'getBean'. On this occasion, what we want is to create a new one
instance of the bean every time we need it. As we saw in the definition of scopes, this can be achieved if
we define the bean with the scope 'prototype', so we will modify the bean declaration by adding the attribute
"scope" in the following way:
If we run our application again, we will see the following output in the console:
As we can see, on this occasion Spring has built a new object of type 'University Student' for each call.
method "getBean".
We will review the rest of the scopes when we see how to create web applications with Spring. Now let's see how
we can create beans using static factory methods, as is done in the factory design pattern.
Most of the time, the beans we configure in the Spring application context are created by invoking
one of the class constructors. This is fine if we always create our beans with constructors
public. But what happens if for some reason we cannot use a public constructor? Or what happens if we use the API
from a third party that exposes objects through a static factory method?
Fortunately, Spring allows us to continue creating beans with this type of classes. To exemplify this, let's look at the
next bean, which is an implementation of the singleton design pattern we talked about earlier.
We will create a new class in the package "beans" called "Sun," for Sun Microsystems ^_^ (you know, for the
The issue is that there is only one Sun Microsystems ñ_ñ ). The class "Sun", as I said, will be an implementation of the pattern of
singleton design. We will add an instance method, which will only be responsible for returning a string that
we will be able to print to the console. The class looks like this:
static
{
instance = new Sun();
}
private Sun()
{
}
The previous class has a private constructor, which means it can only be used from within itself.
application. Additionally, it has an instance of the same type 'Sun', which is initialized within an initialization method.
static, meaning that the instance will be created as soon as the class is loaded into the classloader.
Since the constructor and the class instance are private, we need a way to obtain that instance.
we provide a factory method, the 'getInstance' method, which will return the instance every time
we need.
With the two previous considerations, we ensure that there will only be one instance of the previous class throughout.
the classloader and that there is no way to create another instance. We can see that with this measure we can no longer create
an instance of the class using the 'new' operator, but we must use the 'getInstancia' method. So,
How would we get Spring to create a bean of this class?
For cases like this, the <bean> element provides an attribute called 'factory-method'. This attribute allows us
allows specifying a static method that will be invoked, instead of the constructor, to create an instance of the
class.
So now we will configure a bean of type 'Sun' in the configuration file, for this we add a new
element "<bean>" in this way:
Now we will modify our "main" method. We will continue creating an instance of "ApplicationContext" from the
file '[Link]', but now we will obtain a reference to the bean named 'sun'.
We will invoke its method "getMensaje" and display the string that it returns in the console, as follows:
[Link]([Link]());
}
When running the application, we will obtain the following output in the console:
Thus we can realize that the bean instance has been created correctly, using the method of
factory, and we can use its methods normally ^_^.
Now we will see the life cycle of a bean in Spring, and how to receive notifications during some of the different
events of the life cycle of our beans.
In a traditional Java application, the life cycle of a bean is very simple. The "new" operator is used to instantiate.
the bean, and it is ready to be used. Once we stop using the bean, it is eligible to be collected by the
garbage collector. In contrast, the lifecycle of a bean within the Spring container is a little more
elaborate. It is important to understand the life cycle of a Spring bean, as we may want to have
advantage of some of the opportunities that Spring offers us to customize the way a bean is
created.
The following figure shows the lifecycle of a typical bean that is loaded in a type container.
attention because this is important, 'BeanFactory':
After seeing this figure, we can realize that Spring goes through quite a few configuration steps before
that a bean is ready to be used by a, and again pay attention, 'BeanFactory'. The following table
explain each of these steps in more detail:
Step Description
5. Post-process (before If there are any 'BeanPostProcessors', Spring calls their methods
from the initialization) postProcessBeforeInitialization()
If the bean implements 'InitializingBean', its method 'afterPropertiesSet()' will be called. If the
6. Initialize beans the bean has its own 'init-method' (which we will see in the next section), the method
will be called.
7. Post-process
If there are any "BeanPostProcessors", Spring calls their methods
(after the
postProcessAfterInitialization()
initialization
The bean is ready At this point, the bean is ready to be used by the application and will remain in the bean.
for use factory until it is no longer occupied.
If the bean implements "DisposableBean", its "destroy()" method is called. If the bean has a
9. Destroy the bean
custom 'destroy-bean' method, the specified method will be called.
Why did I emphasize the fact that this is the lifecycle of a bean in a "BeanFactory"? Well, I did this because
the fact that the life cycle of the bean is a bit different within an 'ApplicationContext', which we can see
in the following image:
The only difference is that if the bean implements the "ApplicationContextAware" interface, its method is called.
setApplicationContext
Now that we have a better idea of the lifecycle of beans, let's see how we can receive notifications
when our beans are created or destroyed.
When a new bean is created, it may be necessary for us to carry out some initialization process to
leave it in a reasonable state for use. Similarly, when we no longer need a bean, and it is going to be
removed from the container, it may be necessary to carry out some cleaning process.
Spring provides us with several mechanisms to interact with the lifecycle management of beans.
our container; more specifically for the moment when the beans are created and at the moment when the
that will be destroyed. These mechanisms are known as callback methods, or callback in English.
Each of these mechanisms, as usually happens, has its advantages and disadvantages, but the three are
equally easy to use. The three mechanisms are:
We see an example of the use of these interfaces. To do this, we will modify our "Universitario" class by making it
implement these two interfaces. The method 'afterPropertiesSet()' will serve to indicate when our object is
created, that is when our new college student enters the school ^_^. We will use this method to show a
welcome message in the console; and we will use the 'destroy()' method to show a farewell message,
also in the console.
If we run our application, obtaining in the 'main' method our bean 'student', we will see the following
console output:
If we observe the previous output carefully, we will notice that a message is missing, the message corresponding to
the destruction of the bean. This happens because Spring does not know that the application has stopped running (since this
it ends suddenly when the "main" method finishes) and therefore does not know when to call the "destroy" method.
So how do we make Spring aware of when the application is shutting down? Or in other words, how
Does Spring know when to destroy the bean container and therefore call the 'destroy' method? Fortunately
Spring provides us with an elegant way to do this.
If you remember, we are using a class that implements the interface as a bean container.
ApplicationContext, in this case the class ClassPathXmlApplicationContext. This class has a base class called
"AbstractApplicationContext", which contains a method "close" that we use to tell Spring when it should
close the ApplicationContext, and destroy all the beans contained in it. We modify our 'main' method
to declare our variable "applicationContext" so that it uses a reference of type
AbstractApplicationContext, and we call, at the end of the 'main', its 'close' method. The 'main' method remains of the
next form:
In addition to this change, we need to modify one thing in the Spring configuration file. At this moment the
The bean 'student' is declared as a bean with 'prototype' scope, meaning that one is created each time it is called.
to the method "getBean". If you remember in the explanation of the bean scopes, we said that the methods of
destruction of beans will not be called in prototype beans, so we must change the bean's scope to
that it remains a singleton. We change the following statement:
If we run our application again, we will see the following output in the console:
With this we verify that the methods have been called at the appropriate times. However, now
our application has become coupled to the Spring libraries (which we do not want). As always, Spring has
provide a way to avoid having to make this coupling by declaring in the configuration file the
methods that will be used for the initialization and destruction of the bean.
Declaration of the methods that will receive notifications, using configuration files
As with everything in Spring, declaring the methods that will be used for the initialization and destruction of the bean is
from the simplest. The only thing we need to do is declare, in the <bean> element, the attribute 'init-method', to
the initialization method, and "destroy-method", for the destruction method. These methods can be any
that exists within our class. To illustrate this, we will modify our 'University' class by adding two
new methods. The first will be the method "preparaEstudiante", which will display a message in the console
showing the initialization of the bean. The second method will be 'fireStudent', which will also show a message
in the console, but indicating that the bean will be destroyed:
And we declare, in the "[Link]" file, that the bean "student" will use these two methods:
If we run our application right now, we will get the combined messages of the implementation of
the interfaces from the previous point and the methods declared in the configuration file. To avoid this
we will temporarily remove the declaration of the interfaces of our class 'Universitario', leaving it like this
form:
As we can see, the methods have been called without the need to implement any interface, so now
they are completely decoupled of Spring.
This is quite useful if we have one or two classes that we need to initialize this way. But what happens if
Do we want to perform initialization or destruction processes in many beans? If we use some convention of
names for these initialization and destruction methods (such as 'initialize' and 'destroy') are not
it is necessary for us to declare 'init-method' and 'destroy-method' for each bean individually. Instead of that,
we can take advantage of the attributes "default-init-method" and "default-destroy-method" of the element "<beans>".
this way we are configuring the Spring bean container to look for these initialization methods and
destruction in each bean that we declare in the container. The Spring IoC container will call these methods,
automatically, every time a bean is created or destroyed. This also helps us to use a convention
of names consistent for methods callback of initialization y destruction ^_^.
To exemplify this, let's modify our class 'University Student' once again by adding a new method.
initialization called 'initialize', which will again display a message in the console, and a destruction method
called 'destroy', which will also display a message in the console:
If we run our application again, we will get the following output in the console:
Building a university student
Initializing routine in the bean.
Student 1: [Link]@6e293a
Carrying out routine destruction in the bean.
As we can see, it has correctly executed the default initialization and destruction methods.
What happens if we specify two methods, one with "init-method" and another with "default-init-method"? In that case, the method
more specific ('init-method' indicated at the bean level) takes precedence over the more general method.
These two ways of configuring the initialization and destruction methods of beans are very good, but what happens
If we are working with annotations? Fortunately, we also have a way to indicate these methods.
callback in case we are using annotations.
Once we have our bean, all we need to do is mark the initialization method using the
@PostConstruct annotation, and the destruction method using the @PreDestroy annotation, as follows:
@PostConstruct
public void initialize()
{
[Link]("Initializing routine in the bean.");
}
@PreDestroy
public void destroy()
{
[Link]("Performing routine destruction in the bean.");
}
When we run this application, we will see the following output appear in the console:
As we can see, it indicates that this configuration has also worked properly ^_^.
In the case of bean construction, the calls to the different methods are made in the following order:
In the destruction of the bean, the methods are executed in the same order:
If for some reason we marked a method to use more than one mechanism (let's say we marked the method
afterPropertiesSet, from the interface InitializingBean, with the annotation @PostConstruct, the method will execute a
only once.
Now that we know everything we need to know about the lifecycle of beans in Spring, we can
finish this tutorial calmly ^_^.
I hope it is useful to you, and as always, don't forget to leave all your questions, comments, and suggestions.
Greetings.