Spring provides an easy way to schedule tasks.
Let's say that we would like to have an information about current time printed on a console periodically.
The class that prints the time may look like this:
We need to define a class that will encapsulate the printing task:
The @Scheduled annotation is the key here: the method reportCurrentTime is annotated by it, therefore it will be invoked every 5 seconds.
You can also specify cron expression. You can use fixedRateString parameter if you want to read it from properties file.
Please note setting of the thread name - it will be needed for the test.
Adding production code only for tests is generally not a good practice, but in this case it can also be used for monitoring purposes.
The spring configuration looks as following:
To run it we need to create an invoker class:
Unfortunately there is no trivial way to test it automatically. We can do it the following way.
Let's create a test class:
When we run the test, the spring context will start and the task will be invoked by scheduler.
We check if the thread with our name exists.
We do it for some time to avoid race condition - it may happen that verification method will be invoked before thread starts.
The whole project alongside with dependencies can be found on github.
Showing posts with label spring. Show all posts
Showing posts with label spring. Show all posts
Wednesday, 26 February 2014
Saturday, 21 September 2013
Transaction management with Spring Data JPA
Spring provides an easy way to manage transactions.
Let's see how to make our methods transactional without using any XML configuration.
We will start with Spring Java config for our application:
We have an entity representing a bank account:
We also have a repository from Spring Data JPA for Account objects:
The TransferService allows transferring money from one account to another:
Just for example sake, we are adding money to one account and before subtracting from the second one, we check if it has enough funds.
If the method wasn't transactional, we would introduce a major bug.
However, @Transactional annotation makes it eligible for rollback if the exception is thrown.
It's also important to note that many methods from the repository are transactional with default propagation, so the transaction from our service will be reused.
Let's make sure that it works by writing an integration test:
If we remove @Transactional annotation the test will fail.
Be aware that managing transactions with Spring have some traps that are described in this article.
The whole project can be found at github.
Let's see how to make our methods transactional without using any XML configuration.
We will start with Spring Java config for our application:
We have an entity representing a bank account:
We also have a repository from Spring Data JPA for Account objects:
The TransferService allows transferring money from one account to another:
Just for example sake, we are adding money to one account and before subtracting from the second one, we check if it has enough funds.
If the method wasn't transactional, we would introduce a major bug.
However, @Transactional annotation makes it eligible for rollback if the exception is thrown.
It's also important to note that many methods from the repository are transactional with default propagation, so the transaction from our service will be reused.
Let's make sure that it works by writing an integration test:
If we remove @Transactional annotation the test will fail.
Be aware that managing transactions with Spring have some traps that are described in this article.
The whole project can be found at github.
Thursday, 29 August 2013
Changing application behavior at runtime with JMX
Sometimes we need to be able to change the behavior of our application without a restart.
JMX, apart from its monitoring capabilities, is a perfect solution for this.
Spring provides great JMX that will ease our task.
Let's start with a simple service, which behavior we will change at runtime.
DiscountService calculates discount based on a globalDiscount - it's value is harcoded for simplicity purposes, it would probably be read from some configuration file or database in more realistic example.
First of all, in order to expose methods to manage globalDiscount we need to add @ManagedResource annotation to our class and add the methods with @ManagedOperation annotation.
We could also use @ManagedAttribute if we would treat these methods as simple getter and setter for globalDiscount.
Class with needed methods and annotations would look like:
In Spring configuration we just need to define the bean for DiscountService and enabling exporting MBeans with MBean server.
We can run the application with:
Now we're ready to manage our service with jconsole:
Our service is exposed locally, but if we want to be able to connect to it remotely, we will need to add following beans to the Spring configuration:
Service is now exposed via RMI.
We can invoke the exposed methods programmatically, which allows us to write some scripts and manage services without using jconsole.
Let's write an integration test to check that it works correctly.
We will need a Spring config for the test with the RMI client.
The test will increment the value of globalDiscount.
Take a closer look at exposed methods invocation, which is very cumbersome, especially if the method has parameters.
The whole project can be found at github.
JMX, apart from its monitoring capabilities, is a perfect solution for this.
Spring provides great JMX that will ease our task.
Let's start with a simple service, which behavior we will change at runtime.
DiscountService calculates discount based on a globalDiscount - it's value is harcoded for simplicity purposes, it would probably be read from some configuration file or database in more realistic example.
First of all, in order to expose methods to manage globalDiscount we need to add @ManagedResource annotation to our class and add the methods with @ManagedOperation annotation.
We could also use @ManagedAttribute if we would treat these methods as simple getter and setter for globalDiscount.
Class with needed methods and annotations would look like:
In Spring configuration we just need to define the bean for DiscountService and enabling exporting MBeans with MBean server.
We can run the application with:
Now we're ready to manage our service with jconsole:
Our service is exposed locally, but if we want to be able to connect to it remotely, we will need to add following beans to the Spring configuration:
Service is now exposed via RMI.
We can invoke the exposed methods programmatically, which allows us to write some scripts and manage services without using jconsole.
Let's write an integration test to check that it works correctly.
We will need a Spring config for the test with the RMI client.
The test will increment the value of globalDiscount.
Take a closer look at exposed methods invocation, which is very cumbersome, especially if the method has parameters.
The whole project can be found at github.
Sunday, 21 July 2013
Caching with Spring Cache
From time to time we need to use a cache in our application.
Instead of writing it on our own and reinventing the wheel, we can use Spring Cache.
Its biggest advantage is unobtrusiveness - besides few annotations we keep our code intact.
Let's see how to do it.
At first let's have a look at some fake service that is the reason for using cache (in real life it may be some database call, web service etc.)
We will cache the invocations of isVipClient(...)
Let's start with adding dependencies to our project:
We'd like to use xml-free spring config, so we will define our beans in java:
We have our SlowService defined as a bean. We also have the cacheManager along with a cache name and its implementation - in our case it's based on ConcurrentHashMap. We can't forget about enabling caching via annotation.
The only thing to do is to add annotation @Cacheable with a cache name to our method:
How to test our cache?
One way to do it is to check if the double invocation of our method with the same parameter will actually execute the method only once.
We will use springockito to inject a spy into our class and verify its behaviour.
We need to start with a spring test context:
Basically the context will read the configuration from java class and will replace the slowService bean with a spy. It would be nicer to do it with an annotation but at the time of this writing the @WrapWithSpy doesn't work (https://bitbucket.org/kubek2k/springockito/issue/33).
Here's our test:
This was the very basic example, spring cache offers more advanced features like cache eviction and update.
The whole project can be found at github.
Instead of writing it on our own and reinventing the wheel, we can use Spring Cache.
Its biggest advantage is unobtrusiveness - besides few annotations we keep our code intact.
Let's see how to do it.
At first let's have a look at some fake service that is the reason for using cache (in real life it may be some database call, web service etc.)
We will cache the invocations of isVipClient(...)
Let's start with adding dependencies to our project:
We'd like to use xml-free spring config, so we will define our beans in java:
We have our SlowService defined as a bean. We also have the cacheManager along with a cache name and its implementation - in our case it's based on ConcurrentHashMap. We can't forget about enabling caching via annotation.
The only thing to do is to add annotation @Cacheable with a cache name to our method:
How to test our cache?
One way to do it is to check if the double invocation of our method with the same parameter will actually execute the method only once.
We will use springockito to inject a spy into our class and verify its behaviour.
We need to start with a spring test context:
Basically the context will read the configuration from java class and will replace the slowService bean with a spy. It would be nicer to do it with an annotation but at the time of this writing the @WrapWithSpy doesn't work (https://bitbucket.org/kubek2k/springockito/issue/33).
Here's our test:
This was the very basic example, spring cache offers more advanced features like cache eviction and update.
The whole project can be found at github.
Thursday, 19 April 2012
JMS with Spring configured in Java
Handling JMS using standard JMS API is a tedious task - you need to create a lot of boilerplate code.
Spring provides an abstraction layer that eases this pain.
In the following example I'm using ActiveMQ (which needs to be started before running any of the code below) but Spring works with other major JMS implementations as well.
In order to send a JMS message we can use JMS template. Here's our sender that's using it:
Spring beans needs to be configured in a context. Let's define Spring configuration in Java code:
JMS template must have a connection factory with a broker url and a destination (in our case it's a queue).
The XML configuration equivalent would look like:
Java configuration provides not only compile-time checking but in my opinion it is more straightforward and easier to control.
Unfortunately we can't escape XML completely, we need to turn on component scanning so that Spring will read configuration from classes in our package:
The example code that would run the sender:
Apart from the sender we can also create the receiver. One of the solutions is to make him asynchronous by implementing MessageListener interface.
The Spring config looks as follows:
Our receiver is set in the message listener container with the connection factory and the destination.
Receiver is missing the same XML configuration as sender, and the running code is analogical.
Here's the list of maven dependencies:
Spring provides an abstraction layer that eases this pain.
In the following example I'm using ActiveMQ (which needs to be started before running any of the code below) but Spring works with other major JMS implementations as well.
In order to send a JMS message we can use JMS template. Here's our sender that's using it:
Spring beans needs to be configured in a context. Let's define Spring configuration in Java code:
JMS template must have a connection factory with a broker url and a destination (in our case it's a queue).
The XML configuration equivalent would look like:
Java configuration provides not only compile-time checking but in my opinion it is more straightforward and easier to control.
Unfortunately we can't escape XML completely, we need to turn on component scanning so that Spring will read configuration from classes in our package:
The example code that would run the sender:
Apart from the sender we can also create the receiver. One of the solutions is to make him asynchronous by implementing MessageListener interface.
The Spring config looks as follows:
Our receiver is set in the message listener container with the connection factory and the destination.
Receiver is missing the same XML configuration as sender, and the running code is analogical.
Here's the list of maven dependencies:
Subscribe to:
Posts (Atom)