1. Getting started with Spring Framework - Spring in Action - book notes
Tags: java, programming, books, spring
Published: 2022-01-04 18:24:46

---
series: spring-in-action
---

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](https://www.manning.com/books/spring-in-action-sixth-edition) published by [Manning](https://www.manning.com/).

![Spring in Action, Sixth Edition](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/96pw5tkza6n61x2qqm2d.png)

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](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

```xml
<bean id="inventoryService"
      class="com.example.InventoryService"
/>

<bean id="productService"
      class="com.example.ProductService">
      <constructor-arg ref="inventoryService"/>
</bean>
```

```java
@Configuration
public class ServiceConfiguration {
  @Bean
  public InventoryService inventoryService() {
    return new InventoryService();
  }
  
  @Bean
  public ProductService productService() {
    return new ProductService(inventoryService());
  }
}
```

@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:    
```xml
  <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.5.3</version>
    <relativePath />
  </parent>
```

- 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

```sh
$ ./mvnw package
...
$ java -jar target/taco-cloud-0.0.1-SNAPSHOT.jar
```

```sh
$ ./mvnw package
...
$ java -jar target/taco-cloud-0.0.1-SNAPSHOT.jar
```

A baseline application test

- can be used to assert that the application starts

``` java
package tacos;

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

@SpringBootTest
public class TacoCloudApplicationTests {

  @Test
  public void contextLoads() {
  }

}
```

@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

```html
<!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>
```

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...")

```java
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...")));
  }

}
```

@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