DEV Community

b0r
b0r

Posted on

3 2

1. Getting started with Spring Framework - Spring in Action - book notes

Another month, another book.

To refresh my Spring Framework / Spring Boot knowledge (that I'm using on day-to-day basis), I've started reading an excellent Spring in Action, 6th edition published by Manning.

Spring in Action, Sixth Edition

I'm not sure about you, but taking notes (writing/drawing) really helps me get the most out of the book, so I'm sharing everything I have with you (for further reference).

I also really like taking notes in Markdown format. The nice thing about Markdown is, that I can publish it on dev.to and get a nice HTML automatically generated/published for further reference!!

1. Getting started with Spring

This chapter covers

  • Spring and Spring Boot essentials
  • Initializing a Spring project
  • An overview of the Spring landscape

1.1 What is Spring?

Application Context

  • at its core, Spring offers a container, often referred to as the Spring application context, that creates and manages application components
  • these components, or beans, are wired together inside the Spring application context to make a complete application, much like bricks, mortar, timber...are bounded to make a house

  • application components are managed and injected into each other by spring application context

Dependency Injection

  • the act of wiring beans together
  • dependency injected application relies on a separate entity (container) to create and maintain all components and inject those into the beans that need them.
  • typically done through constructor args or property accessor methods
<bean id="inventoryService"
      class="com.example.InventoryService"
/>

<bean id="productService"
      class="com.example.ProductService">
      <constructor-arg ref="inventoryService"/>
</bean>
Enter fullscreen mode Exit fullscreen mode
@Configuration
public class ServiceConfiguration {
  @Bean
  public InventoryService inventoryService() {
    return new InventoryService();
  }

  @Bean
  public ProductService productService() {
    return new ProductService(inventoryService());
  }
}
Enter fullscreen mode Exit fullscreen mode

@Configuration

  • indicates that class provides beans to the Spring application context

@bean

  • indicates that returned object should be added as a bean in the application context

Component Scanning

  • Spring automatically discover components from an application's classpath and create them as bean in the Spring application context

Autowiring

  • Spring automatically injects the components with the other beans that they depend on

Spring Boot

  • most well-known enhancement is auto-configuration
    • make reasonable guesses of what components need to be configured and wired together based on entries in the classpath, env vars,...

1.2 Initializing a Spring application

Initializing a Spring project with Spring Tool Suite

  • Taco Cloud

    • an online app for ordering food
    • dependencies:
    • spring web
    • spring dev tools
    • thymeleaf

Exploring the build specification

  • parent pom provides dependency management for several libraries commonly used in Spring projects:
  <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.5.3</version>
    <relativePath />
  </parent>
Enter fullscreen mode Exit fullscreen mode
  • library version is inherited from the parent version

  • spring boot starter dependencies typically don't have any library code themselves, but instead transitively pull in other libraries

    • you're able to think of your dependencies in terms of what capabilities they provide, rather than their library names
    • you don't have to worry about the library version

Spring Boot Plugin

  • it provides a Maven goal to run the application
  • ensures that all deps. are included within the executable JAR file and available on the runtime classpath
  • produces a manifest file (contains metadata) in the JAR file that denotes the bootstrap class as the main class for the executable JAR

Bootstrapping the application

@SpringBootApplication

  • composite annotation that combines 3 other annotations:
    • @SpringBootConfiguration (specialized form of the @Configuration)
    • @EnableAutoConfiguration (automatically configure any component you might need)
    • @ComponentScan (spring automatically discovers/registers components, services, controllers..)

Testing the application

$ ./mvnw package
...
$ java -jar target/taco-cloud-0.0.1-SNAPSHOT.jar
Enter fullscreen mode Exit fullscreen mode
$ ./mvnw package
...
$ java -jar target/taco-cloud-0.0.1-SNAPSHOT.jar
Enter fullscreen mode Exit fullscreen mode

A baseline application test

  • can be used to assert that the application starts
package tacos;

import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
public class TacoCloudApplicationTests {

  @Test
  public void contextLoads() {
  }

}
Enter fullscreen mode Exit fullscreen mode

@SpringBootTest

  • tells JUnit to bootstrap the test with Spring Boot capabilities
  • ocmposite annotation:
    • @ExtendWith(SpringExtension.class)

1.3 Writing a Spring application

Create Taco Cloud application homepage:

  • create controlle
  • create view template
  • write tests

Handling web requests

Spring MVC

  • controller - a class that handles req/resp
  • @Controller annotation
    • identify class as a component for component scanning
  • home() method
  • @GetMapping
  • return "home"
    • "home" is a logical name of a view
    • template name is derivered from the logical view name /templates/home.html

Defining the view

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" 
      xmlns:th="http://www.thymeleaf.org">
  <head>
    <title>Taco Cloud</title>
  </head>

  <body>
    <h1>Welcome to...</h1>
    <img th:src="@{/images/TacoCloud.png}"/>
  </body>
</html>
Enter fullscreen mode Exit fullscreen mode

Static content, e.g. images are kept in the /src/main/resources/static/

Testing the controller

  • perform the HTTP GET request for the root path '/'
    • expect successful result (viewName = home, content = "Welcome to...")
package tacos;

import static org.hamcrest.Matchers.containsString;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.view;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.test.web.servlet.MockMvc;

@WebMvcTest(HomeController.class)
public class HomeControllerTest {

  @Autowired
  private MockMvc mockMvc;

  @Test
  public void testHomePage() throws Exception {
    mockMvc.perform(get("/"))
      .andExpect(status().isOk())
      .andExpect(view().name("home"))
      .andExpect(content().string(
          containsString("Welcome to...")));
  }

}
Enter fullscreen mode Exit fullscreen mode

@WebMvcTest

  • special annotation provided by spring boot
  • arranges the test to run in the context of a Spring MVC application
    • arranges HomeController to be registered in Spring MVC so that you can send request to it
  • it doesn't start the server (mockin is good enough in this case)
  • the test class is injected with a MockMvc object for the test to drive the mockup

Building and running the application

./mvnw springBoot:run

Spring Boot application tend to bring everything they need with them and don't need to be deployed to some application server. Tomcat is a part of your application.

Getting to know Spring Boot DevTools

Spring DevTools provides developers with some handy development-time tools:

  • automatic application restart when code (or application properties) changes
  • automatic browser refresh
  • automatic disable of template caches
  • built in h2 console/DB

How it works?

  • there are 2 class loaders
    • first one contains you Java code, property files that change frequently
    • second one contains dependency libraries which aren't changed often
  • when change is detected, first class loader is automatically restarted

Let's review

  • initialized project
  • wrote controller
  • defined template
  • wrote simple test

The main benefit is that you can focus on the code that meets the requirements of an application, rather than on satisfying the demands of a framework <- "framework-less framework"

  • declare dependencies in pom.xml
    • web
    • thymeleaf

these two dependencies transitively bring in other dependencies:

  • spring mvc framework
  • embedded tomcat
  • thymeleaf and thymeleaf layout dialect
  • spring auto-configuration library

1.4 Surveying the Spring landscape

  • Spring Framework (Core)
    • provides core container and dependency injection
    • provides Spring MVC, a Spring's web framework, JDBC support, WebFlux (reactive)
  • Spring Boot
    • provides starter dependencies and auto-configuration
    • actuator (runtime insight into the inner workings of the application)
    • flexible specification of env. properties
    • additional testing support
    • Spring Boot CLI (alternative programming model based on Groovy scripts)
  • Spring Date
    • define data repositories as Java interfaces (sql, nosql, graph,..)
  • Spring Security
    • authentication, authorization, API security
  • Spring Integration
    • real time integration where data is processed as it's made available
  • Spring Batch
    • batched integration
  • Spring Cloud
    • check out Cloud Native Spring
  • Spring Native
    • Spring Boot + GraalVM => native images

1.5 Sumary

  • spring aims to make developer challenges easy
    • creating web apps, working with databases, securing applications, and microservices
  • spring boot builds on top of spring to make spring even easier
  • spring applications can be initialized using the spring initializer
  • beans (components) can be declared explicitly with Java or XML, discovered by component scanning, or automatically configured with spring boot auto-configuration

AWS Security LIVE!

Tune in for AWS Security LIVE!

Join AWS Security LIVE! for expert insights and actionable tips to protect your organization and keep security teams prepared.

Learn More

Top comments (0)

Sentry image

See why 4M developers consider Sentry, “not bad.”

Fixing code doesn’t have to be the worst part of your day. Learn how Sentry can help.

Learn more