An Introduction to Spring Boot

An Introduction to Spring Boot

This article gives an overview of various Spring configuration styles and helps you understand the complexity of configuring Spring applications.

This article gives an overview of various Spring configuration styles and helps you understand the complexity of configuring Spring applications.

Spring is a very popular Java-based framework for building web and enterprise applications. Unlike many other frameworks, which focus on only one area, Spring framework provides a wide verity of features addressing the modern business needs via its portfolio projects.

Spring framework provides flexibility to configure beans in multiple ways such as XML, Annotations, and JavaConfig. With the number of features increased the complexity also gets increased and configuring Spring applications becomes tedious and error-prone.

The Spring team created Spring Boot to address the complexity of configuration.

But before diving into SpringBoot, we will take a quick look at the Spring framework and see what kind of problems SpringBoot is trying to address.

In this article we will cover:

  • Overview of Spring framework
  • A web application using Spring MVC and JPA (Hibernate)
  • A quick taste of Spring Boot
Overview of Spring Framework

If you are a Java developer then there is a high chance that you might have heard about Spring framework and probably have used it in your projects. Spring framework was created primarily as a Dependency Injection container but it is much more than that.

Spring is very popular for several reasons:

  • Overview of Spring framework
  • A web application using Spring MVC and JPA (Hibernate)
  • A quick taste of Spring Boot

Along with the Spring framework, there are many other Spring sister projects that help to build applications addressing modern business needs:

  • Overview of Spring framework
  • A web application using Spring MVC and JPA (Hibernate)
  • A quick taste of Spring Boot

There are many other interesting projects addressing various other modern application development needs. For more information, take a look at http://spring.io/projects.

In the initial days, the Spring framework provided an XML-based approach for configuring beans. Later Spring introduced XML-based DSLs, Annotations, and JavaConfig-based approaches for configuring beans.

Let us take a quick look at how each of those configuration styles looks.

XML-Based Configuration

<bean id="userService" class="com.sivalabs.myapp.service.UserService">
    <property name="userDao" ref="userDao"/>
</bean>

<bean id="userDao" class="com.sivalabs.myapp.dao.JdbcUserDao">
    <property name="dataSource" ref="dataSource"/>
</bean>

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
    <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
    <property name="url" value="jdbc:mysql://localhost:3306/test"/>
    <property name="username" value="root"/>
    <property name="password" value="secret"/>
</bean>

Annotation-Based Configuration

@Service
public class UserService
{
    private UserDao userDao;

    @Autowired
    public UserService(UserDao dao){
        this.userDao = dao;
    }
    ...
    ...
}
@Repository
public class JdbcUserDao
{
    private DataSource dataSource;

    @Autowired
    public JdbcUserDao(DataSource dataSource){
        this.dataSource = dataSource;
    }
    ...
    ...
}

JavaConfig-Based Configuration

@Configuration
public class AppConfig
{
    @Bean
    public UserService userService(UserDao dao){
        return new UserService(dao);
    }

    @Bean
    public UserDao userDao(DataSource dataSource){
        return new JdbcUserDao(dataSource);
    }

    @Bean
    public DataSource dataSource(){
        BasicDataSource dataSource = new BasicDataSource();
        dataSource.setDriverClassName("com.mysql.jdbc.Driver");
        dataSource.setUrl("jdbc:mysql://localhost:3306/test");
        dataSource.setUsername("root");
        dataSource.setPassword("secret");
        return dataSource;
    }
}

Wow… Spring provides many approaches for doing the same thing, and we can even mix the approaches and use both JavaConfig- and Annotation-based configuration styles in the same application.

That is a lot of flexibility and it is both good and bad. People new to the Spring framework may get confused about which approach to follow. As of now, the Spring team suggests following a JavaConfig-based approach as it gives more flexibility.

But there is no one-size fits all kind of solution. One has to choose the approach based on their own application needs.

OK, now that you had a glimpse of how various styles of Spring bean configurations look.

Let us take a quick look at what the configuration of a typical SpringMVC + JPA/Hibernate web application configuration looks like.

A Web Application Using Spring MVC and JPA (Hibernate)

Before getting to know what Spring Boot is and what kind of features it provides, let us take a look at how a typical Spring web application configuration looks, the pain points, and how Spring Boot addresses those problems.

Step 1: Configure Maven Dependencies

The first thing we need to do is configure all the dependencies required in our pom.xml.

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="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.0 
                        http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.sivalabs</groupId>
    <artifactId>springmvc-jpa-demo</artifactId>
    <packaging>war</packaging>
    <version>1.0-SNAPSHOT</version>
    <name>springmvc-jpa-demo</name>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>      
        <failOnMissingWebXml>false</failOnMissingWebXml>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>4.2.4.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.data</groupId>
            <artifactId>spring-data-jpa</artifactId>
            <version>1.9.2.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>jcl-over-slf4j</artifactId>
            <version>1.7.13</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.7.13</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>1.7.13</version>
        </dependency>
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>
        <dependency>
            <groupId>com.h2database</groupId>
            <artifactId>h2</artifactId>
            <version>1.4.190</version>
        </dependency>
        <dependency>
            <groupId>commons-dbcp</groupId>
            <artifactId>commons-dbcp</artifactId>
            <version>1.4</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.38</version>
        </dependency>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-entitymanager</artifactId>
            <version>4.3.11.Final</version>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.1.0</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.thymeleaf</groupId>
            <artifactId>thymeleaf-spring4</artifactId>
            <version>2.1.4.RELEASE</version>
        </dependency>
    </dependencies>
</project>

We have configured all our Maven jar dependencies to include Spring MVC, Spring Data JPA, JPA/Hibernate, Thymeleaf, and Log4j.

Step 2: Configure Service/DAO Layer Beans Using JavaConfig

@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(basePackages="com.sivalabs.demo")
@PropertySource(value = { "classpath:application.properties" })
public class AppConfig 
{
    @Autowired
    private Environment env;

    @Bean
    public static PropertySourcesPlaceholderConfigurer placeHolderConfigurer()
    {
        return new PropertySourcesPlaceholderConfigurer();
    }

    @Value("${init-db:false}")
    private String initDatabase;

    @Bean
    public PlatformTransactionManager transactionManager()
    {
        EntityManagerFactory factory = entityManagerFactory().getObject();
        return new JpaTransactionManager(factory);
    }

    @Bean
    public LocalContainerEntityManagerFactoryBean entityManagerFactory()
    {
        LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();

        HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
        vendorAdapter.setGenerateDdl(Boolean.TRUE);
        vendorAdapter.setShowSql(Boolean.TRUE);

        factory.setDataSource(dataSource());
        factory.setJpaVendorAdapter(vendorAdapter);
        factory.setPackagesToScan("com.sivalabs.demo");

        Properties jpaProperties = new Properties();
        jpaProperties.put("hibernate.hbm2ddl.auto", env.getProperty("hibernate.hbm2ddl.auto"));
        factory.setJpaProperties(jpaProperties);

        factory.afterPropertiesSet();
        factory.setLoadTimeWeaver(new InstrumentationLoadTimeWeaver());
        return factory;
    }

    @Bean
    public HibernateExceptionTranslator hibernateExceptionTranslator()
    {
        return new HibernateExceptionTranslator();
    }

    @Bean
    public DataSource dataSource()
    {
        BasicDataSource dataSource = new BasicDataSource();
        dataSource.setDriverClassName(env.getProperty("jdbc.driverClassName"));
        dataSource.setUrl(env.getProperty("jdbc.url"));
        dataSource.setUsername(env.getProperty("jdbc.username"));
        dataSource.setPassword(env.getProperty("jdbc.password"));
        return dataSource;
    }

    @Bean
    public DataSourceInitializer dataSourceInitializer(DataSource dataSource) 
    {
        DataSourceInitializer dataSourceInitializer = new DataSourceInitializer();
        dataSourceInitializer.setDataSource(dataSource);
        ResourceDatabasePopulator databasePopulator = new ResourceDatabasePopulator();
        databasePopulator.addScript(new ClassPathResource("data.sql"));
        dataSourceInitializer.setDatabasePopulator(databasePopulator);
        dataSourceInitializer.setEnabled(Boolean.parseBoolean(initDatabase));
        return dataSourceInitializer;
    }   
}

In our AppConfig.java configuration class we have done the following:

  • Overview of Spring framework
  • A web application using Spring MVC and JPA (Hibernate)
  • A quick taste of Spring Boot

We need to configure property placeholder values in application.properties as follows:

jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/test
jdbc.username=root
jdbc.password=admin
init-db=true
hibernate.dialect=org.hibernate.dialect.MySQLDialect
hibernate.show_sql=true
hibernate.hbm2ddl.auto=update

We can create a simple SQL script data.sql to populate sample data into USER table:

delete from user;
insert into user(id, name) values(1,'Siva');
insert into user(id, name) values(2,'Prasad');
insert into user(id, name) values(3,'Reddy');

We can create log4j.properties file with basic configuration as follows:

log4j.rootCategory=INFO, stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p %t %c{2}:%L - %m%n

log4j.category.org.springframework=INFO
log4j.category.com.sivalabs=DEBUG

Step 3: Configure Spring MVC Web Layer Beans

We will have to configure Thymeleaf ViewResolver, static ResourceHandlers, MessageSource for i18n etc.

@Configuration
@ComponentScan(basePackages = { "com.sivalabs.demo"}) 
@EnableWebMvc
public class WebMvcConfig extends WebMvcConfigurerAdapter
{
    @Bean
    public TemplateResolver templateResolver() {
        TemplateResolver templateResolver = new ServletContextTemplateResolver();
        templateResolver.setPrefix("/WEB-INF/views/");
        templateResolver.setSuffix(".html");
        templateResolver.setTemplateMode("HTML5");
        templateResolver.setCacheable(false);
        return templateResolver;
    }

    @Bean
    public SpringTemplateEngine templateEngine() {
        SpringTemplateEngine templateEngine = new SpringTemplateEngine();
        templateEngine.setTemplateResolver(templateResolver());
        return templateEngine;
    }

    @Bean
    public ThymeleafViewResolver viewResolver() {
        ThymeleafViewResolver thymeleafViewResolver = new ThymeleafViewResolver();
        thymeleafViewResolver.setTemplateEngine(templateEngine());
        thymeleafViewResolver.setCharacterEncoding("UTF-8");
        return thymeleafViewResolver;
    }

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry)
    {
        registry.addResourceHandler("/resources/**").addResourceLocations("/resources/");
    }

    @Override
    public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer)
    {
        configurer.enable();
    }

    @Bean(name = "messageSource")
    public MessageSource configureMessageSource()
    {
        ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
        messageSource.setBasename("classpath:messages");
        messageSource.setCacheSeconds(5);
        messageSource.setDefaultEncoding("UTF-8");
        return messageSource;
    }
}

In our WebMvcConfig.java configuration class we have done the following:

  • Overview of Spring framework
  • A web application using Spring MVC and JPA (Hibernate)
  • A quick taste of Spring Boot

For now we do not have any messages to be configured, so create an empty messages.properties file in src/main/resources folder.

Step 4: Register Spring MVC FrontController Servlet DispatcherServlet

Prior to Servlet 3.x specification we have to register Servlets/Filters in web.xml. Since Servlet 3.x specification we can register Servlets/Filters programatically using ServletContainerInitializer.

Spring MVC provides a convenient class AbstractAnnotationConfigDispatcherServletInitializer to register DispatcherServlet.

public class SpringWebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer
{

    @Override
    protected Class<?>[] getRootConfigClasses()
    {
        return new Class<?>[] { AppConfig.class};
    }

    @Override
    protected Class<?>[] getServletConfigClasses()
    {
        return new Class<?>[] { WebMvcConfig.class };
    }

    @Override
    protected String[] getServletMappings()
    {
        return new String[] { "/" };
    }

    @Override
    protected Filter[] getServletFilters() {
       return new Filter[]{ new OpenEntityManagerInViewFilter() };
    }
}

In our SpringWebAppInitializer.java configuration class we have done the following:

  • Overview of Spring framework
  • A web application using Spring MVC and JPA (Hibernate)
  • A quick taste of Spring Boot

Step 5: Create a JPA Entity and Spring Data JPA Repository

Create a JPA entity User.java and a Spring Data JPA repository for User entity.

@Entity
public class User
{
    @Id @GeneratedValue(strategy=GenerationType.AUTO)
    private Integer id;
    private String name;

    //setters and getters
}
public interface UserRepository extends JpaRepository<User, Integer>
{
}

Step 6: Create a SpringMVC Controller

Create a SpringMVC controller to handle URL “/” and render a list of users.

@Controller
public class HomeController
{
    @Autowired UserRepository userRepo;

    @RequestMapping("/")
    public String home(Model model)
    {
        model.addAttribute("users", userRepo.findAll());
        return "index";
    }
}

Step 7: Create a Thymeleaf View /WEB-INF/views/index.html to Render List of Users

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="utf-8"/>
<title>Home</title>
</head>
<body>
    <table>
        <thead>
            <tr>
                <th>Id</th>
                <th>Name</th>
            </tr>
        </thead>
        <tbody>
            <tr th:each="user : ${users}">
                <td th:text="${user.id}">Id</td>
                <td th:text="${user.name}">Name</td>
            </tr>
        </tbody>
    </table>
</body>
</html>

We are all set now to run the application. But before that we need to download and configure the server like Tomcat or Jetty or Wildfly etc in your IDE.

You can download Tomcat 8 and configure in your favorite IDE, run the application and point your browser to http://localhost:8080/springmvcjpa-demo. You should see the list of users details in a table.

Yay…We did it.

But wait…Isn’t it too much work to just show a list of user details pulled from a database table?

Let us be honest and fair. All this configuration is not just for this one use-case. This configuration is the basis for rest of the application also.

But again, this is too much of work to do if you want to quickly get up and running.

Another problem with it is, assume you want to develop another SpringMVC application with a similar technical stack?

Well, you copy-paste the configuration and tweak it. Right? But remember one thing: if you have to do the same thing again and again, you should find an automated way to do it.

Apart from writing the same configuration again and again, do you see any other problems here?

Well, let me list what are the problems I am seeing here.

  • Overview of Spring framework
  • A web application using Spring MVC and JPA (Hibernate)
  • A quick taste of Spring Boot

If Spring can automatically do it for me that would be awesome!!!.
Imagine, what if Spring is capable of configuring beans automatically? What if you can customize the automatic configuration using simple customizable properties?

For example, instead of mapping DispatcherServlet url-pattern to “/” you want to map it to “/app/”. Instead of putting Thymeleaf views in “/WEB-INF/views” folder you may want to place them in “/WEB-INF/templates/” folder.

So basically you want Spring to do things automatically but provide the flexibility to override the default configuration in a simpler way?

Well, you are about to enter into the world of SpringBoot where your dreams come true!!!

A Quick Taste of Spring Boot

Welcome to Spring Boot! Spring Boot does what exactly you are looking for. It will do things automatically for you but allows you to override the defaults if you want to.

Instead of explaining in theory I prefer to explain by example.

So let us implement the same application that we built earlier but this time using SpringBoot.

Step 1: Create a Maven-Based Spring Boot Project

Create a Maven project and configure the dependencies as follows:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="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.0 
                        http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.sivalabs</groupId>
    <artifactId>hello-springboot</artifactId>
    <packaging>jar</packaging>
    <version>1.0-SNAPSHOT</version>
    <name>hello-springboot</name>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.3.2.RELEASE</version>
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
    </dependencies>
</project>

Wow our pom.xml suddenly become so small!

Step 2: Configure Datasource/JPA Properties in application.properties as Follows

spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/test
spring.datasource.username=root
spring.datasource.password=admin
spring.datasource.initialize=true
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true

You can copy the same data.sql file into src/main/resources folder.

Step 3: Create a JPA Entity and Spring Data JPA Repository Interface for the Entity

Create User.java, UserRepository.java and HomeController.java same as in springmvc-jpa-demo application.

Step 4: Create Thymeleaf View to Show List of Users

Copy /WEB-INF/views/index.html that we created in springmvc-jpa-demo application intosrc/-main/resources/templates folder in our new project.

Step 5: Create SpringBoot EntryPoint Class

Create a Java class Application.java with main method as follows:

@SpringBootApplication
public class Application
{
    public static void main(String[] args)
    {
        SpringApplication.run(Application.class, args);
    }
}

Now run Application.java as a Java Application and point your browser to http://localhost:8080/.

You should see the list of users in table format. Coool!!!

Ok ok, I hear you are shouting “What is going on???”.

Let me explain what just happened.

1. Easy dependency Management

  • Overview of Spring framework
  • A web application using Spring MVC and JPA (Hibernate)
  • A quick taste of Spring Boot

2. Auto Configuration

  • Overview of Spring framework
  • A web application using Spring MVC and JPA (Hibernate)
  • A quick taste of Spring Boot

3. Embedded Servlet Container Support

The most important and surprising thing is we have created a simple Java class annotated with some magical annotation @SpringApplication having a main method and by running that main we are able to run the application and access it at http://localhost:8080/.

Where is the servlet container comes from?

We have added spring-boot-starter-web which pulls the spring-boot-starter-tomcat automatically and when we run the main() method it started tomcat as an embedded container so that we don’t have to deploy our application on any externally installed tomcat server.

By the way have you observe that our packaging type in pom.xml is ‘jar’ not ‘war’. Wonderful!

Ok, but what if I want to use Jetty server instead of tomcat?

Simple, exclude spring-bootstarter-tomcat from spring-boot-starter-web and include spring-boot-starter-jetty.

That’s it.

But, this looks all magical!!!

I can imagine what you are thinking. You are thinking like SpringBoot looks cool and it is doing lot of things automatically for me. But still I am not fully understanding how it is all really working behind the scenes. Right?

I can understand. Watching a magic show is fun normally, but not in Software Development. Don’t worry, we will be looking at each of those things and explain in detail how things are happening behind the scenes in future articles. But I don’t want to overwhelm you by dumping everything onto you right now in this article.

Summary

In this article we had a quick overview of various Spring configuration styles and understand the complexity of configuring Spring applications. Also, we had a quick look at SpringBoot by creating a simple web application.

Spring Boot Tutorial For Beginner- Spring Boot Full Course

Spring Boot Tutorial For Beginner- Spring Boot Full Course

This "Spring Boot Tutorial For Beginner- Spring Boot Full Course" video will help you learn Spring Boot Framework from scratch with examples. This Spring Tutorial is ideal for both beginners as well as professionals who want to master the Spring Boot Framework

Spring Boot Full Course - Learn Spring Boot In 4 Hours | Spring Boot Tutorial For Beginner

Below are the topics covered in this Spring Boot Tutorial for Beginners video:

1:40 What is Spring Boot?
2:35 Features of Spring Boot
3:50 Why Do We Need Spring Boot?
4:30 Spring Boot Market Trend
5:15 Spring vs Spring Boot
6:25 Install & Setup Spring Boot
6:45 System Requirements
7:35 Install & Set up Spring Boot CLI
14:00 Install & Setup Spring Tool Suite
25:40 Model View Controller
26:00 What is MVC?
27:35 Model View Controller Workflow
29:00 What is Dependency Injection?
31:50 Inversion of Control
33:10 Types of Dependency Injection
34:05 Benefits of Dependency Injection
48:35 Auto wire
49:50 Create First Web Application Using Spring Boot
1:06:50 Create a Web Application To Pass Client Data
1:13:40 Model View & Object Example
1:20:30 Create a Submission Form In Spring Boot
1:40:50 Connect Web Application To Database
2:04:50 REST API
2:07:35 What is REST API?
2:08:50 Features of REST API
2:09:35 Principles of REST API
2:11:40 Methods of REST API
2:12:20 REST API Hands-On
2:35:55 Spring Data REST
2:36:55 Spring Data REST Hands-On
2:46:35 Spring Security
2:47:30 Secure Applications Using Spring Boot
2:58:56 Spring Boot Interview Questions

Full-stack Reactive Java with Spring Framework, Spring Boot and Project Reactor

Full-stack Reactive Java with Spring Framework, Spring Boot and Project Reactor

Reactive programming offers Java developers a way to build message-driven, elastic, resilient, and responsive services...yet many Java developers don't know where to begin.

Reactive programming offers Java developers a way to build message-driven, elastic, resilient, and responsive services...yet many Java developers don't know where to begin.

The Reactive Streams initiative provides a baseline and Project Reactor provides a great way to become immediately productive, leveraging reactive capabilities from end to end. Whether you're coming from a Spring MVC environment or a functional perspective, Reactor empowers you to spin up fully reactive Spring Boot 2 applications quickly and efficiently.

In this talk, the presenter dives into the net-new Netty-based web runtime and shows you how to:

  • integrate easily with existing Spring-stack technologies
  • easily transition from blocking to reactive applications & systems
  • define your API in an imperative style and functionally, reaping all benefits both ways
  • leverage powerful new testing mechanisms to make code better and life easier

Thanks for reading

If you liked this post, share it with all of your programming buddies!

Follow us on Facebook | Twitter

Further reading about Java Spring Framework and Spring Boot

Java Programming Masterclass for Software Developers

100+ Java Interview Questions and Answers In 2019

Build a microservices architecture with Spring Boot and Spring Cloud

Spring Framework - Top 50 Questions for Interview In 2019

Building a Simple CRUD App using Spring Boot, MySQL, JPA/Hibernate

Full Stack Web Development with Angular and Spring MVC

Spring Boot vs. Spring MVC vs. Spring: How Do They Compare?

Spring Boot vs. Spring MVC vs. Spring: How Do They Compare?

In this article, you will receive overviews of Spring, Spring MVC, and Spring Boot, learn what problems they solve, and where they’re best applied. The most important thing that you will learn is that Spring, Spring MVC, and Spring Boot are not competing for the same space. They solve different problems and they solve them very well.

In this article, you will receive overviews of Spring, Spring MVC, and Spring Boot, learn what problems they solve, and where they’re best applied. The most important thing that you will learn is that Spring, Spring MVC, and Spring Boot are not competing for the same space. They solve different problems and they solve them very well.

Spring, Spring Boot, Spring MVC, there are springs everywhere! Let's walk through where and when you should apply each of these tools.

What Is the Core Problem That Spring Framework Solves?

Think long and hard. What’s the problem Spring Framework solves?

The most important feature of Spring Framework is Dependency Injection. At the core of all Spring Modules is Dependency Injection or IOC Inversion of Control.
Why is this important? Because, when DI or IOC is used properly, we can develop loosely coupled applications. And loosely coupled applications can be easily unit tested.

Let’s consider a simple example.

Example Without Dependency Injection

Consider the example below: WelcomeController depends on WelcomeService to get the welcome message. What is it doing to get an instance of WelcomeService?

WelcomeService service = new WelcomeService();

It’s creating an instance of it. And that means they are tightly coupled. For example: If I create a mock for WelcomeService in a unit test for WelcomeController, how do I make WelcomeController use the mock? Not easy!

@RestController
public class WelcomeController {

    private WelcomeService service = new WelcomeService();

    @RequestMapping("/welcome")
    public String welcome() {
        return service.retrieveWelcomeMessage();
    }
}

Same Example with Dependency Injection

The world looks much simpler with dependency injection. You let the Spring Framework do the hard work. We just use two simple annotations: @Component and @Autowired.

  • Using @Component, we tell Spring Framework: Hey there, this is a bean that you need to manage.
  • Using @Autowired, we tell Spring Framework: Hey find the correct match for this specific type and autowire it in.

In the example below, Spring framework would create a bean for WelcomeService and autowire it into WelcomeController.

In a unit test, I can ask the Spring framework to auto-wire the mock of WelcomeService into WelcomeController. (Spring Boot makes things easy to do this with @MockBean. But, that’s a different story altogether!)

@Component
public class WelcomeService {
    //Bla Bla Bla
}

@RestController
public class WelcomeController {

    @Autowired
    private WelcomeService service;

    @RequestMapping("/welcome")
    public String welcome() {
        return service.retrieveWelcomeMessage();
    }
}

What Else Does Spring Framework Solve?

Problem 1: Duplication/Plumbing Code

Does Spring Framework stop with Dependency Injection? No. It builds on the core concept of Dependency Injection with a number of Spring Modules

  • Spring JDBC
  • Spring MVC
  • Spring AOP
  • Spring ORM
  • Spring JMS
  • Spring Test

Consider Spring JMS and Spring JDBC for a moment.

Do these modules bring in any new functionality? No. We can do all this with J2EE or Java EE. So, what do these bring in? They bring in simple abstractions. The aim of these abstractions is to

  • Reduce Boilerplate Code/Reduce Duplication
  • Promote Decoupling/Increase Unit Testability

For example, you need much less code to use a JDBCTemplate or a JMSTemplate compared to a traditional JDBC or JMS.

Problem 2: Good Integration With Other Frameworks

The great thing about Spring Framework is that it does not try to solve problems that are already solved. All that it does is to provide a great integration with frameworks which provide great solutions.

  • Hibernate for ORM
  • iBatis for Object Mapping
  • JUnit and Mockito for Unit Testing
What Is the Core Problem That Spring MVC Framework Solves?

Spring MVC Framework provides decoupled way of developing web applications. With simple concepts like Dispatcher Servlet, ModelAndView and View Resolver, it makes it easy to develop web applications.## Why Do We Need Spring Boot?

Spring based applications have a lot of configuration.

When we use Spring MVC, we need to configure component scan, dispatcher servlet, a view resolver, web jars(for delivering static content) among other things.

  <bean
        class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix">
            <value>/WEB-INF/views/</value>
        </property>
        <property name="suffix">
            <value>.jsp</value>
        </property>
  </bean>

  <mvc:resources mapping="/webjars/**" location="/webjars/"/>


The code snippet below shows the typical configuration of a dispatcher servlet in a web application.

    <servlet>
        <servlet-name>dispatcher</servlet-name>
        <servlet-class>
            org.springframework.web.servlet.DispatcherServlet
        </servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>/WEB-INF/todo-servlet.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>dispatcher</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>


When we use Hibernate/JPA, we would need to configure a datasource, an entity manager factory, a transaction manager among a host of other things.

    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
        destroy-method="close">
        <property name="driverClass" value="${db.driver}" />
        <property name="jdbcUrl" value="${db.url}" />
        <property name="user" value="${db.username}" />
        <property name="password" value="${db.password}" />
    </bean>

    <jdbc:initialize-database data-source="dataSource">
        <jdbc:script location="classpath:config/schema.sql" />
        <jdbc:script location="classpath:config/data.sql" />
    </jdbc:initialize-database>

    <bean
        class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
        id="entityManagerFactory">
        <property name="persistenceUnitName" value="hsql_pu" />
        <property name="dataSource" ref="dataSource" />
    </bean>

    <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
        <property name="entityManagerFactory" ref="entityManagerFactory" />
        <property name="dataSource" ref="dataSource" />
    </bean>

    <tx:annotation-driven transaction-manager="transactionManager"/>


Problem #1: Spring Boot Auto Configuration: Can We Think Different?

Spring Boot brings a new thought process around this.

Can we bring more intelligence into this? When a spring mvc jar is added into an application, can we auto configure some beans automatically?* How about auto-configuring a Data Source if Hibernate jar is on the classpath?

  • How about auto-configuring a Dispatcher Servlet if Spring MVC jar is on the classpath?

There would be provisions to override the default auto configuration.

Spring Boot looks at a) Frameworks available on the CLASSPATH b) Existing configuration for the application. Based on these, Spring Boot provides basic configuration needed to configure the application with these frameworks. This is called Auto Configuration.### Problem #2: Spring Boot Starter Projects: Built Around Well-Known Patterns

Let’s say we want to develop a web application.

First of all, we would need to identify the frameworks we want to use, which versions of frameworks to use and how to connect them together.

All web application have similar needs. Listed below are some of the dependencies we use in our Spring MVC Course. These include Spring MVC, Jackson Databind (for data binding), Hibernate-Validator (for server side validation using Java Validation API) and Log4j (for logging). When creating this course, we had to choose the compatible versions of all these frameworks.

<dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-webmvc</artifactId>
   <version>4.2.2.RELEASE</version>
</dependency>

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.5.3</version>
</dependency>

<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-validator</artifactId>
    <version>5.0.2.Final</version>
</dependency>

<dependency>
    <groupId>log4j</groupId>
    <artifactId>log4j</artifactId>
    <version>1.2.17</version>
</dependency>


Here’s what the Spring Boot documentations says about starters.

Starters are a set of convenient dependency descriptors that you can include in your application. You get a one-stop-shop for all the Spring and related technology that you need, without having to hunt through sample code and copy paste loads of dependency descriptors. For example, if you want to get started using Spring and JPA for database access, just include the spring-boot-starter-data-jpa dependency in your project, and you are good to go.
Let’s consider an example starter: Spring Boot Starter Web.

If you want to develop a web application or an application to expose restful services, Spring Boot Start Web is the starter to pick. Let’s create a quick project with Spring Boot Starter Web using Spring Initializr.

Dependency for Spring Boot Starter Web

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>


The following screenshot shows the different dependencies that are added into our application

Dependencies can be classified into:

  • Spring: core, beans, context, aop
  • Web MVC: (Spring MVC)
  • Jackson: for JSON Binding
  • Validation: Hibernate Validator, Validation API
  • Embedded Servlet Container: Tomcat
  • Logging: logback, slf4j

Any typical web application would use all these dependencies. Spring Boot Starter Web comes pre-packaged with these. As a developer, I would not need to worry about either these dependencies or their compatible versions.

Spring Boot Starter Project Options

As we see from Spring Boot Starter Web, starter projects help us in quickly getting started with developing specific types of applications.

  • spring-boot-starter-web-services: SOAP Web Services
  • spring-boot-starter-web: Web and RESTful applications
  • spring-boot-starter-test: Unit testing and Integration Testing
  • spring-boot-starter-jdbc: Traditional JDBC
  • spring-boot-starter-hateoas: Add HATEOAS features to your services
  • spring-boot-starter-security: Authentication and Authorization using Spring Security
  • spring-boot-starter-data-jpa: Spring Data JPA with Hibernate
  • spring-boot-starter-cache: Enabling Spring Framework’s caching support
  • spring-boot-starter-data-rest: Expose Simple REST Services using Spring Data REST
Other Goals of Spring Boot

There are a few starters for technical stuff as well

  • spring-boot-starter-actuator: To use advanced features like monitoring and tracing to your application out of the box
  • spring-boot-starter-undertow, spring-boot-starter-jetty, spring-boot-starter-tomcat: To pick your specific choice of Embedded Servlet Container
  • spring-boot-starter-logging: For Logging using logback
  • spring-boot-starter-log4j2: Logging using Log4j2

Spring Boot aims to enable production ready applications in quick time.

  • Actuator: Enables Advanced Monitoring and Tracing of applications.
  • Embedded Server Integrations: Since the server is integrated into the application, I would need to have a separate application server installed on the server.
  • Default Error Handling