1. Getting started with Spring Framework - Spring in Action - book notes
b0r
Posted on January 4, 2022
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.
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>
@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
- 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>
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..)
- @SpringBootConfiguration (specialized form of the
Testing the application
$ ./mvnw package
...
$ java -jar target/taco-cloud-0.0.1-SNAPSHOT.jar
$ ./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
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
<!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...")
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
Posted on January 4, 2022
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.