The Spring Framework is an application framework and inversion of control container for the Java platform. The framework’s core features can be used by any Java application, but there are extensions for building web applications on top of the Java EE platform.
After generating the project, you must have got your project’s zip file. Unzip the file and import it in your favorite IDE.
The project’s directory structure looks like this –
Running the Application
You can run the application using the following command –
$ mvn spring-boot:run
The application will start on spring boot’s default tomcat port 8080. If you browse http://localhost:8080 on your web browser, the app will respond with a 404 error page because we haven’t created any server endpoint yet.
Let’s do that now.
Defining a Controller
First, Create a new package controller inside com.example.thymeleaftour package, and then create a new file HomeController with the following code –
In the above controller, We have defined a Request Parameter called name. This is an optional parameter with a default value of Guest.
Whenever a user requests the home page, we’ll display the application name and user’s name if it is supplied in the request parameter, or we’ll just show Hello Guest!
Next, We’re adding the name and title attributes to the Model so that they can be accessed from the template.
Finally, we’re returning the template name which will be used to render the response to the browser.
Creating a Thymeleaf Template
All Server side templates go into src/main/resources/templates directory. Create a new file called home.html inside the templates directory with the following contents –
Notice the use of th:text attributes in the template above. It is a thymeleaf attribute, which evaluates the expression present in the value and sets the result as the body of the host tag.
The value "|Hello ${name}!|" in the template, is same as "'Hello' + ${name}". It’s just a syntactic sugar provided by thymeleaf for writing mixed expressions.
Adding static resources
Let’s add some css to our template. All static files in Spring Boot go to src/main/resources/static folder. Create a new folder css inside the static folder and then create a file main.css inside static/css.
Finally, We need to reference the css file inside home.html. Just add the following link tag in the head section of home.html file –
<link rel="stylesheet" href="/css/main.css" />
Running the application
You can run the application by going to the app’s root directory and typing the following command –
$ mvn spring-boot:run
You can browse the application at localhost:8080. Following is a screenshot of the app we just built –
Also, If you pass your name in the request parameter – http://localhost:8080?name=yaniv, then the app will greet you with your name instead of displaying Hello Guest.
Conclusion
In this tutorial, we learned how to use thymeleaf with Spring Boot. You can learn more about thymeleaf’s syntax and features from thymeleaf’s documentation.
Thank you for reading. Please ask any questions in the comment section below.
The Spring Boot annotations are mostly placed in org.springframework.boot.autoconfigure and org.springframework.boot.autoconfigure.condition packages. Let’s learn about some frequently used spring boot annotations as well as which work behind the scene.
1. @SpringBootApplication
Spring boot is mostly about auto-configuration. This auto-configuration is done by component scanning i.e. finding all classes in classspath for @Component annotation. It also involve scanning of @Configuration annotation and initialize some extra beans.
@SpringBootApplication annotation enable all able things in one step. It enables the three features:
This annotation enables auto-configuration of the Spring Application Context, attempting to guess and configure beans that we are likely to need based on the presence of predefined classes in classpath.
For example, if we have tomcat-embedded.jar on the classpath, we are likely to want a TomcatServletWebServerFactory.
As this annotation is already included via @SpringBootApplication, so adding it again on main class has no impact. It is also advised to include this annotation only once via @SpringBootApplication.
Auto-configuration classes are regular Spring Configuration beans. They are located using the SpringFactoriesLoader mechanism (keyed against this class). Generally auto-configuration beans are @Conditional beans (most often using @ConditionalOnClass and @ConditionalOnMissingBean annotations).
3. @SpringBootConfiguration
It indicates that a class provides Spring Boot application configuration. It can be used as an alternative to the Spring’s standard @Configuration annotation so that configuration can be found automatically.
Application should only ever include one @SpringBootConfiguration and most idiomatic Spring Boot applications will inherit it from @SpringBootApplication.
The main difference is both annotations is that @SpringBootConfiguration allows configuration to be automatically located. This can be especially useful for unit or integration tests.
4. @ImportAutoConfiguration
It import and apply only the specified auto-configuration classes. The difference between @ImportAutoConfiguration and @EnableAutoConfiguration is that later attempts to configure beans that are found in the classpath during scanning, whereas @ImportAutoConfiguration only runs the configuration classes that we provide in the annotation.
We should use @ImportAutoConfiguration when we don’t want to enable the default auto-configuration.
We can use the @AutoConfigureAfter or @AutoConfigureBefore annotations if our configuration needs to be applied in a specific order (before of after).
If we want to order certain auto-configurations that should not have any direct knowledge of each other, we can also use @AutoConfigureOrder. That annotation has the same semantic as the regular @Order annotation but provides a dedicated order for auto-configuration classes.
All auto-configuration classes generally have one or more @Conditional annotations. It allow to register a bean only when the condition meets. Following are some useful conditional annotations to use.
5.1. @ConditionalOnBean and @ConditionalOnMissingBean
These annotations let a bean be included based on the presence or absence of specific beans.
It’s value attribute is used to specify beans by type or by name. Also the search attribute lets us limit the ApplicationContext hierarchy that should be considered when searching for beans.
Using these annotations at the class level prevents registration of the @Configuration class as a bean if the condition does not match.
In below example, bean JpaTransactionManager will only be loaded if a bean of type JpaTransactionManager is not already defined in the application context.
5.2. @ConditionalOnClass and @ConditionalOnMissingClass
These annotations let configuration classes be included based on the presence or absence of specific classes. Notice that annotation metadata is parsed by using spring ASM module, and even if a class might not be present in runtime – you can still refer to the class in annotation.
We can also use value attribute to refer the real class or the name attribute to specify the class name by using a String value.
Below configuration will create EmbeddedAcmeService only if this class is available in runtime and no other bean with same name is present in application context.
5.3. @ConditionalOnNotWebApplication and @ConditionalOnWebApplication
These annotations let configuration be included depending on whether the application is a “web application” or not. In Spring, a web application is one which meets at least one of below three requirements:
uses a Spring WebApplicationContext
defines a session scope
has a StandardServletEnvironment
5.4. @ConditionalOnProperty
This annotation lets configuration be included based on the presence and value of a Spring Environment property.
For example, if we have different datasource definitions for different environments, we can use this annotation.
This annotation lets configuration be included only when a specific resource is present in the classpath. Resources can be specified by using the usual Spring conventions.
This annotation lets configuration be included based on the result of a SpEL expression. Use this annotation when condition to evaluate is complex one and shall be evaluated as one condition.
External configurations allow you to work with the same code in different environments. They also provide you the flexibility to tune your application from a single place.
In this article, you’ll learn how to define and use external configurations in Spring Boot with a very simple annotation based API called @ConfigurationProperties.
@ConfigurationProperties bind external configurations to a strongly typed bean in your application code. You can inject and use this bean throughout your application code just like any other spring bean.
Let the exploring begin!
Creating the Application
Let’s create a sample application to learn how to define and use external configurations in spring boot.
We’ll use Spring Boot CLI to initialize the project. Fire up your terminal and type the following command to generate the project –
spring init --dependencies=web --name=config-properties-demo --package-name=com.example.demo config-properties-demo
Alternatively, You may also bootstrap the application from Spring Initializr website by following the instructions below –
Enter config-properties-demo in the Artifact field.
Add Web in the dependencies section.
Click Generate Project to download the project.
Following is the directory structure of the complete application for your reference-
Defining Properties
Spring Boot application loads configuration properties from application.properties file located in the classpath by default.
Open src/main/resources/application.properties file and add the following properties to it
## Top level app properties
app.name=ConfigurationPropertiesDemoApp
app.description=${app.name} is a spring boot app that demonstrates how to use external configuration properties
app.upload-dir=/uploads
app.connect-timeout=500ms
app.read-timeout=10s
## Nested Object Properties (security)
app.security.username=user
app.security.password=123456
app.security.roles=USER,ADMIN,PARTNER # List Property
app.security.enabled=true
## Map Properties (permissions)
app.security.permissions.CAN_VIEW_POSTS=true
app.security.permissions.CAN_EDIT_POSTS=true
app.security.permissions.CAN_DELETE_POSTS=false
app.security.permissions.CAN_VIEW_USERS=true
app.security.permissions.CAN_EDIT_USERS=true
app.security.permissions.CAN_DELETE_USERS=false
Binding external properties to a POJO class using @ConfigurationProperties
Let’s now see how we can bind the properties defined in the application.properties file to a POJO class using @ConfigurationProperties.
The @ConfigurationProperties annotation takes a prefix parameter, and binds all the properties with the specified prefix to the POJO class –
package com.example.demo.config;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.convert.DurationUnit;
import java.time.Duration;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@ConfigurationProperties(prefix = "app")
public class AppProperties {
private String name;
private String description;
private String uploadDir;
private Duration connectTimeout = Duration.ofMillis(1000);
@DurationUnit(ChronoUnit.SECONDS)
private Duration readTimeout = Duration.ofSeconds(30);
private final Security security = new Security();
// Getters and Setters (Omitted for brevity)
public static class Security {
private String username;
private String password;
private List<String> roles = new ArrayList<>();
private boolean enabled;
private Map<String, String> permissions = new HashMap<>();
// Getters and Setters (Omitted for brevity)
}
}
Let’s understand a few details about the binding:
Type-safe binding (List and Map)Notice how the comma separated roles in the properties file are bound to a List of roles and the permissions are bound to a Map.
Duration SupportAlso, note how the duration properties are safely bound to the Duration types. This is so awesome. Spring Boot allows you to specify durations with the following units in the application.properties files –
ns for nanoseconds
us for microseconds
ms for milliseconds
s for seconds
m for minutes
h for hours
d for days
The default unit is milliseconds. So if you don’t specify any unit in the properties file, It will be considered as milliseconds.Note that, you can also override the unit using @DurationUnit annotation as we have done in the above POJO class.
Naming ConventionAll the kebab case property names (ex: upload-dir) are bound to the corresponding camel case fields (ex: uploadDir) in the POJO class.Note that the properties can also be specified in camel case. But using kebab case is recommended.
Enabling Configuration Properties
You need to explicitly register the properties classes using the @EnableConfigurationProperties annotation as shown in the following example.
package com.example.demo;
import com.example.demo.config.AppProperties;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
@SpringBootApplication
@EnableConfigurationProperties(AppProperties.class)
public class ConfigPropertiesDemoApplication {
public static void main(String[] args) {
SpringApplication.run(ConfigPropertiesDemoApplication.class, args);
}
}
Alternatively, you could also add a @Component annotation to the AppProperties class and the binding would still work.
Injecting Configuration Properties in your Spring Beans
The @ConfigurationProperties classes are regular spring beans, and you can inject them in the same way as any other bean.
In the following example, I’ve written a sample API that retrieves app details from configuration properties and returns them to the client –
package com.example.demo.controller;
import com.example.demo.config.AppProperties;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.HashMap;
import java.util.Map;
@RestController
public class IndexController {
// Injecting ConfigurationProperties in your Beans
@Autowired
private AppProperties appProperties;
@GetMapping("/")
public Map<String, String> getAppDetails() {
Map<String, String> appDetails = new HashMap<>();
appDetails.put("name", appProperties.getName());
appDetails.put("description", appProperties.getDescription());
return appDetails;
}
}
@ConfigurationProperties Validation
You can validate configuration properties using javax.validation constraints like @NotNull, @NotEmpty etc.
To enable validation, you just need to add Spring’s @Validated annotation to the @ConfigurationProperties class –
package com.example.demo.config;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.convert.DurationUnit;
import org.springframework.validation.annotation.Validated;
import javax.validation.Valid;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.time.Duration;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@ConfigurationProperties(prefix = "app")
@Validated
public class AppProperties {
@NotNull
private String name;
private String description;
private String uploadDir;
private Duration connectTimeout = Duration.ofMillis(1000);
@DurationUnit(ChronoUnit.SECONDS)
private Duration readTimeout = Duration.ofSeconds(30);
@Valid
private final Security security = new Security();
// Getters and Setters (Omitted for brevity)
public static class Security {
private String username;
private String password;
@NotEmpty
private List<String> roles = new ArrayList<>();
private boolean enabled;
private Map<String, String> permissions = new HashMap<>();
// Getters and Setters (Omitted for brevity)
}
}
Now, The Spring Boot application will throw a validation exception on startup, if the name property is null or the security.roles property is empty
Environment based (Profile specific) Configuration Properties
In addition to the standard application.properties file, Spring Boot also allows you to define profile-specific properties with the following naming convention –
application-{profile}.properties
The profile specific property files are loaded from the same location as the application.properties file, with profile-specific properties always overriding the default ones.
To illustrate this, Let’s define some profile-specific property files, and override some of the default properties –
application-dev.properties## Override properties for dev environment app.name=ConfigurationPropertiesDemoApp-DEVELOPMENT app.security.username=project-dev
application-staging.properties## Override properties for staging environment app.name=ConfigurationPropertiesDemoApp-STAGING app.security.username=project-staging app.security.password=C@ll1C0d3r
application-prod.properties## Override properties for prod environment app.name=ConfigurationPropertiesDemoApp-PRODUCTION app.security.username=project-prod app.security.password=C@ll1C0d3r
Now, we need to activate a spring profile so that the corresponding properties file is loaded by spring boot.
Activating a Spring Profile
You can set active profiles in many ways –
Using application propertiesThe default application.properties file is always loaded by Spring Boot. You can set active profiles in the application.properties file by adding the following property –spring.profiles.active=staging After adding the above property, Spring Boot will load application-staging.properties file as well, and override properties with the new values specified there.
Using command line argumentYou can set active profiles on startup by providing the spring.profiles.active command line argument like this –# Packaging the app mvn clean package -Dspring.profiles.active=staging # Running the packaged jar with `spring.profiles.active` argument java -jar -Dspring.profiles.active=staging target/config-properties-demo-0.0.1-SNAPSHOT.jar Moreover, Here is how you can set active profiles while running the application with spring-boot:run command –mvn spring-boot:run -Dspring.profiles.active=dev
Using environment variableLastly, you can also set active profiles using the SPRING_PROFILES_ACTIVE environment variable-export SPRING_PROFILES_ACTIVE=prod
Running the application
Let’s run the application and access the sample Rest API to see configuration properties in action –
mvn spring-boot:run
$ curl http://localhost:8080
{"name":"ConfigurationPropertiesDemoApp","description":"ConfigurationPropertiesDemoApp is a spring boot app that demonstrates how to use external configuration properties"}
Running the application with active profiles set to prod
mvn spring-boot:run -Dspring.profiles.active=prod
$ curl http://localhost:8080
{"name":"ConfigurationPropertiesDemoApp-PRODUCTION","description":"ConfigurationPropertiesDemoApp-PRODUCTION is a spring boot app that demonstrates how to use external configuration properties"}
Conclusion
@ConfigurationProperties are a really nice way to bind external configurations in a type-safe manner. I use this feature in almost all my projects. Moreover, Spring Boot’s auto-configurations also rely on configuration properties.
Let me know what do you think about this feature in the comment section below.
Spring Boot is powerful yet flexible. It tries to auto-configure most of the stuff for you so that you can get up and running quickly with your application.
It uses sensible defaults during auto-configuration but also gives you the flexibility to change those defaults by just tweaking a few things.
In this article, you’ll learn about the most common configuration tweaks that might need to do in your application.
Changing the embedded server in Spring Boot
Spring Boot uses Tomcat as the default embedded server. If you wanna use some other popular server like Jetty or Undertow then you just need to exclude tomcat dependency and add the other server dependency.
1. Using Jetty as the embedded server in Spring Boot
Changing the default server port and context path in Spring Boot
By default, Spring Boot runs your application on port 8080 with the context path /.
If you wanna change the default port and context path, then it’s just a matter of specifying the corresponding values in the application.properties file –
# HTTP Server port
server.port=8080
# Make the application accessible on the given context path (http://localhost:8080/myapp)
server.servlet.context-path=/myapp
Enabling GZip compression in Spring Boot
GZip compression is a very simple and effective way to save bandwidth and improve the speed of your website.
It reduces the response time of your website by compressing the resources and then sending it over to the clients. It saves bandwidth by at least 50%.
GZip compression is disabled by default in Spring Boot. To enable it, add the following properties to your application.properties file –
# Enable response compression
server.compression.enabled=true
# The comma-separated list of mime types that should be compressed
server.compression.mime-types=text/html,text/xml,text/plain,text/css,text/javascript,application/javascript,application/json
# Compress the response only if the response size is at least 1KB
server.compression.min-response-size=1024
Note that, GZip compression has a small overhead. Therefore I’ve added a min-response-size property to tell spring boot server to compress the response only if the size is more than the given value.
Enabling HTTP/2 support in Spring Boot
HTTP/2 is an improvement over the HTTP1 protocol. It improves the page load speed of your website by employing several mechanisms like data compression, server push, multiplexing of multiple requests over a single TCP connection etc.
You can enable HTTP2 in spring boot with the following property, if the server has support for it –
# Enable HTTP/2 support, if the current environment supports it
server.http2.enabled=true
Enabling browser caching of static resources in Spring Boot
Browser caching is another way to improve the page load speed of your website. You can set cache-control headers to tell browsers to cache static resources until a certain period of time.
Browser caching is disabled by default in Spring Boot. You can enable caching by setting the following properties in the application.properties file.
# Maximum time the response should be cached (in seconds)
spring.resources.cache.cachecontrol.max-age=120
# The cache must re-validate stale resources with the server. Any expired resources must not be used without re-validating.
spring.resources.cache.cachecontrol.must-revalidate=true
Following are few other cache related properties that you should be aware of –
# The resources are private and intended for a single user. They must not be stored by a shared cache (e.g CDN).
spring.resources.cache.cachecontrol.cache-private= # set a boolean value true/false
# The resources are public and any cache may store the response.
spring.resources.cache.cachecontrol.cache-public= # set a boolean value true/false
Configuring multipart file uploads in Spring Boot
Multipart file uploads are enabled by default in Spring Boot with the following property –
spring.servlet.multipart.enabled=true
But there are few other default multipart properties that you might need to change.
By default, Spring Boot allows you to upload a file with a maximum size of 1MB. You might need to change this to the desired value as per your requirements.
Following is the complete set of properties –
# Write files to disk if the file size is more than 2KB.
spring.servlet.multipart.file-size-threshold=2KB
# The intermediate disk location where the uploaded files are written
spring.servlet.multipart.location=/tmp
# Maximum file size that can be uploaded
spring.servlet.multipart.max-file-size=50MB
# Maximum allowed multipart request size
spring.servlet.multipart.max-request-size=75MB
Conclusion
In this short article, you learned how to tweak Spring Boot’s default configurations as per your needs. You can find a full index of common application properties on the following official Spring Boot page –
Whenever you need to configure anything in your spring boot application, the first thing you should do is – check the above common application properties page. Most probably, you’ll find a property for configuring the stuff that you’re looking for.
I hope you enjoyed this article. As always, Thanks for reading.
In this article, You’ll learn how to schedule tasks in Spring Boot using @Scheduled annotation. You’ll also learn how to use a custom thread pool for executing all the scheduled tasks.
The @Scheduled annotation is added to a method along with some information about when to execute it, and Spring Boot takes care of the rest.
Spring Boot internally uses the TaskScheduler interface for scheduling the annotated methods for execution.
The purpose of this article is to build a simple project demonstrating all the concepts related to task scheduling.
Create the Project
Let’s use Spring Boot CLI to create the Project. Fire up your terminal and type the following command to generate the project –
$ spring init --name=scheduler-demo scheduler-demo
Alternatively, You can generate the project using Spring Initializer web app. Just go to http://start.spring.io/, enter the Artifact’s value as “scheduler-demo” and click Generate to generate and download the project.
Once the project is generated, import it in your favorite IDE. The project’s directory structure should like this –
Enable Scheduling
You can enable scheduling simply by adding the @EnableScheduling annotation to the main application class or one of the Configuration classes.
Open SchedulerDemoApplication.java and add @EnableScheduling annotation like so –
package com.example.schedulerdemo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;
@SpringBootApplication
@EnableScheduling
public class SchedulerDemoApplication {
public static void main(String[] args) {
SpringApplication.run(SchedulerDemoApplication.class, args);
}
}
Scheduling Tasks
Scheduling a task with Spring Boot is as simple as annotating a method with @Scheduled annotation, and providing few parameters that will be used to decide the time at which the task will run.
Before adding tasks, Let’s first create the container for all the scheduled tasks. Create a new class called ScheduledTasks inside com.example.schedulerdemo package with the following contents –
package com.example.schedulerdemo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.concurrent.TimeUnit;
@Component
public class ScheduledTasks {
private static final Logger logger = LoggerFactory.getLogger(ScheduledTasks.class);
private static final DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("HH:mm:ss");
public void scheduleTaskWithFixedRate() {}
public void scheduleTaskWithFixedDelay() {}
public void scheduleTaskWithInitialDelay() {}
public void scheduleTaskWithCronExpression() {}
}
The class contains four empty methods. We’ll look at the implementation of all the methods one by one.
All the scheduled methods should follow the following two criteria –
The method should have a void return type.
The method should not accept any arguments.
Cool! Let’s now jump into the implementation.
1. Scheduling a Task with Fixed Rate
You can schedule a method to be executed at a fixed interval by using fixedRate parameter in the @Scheduled annotation. In the following example, The annotated method will be executed every 2 seconds.
@Scheduled(fixedRate = 2000)
public void scheduleTaskWithFixedRate() {
logger.info("Fixed Rate Task :: Execution Time - {}", dateTimeFormatter.format(LocalDateTime.now()) );
}
# Sample Output
Fixed Rate Task :: Execution Time - 10:26:58
Fixed Rate Task :: Execution Time - 10:27:00
Fixed Rate Task :: Execution Time - 10:27:02
....
....
The fixedRate task is invoked at the specified interval even if the previous invocation of the task is not finished.
2. Scheduling a Task with Fixed Delay
You can execute a task with a fixed delay between the completion of the last invocation and the start of the next, using fixedDelay parameter.
The fixedDelay parameter counts the delay after the completion of the last invocation.
Consider the following example –
@Scheduled(fixedDelay = 2000)
public void scheduleTaskWithFixedDelay() {
logger.info("Fixed Delay Task :: Execution Time - {}", dateTimeFormatter.format(LocalDateTime.now()));
try {
TimeUnit.SECONDS.sleep(5);
} catch (InterruptedException ex) {
logger.error("Ran into an error {}", ex);
throw new IllegalStateException(ex);
}
}
Since the task itself takes 5 seconds to complete and we have specified a delay of 2 seconds between the completion of the last invocation and the start of the next, there will be a delay of 7 seconds between each invocation –
# Sample Output
Fixed Delay Task :: Execution Time - 10:30:01
Fixed Delay Task :: Execution Time - 10:30:08
Fixed Delay Task :: Execution Time - 10:30:15
....
....
3. Scheduling a Task With Fixed Rate and Initial Delay
You can use initialDelay parameter with fixedRate and fixedDelay to delay the first execution of the task with the specified number of milliseconds.
In the following example, the first execution of the task will be delayed by 5 seconds and then it will be executed normally at a fixed interval of 2 seconds –
@Scheduled(fixedRate = 2000, initialDelay = 5000)
public void scheduleTaskWithInitialDelay() {
logger.info("Fixed Rate Task with Initial Delay :: Execution Time - {}", dateTimeFormatter.format(LocalDateTime.now()));
}
# Sample output (Server Started at 10:48:46)
Fixed Rate Task with Initial Delay :: Execution Time - 10:48:51
Fixed Rate Task with Initial Delay :: Execution Time - 10:48:53
Fixed Rate Task with Initial Delay :: Execution Time - 10:48:55
....
....
4. Scheduling a Task using Cron Expression
If the above simple parameters can not fulfill your needs, then you can use cron expressions to schedule the execution of your tasks.
In the following example, I have scheduled the task to be executed every minute –
But hey, You can create your own thread pool and configure Spring to use that thread pool for executing all the scheduled tasks.
Create a new package config inside com.example.schedulerdemo, and then create a new class called SchedulerConfig inside config package with the following contents –
package com.example.schedulerdemo.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.SchedulingConfigurer;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.scheduling.config.ScheduledTaskRegistrar;
@Configuration
public class SchedulerConfig implements SchedulingConfigurer {
private final int POOL_SIZE = 10;
@Override
public void configureTasks(ScheduledTaskRegistrar scheduledTaskRegistrar) {
ThreadPoolTaskScheduler threadPoolTaskScheduler = new ThreadPoolTaskScheduler();
threadPoolTaskScheduler.setPoolSize(POOL_SIZE);
threadPoolTaskScheduler.setThreadNamePrefix("my-scheduled-task-pool-");
threadPoolTaskScheduler.initialize();
scheduledTaskRegistrar.setTaskScheduler(threadPoolTaskScheduler);
}
}
That’s all you need to do for configuring Spring to use your own thread pool instead of the default one.
If you log the name of the current thread in the scheduled methods now, you’ll get the output like so –
Current Thread : my-scheduled-task-pool-1
Current Thread : my-scheduled-task-pool-2
# etc...
Conclusion
In this article, you learned how to schedule tasks in Spring Boot using @Scheduled annotation. You also learned how to use a custom thread pool for running these tasks.
The Scheduling abstraction provided by Spring Boot works pretty well for simple use-cases. But if you have more advanced use cases like Persistent Jobs, Clustering, Dynamically adding and triggering new jobs then check out the following article –
Spring Boot is a Spring framework module which provides RAD (Rapid Application Development) feature to the Spring framework. It is highly dependent on the starter templates feature which is very powerful and works flawlessly.
Spring boot modules
1. What is starter template?
Spring Boot starters are templates that contain a collection of all the relevant transitive dependencies that are needed to start a particular functionality. For example, If you want to create a Spring WebMVC application then in a traditional setup, you would have included all required dependencies yourself. It leaves the chances of version conflict which ultimately result in more runtime exceptions.
With Spring boot, to create MVC application all you need to import is spring-boot-starter-web dependency.
<!-- Parent pom is mandatory to control versions of child dependencies --><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.1.6.RELEASE</version><relativePath/></parent><!-- Spring web brings all required dependencies to build web application. --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency>
Above spring-boot-starter-web dependency, internally imports all given dependencies and add to your project. Notice how some dependencies are direct, and some dependencies further refer to other starter templates which transitively downloads more dependencies.
Also, notice that you do not need to provide version information into child dependencies. All versions are resolved in relation to version of parent starter (in our example it’s 2.0.4.RELEASE).
Autoconfiguration is enabled with @EnableAutoConfiguration annotation. Spring boot auto configuration scans the classpath, finds the libraries in the classpath and then attempt to guess the best configuration for them, and finally configure all such beans.
Auto-configuration tries to be as intelligent as possible and will back-away as you define more of your own configuration.
Auto-configuration is always applied after user-defined beans have been registered.
Spring boot auto-configuration logic is implemented in spring-boot-autoconfigure.jar. Yoy can verify the list of packages here.
Spring boot autoconfiguration packages
For example, look at auto-configuration for Spring AOP. It does the followings-
Scan classpath to see if EnableAspectJAutoProxy, Aspect, Advice and AnnotatedElement classes are present.
If classes are not present, no autoconfiguration will be made for Spring AOP.
If classes are found then AOP is configured with Java config annotation @EnableAspectJAutoProxy.
It checks for property spring.aop which value can be true or false.
Based on the value of property, proxyTargetClass attribute is set.
Spring boot applications always include tomcat as embedded server dependency. It means you can run the Spring boot applications from the command prompt without needling complex server infrastructure.
You can exclude tomcat and include any other embedded server if you want. Or you can make exclude server environment altogether. It’s all configuration based.
For example, below configuration exclude tomcat and include jetty as embedded server.
To run the application, we need to use @SpringBootApplication annotation. Behind the scenes, that’s equivalent to @Configuration, @EnableAutoConfiguration, and @ComponentScan together.
It enables the scanning of config classes, files and load them into spring context. In below example, execution start with main() method. It start loading all the config files, configure them and bootstrap the application based on application properties in application.properties file in /resources folder.
### Server port #########server.port=8080### Context root ########server.contextPath=/home
To execute the application, you can run the main() method from IDE such eclipse, or you can build the jar file and execute from command prompt.
$ java -jar spring-boot-demo.jar
5. Advantages of Spring boot
Spring boot helps in resolving dependency conflict. It identifies required dependencies and import them for you.
It has information of compatible version for all dependencies. It minimizes the runtime classloader issues.
It’s “opinionated defaults configuration” approach helps you in configuring most important pieces behind the scene. Override them only when you need. Otherwise everything just works, perfectly. It helps in avoiding boilerplate code, annotations and XML configurations.
It provides embedded HTTP server Tomcat so that you can develop and test quickly.
It has excellent integration with IDEs like eclipse and intelliJ idea.
Administration of spring boot applications using spring boot admin.
This includes health status, various metrics, log level management, JMX-Beans interaction, thread dumps and traces, and much more. Spring Boot Admin is a community project initiated and maintained by code-centric.
Spring boot admin will provide UI to monitor and do some administrative work for your spring boot applications.
This project has been started by codecentric and its open source. You can do your own customization if you want to.
The above video will give you a better idea of what is this project, so we will directly start with an example.
Spring Boot provides actuator endpoints to monitor metrics of individual microservices. These endpoints are very helpful for getting information about applications like if they are up if their components like database etc are working well. But a major drawback or difficulty about using actuator endpoints is that we have to individually hit the endpoints for applications to know their status or health. Imagine microservices involving 150 applications, the admin will have to hit the actuator endpoints of all 150 applications. To help us to deal with this situation we are using Spring Boot Admin app.
Sample Code:
To implement this we will create two projects one is server and another is the client.
Spring Boot Admin server.
Spring Boot Admin client.
Spring Boot Admin Server:
The project structure should look like any spring boot application:
We can notify and send alerts using any below channels.
Email
PagerDuty
OpsGenie
Hipchat
Slack
Let’s Chat
Spring Boot Admin Client:
Now we are ready with the admin server application let us create the client application. Create any HelloWorld spring boot application or if you have any existing spring boot app you can use the same as a client application.
These changes are fine in your client application now run the client application. Once the client application is up and running go and check your admin server application. It will show all your applications.
Beautiful Dashboards:
Spring boot admin is providing a wide range of features. As part of this article, we have just listed very few dig deeper and explore more.
Learn to create and configure spring boot jsp view resolver which uses JSP template files to render view layer. This example uses embedded Tomcat server to run the application.
Maven dependencies – pom.xml
This application uses given below dependencies.
<projectxmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0http://maven.apache.org/maven-v4_0_0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.fusebes</groupId><artifactId>spring-boot-demo</artifactId><packaging>war</packaging><version>0.0.1-SNAPSHOT</version><name>spring-boot-demo Maven Webapp</name><url>http://maven.apache.org</url><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>1.5.1.RELEASE</version></parent><properties><java.version>1.8</java.version></properties><dependencies><!-- Web --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- Tomcat Embed --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-tomcat</artifactId><scope>provided</scope></dependency><!-- JSTL --><dependency><groupId>javax.servlet</groupId><artifactId>jstl</artifactId></dependency><!-- To compile JSP files --><dependency><groupId>org.apache.tomcat.embed</groupId><artifactId>tomcat-embed-jasper</artifactId><scope>provided</scope></dependency></dependencies></project>
Spring Boot Application Initializer
The first step in producing a deployable war file is to provide a SpringBootServletInitializer subclass and override its configure() method. This makes use of Spring Framework’s Servlet 3.0 support and allows you to configure your application when it’s launched by the servlet container.
Controller classes can have methods mapped to specific URLs in the application. In given application, it has two views i.e. “/” and “/next”.
packagecom.fusebes.app.controller;importjava.util.Map;importorg.springframework.stereotype.Controller;importorg.springframework.web.bind.annotation.RequestMapping;@ControllerpublicclassIndexController {@RequestMapping("/")publicString home(Map<String, Object> model) {model.put("message", "Fusebes Reader !!");return"index";}@RequestMapping("/next")publicString next(Map<String, Object> model) {model.put("message", "You are in new page !!");return"next";}}
Spring Boot JSP ViewResolver Configuration
To resolve JSP files location, you can have two approaches.
1) Add entries in application.properties
spring.mvc.view.prefix=/WEB-INF/view/spring.mvc.view.suffix=.jsp//For detailed logging during developmentlogging.level.org.springframework=TRACElogging.level.com=TRACE
2) Configure InternalResourceViewResolver to serve JSP pages
To create any simple spring boot application, we need to start by creating a pom.xml file. Add spring-boot-starter-parent as parent of the project which makes it a spring boot application.pom.xml<?xmlversion="1.0"encoding="UTF-8"?><projectxmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.example</groupId><artifactId>myproject</artifactId><version>0.0.1-SNAPSHOT</version><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.2.1.RELEASE</version></parent></project>Above is simplest spring boot application which can be packaged as jar file. Now import the project in your IDE (optional).
Now we can start adding other starter dependencies that we are likely to need when developing a specific type of application. For example, for a web application, we add a spring-boot-starter-web dependency.pom.xml<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency></dependencies>
Start adding application business logic, views and domain data at this step. By default, Maven compiles sources from src/main/java so create your application code inside this folder only.As the very initial package, add the application bootstrap class and add @SpringBootApplication annotation. This class will be used to run the application. It’s main() method acts as the application entry point.MyApplication.javaimportorg.springframework.boot.SpringApplication;importorg.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplicationpublicclassMyApplication {publicstaticvoidmain(String[] args) {SpringApplication.run(MyApplication.class, args);}}
The SpringApplication class provided in above main() method bootstraps our application, starting Spring, which, in turn, starts the auto-configured Tomcat web server. MyApplication (method argument) indicates the primary Spring component.
Since we used the spring-boot-starter-parent POM, we have a useful “run” goal that we can use to start the application. Type 'mvn spring-boot:run' from the root project directory to start the application.It will start the application which we can verify in console logs as well as in browser by hitting URL: localhost:8080.