SpringBoot Fundamentals and Integration Guide
Learning SpringBoot
Objectives:
- Understand the pros and cons of Spring
- Understand the features of SpringBoot
- Understand the core functionality of SpringBoot
- Set up the SpringBoot environment
- Configure application.properties
- Configure application.yml
- Integrate MyBatis with SpringBoot
- Integrate JUnit with SpringBoot
Section 1: Introduction to SpringBoot
1. Spring Pros and Cons Analysis
-
Advantages
- Spring is a lightweight replacement for Java Enterprise Edition (JEE, formerly J2EE). It provides a relatively simple approach to enterprise Java development by using dependency injection and aspect-oriented programming, enabling POJOs to implement EJB functionality.
-
Disadvantages
- Although Spring's component code is lightweight, its configuration is heavyweight. Initially, Spring used XML configuration, often extensive. Spring 2.5 introduced annotation-based component scanning, reducing explicit XML configuration. Spring 3.0 introduced Java-based configuration, a type-safe, refactorable alternative to XML. All this configuration incurs development overhead, as switching between configuring Spring features and solving business problems wastes time. Like all frameworks, Spring is useful but demands significant effort.
- Additionally, dependency management is time-consuming. During environment setup, you need to determine which library coordinates to import and their transitive dependencies. Selecting the wrong version can cause incompatibility issues, hindering development progress.
2. SpringBoot Overview
2.1 Design Philosophy
SpringBoot improves upon Spring's disadvantages with a convention over configuration approach, allowing developers to focus on writing business logic without switching between configuration and code, greatly improving efficiency and shortening project timelines.
2.2 Features
- Quicck start for Spring-based development
- Out-of-the-box: no code generation or XML configuration required, with defaults adjustable to specific needs
- Provides common non-functional features for large projects: embedded server, security, metrics, health checks, external configuration, etc.
- SpringBoot does not enhance Spring's functionality but provides a fast way to use Spring.
2.3 Four Pillars
- Starter Dependencies: Essentially a Maven POM that defines transitive dependencies for a given feature. Simplifies dependency management.
- AutoConfiguration: Runtime (application startup) process that determines which Spring configuraton to use based on various factors.
- CLI: Command-line tool for quickly developing with Spring using Groovy scripts.
- Actuator: Provides monitoring capabilities (status, beans, environment variables, logs, threads, etc.)
Section 2: SpringBoot Quick Start
1. Code Implementation
1.1 Create Maven Project
Use IntelliJ IDEA to create a simple Maven project (plain Java project).
1.2 Add Starter Dependency
SpringBoot requires inheriting the spring-boot-starter-parent.
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.1.RELEASE</version>
</parent>
To develop Controllers with SpringMVC, import the web starter.
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
1.3 Create SpringBoot Bootstrap Class
@SpringBootApplication
public class PropertyApplication {
public static void main(String[] args) {
SpringApplication.run(PropertyApplication.class);
}
}
1.4 Create Controller
Create UserController in the same or sub-package of the bootstrap class.
@RestController
public class UserController {
@GetMapping("/welcome")
public String welcome() {
return "welcome to springboot";
}
}
1.5 Test
Run the main method of the bootstrap class. Once the server starts, access http://localhost:8080/welcome in a browser.
2. Quick Start Analysis
2.1 Code Explanation
- @SpringBootApplication: Marks the startup class with multiple functions (detailed later).
SpringApplication.run(PropertyApplication.class): Runs the startup class, parameter is the bytecode object of the bootstrap class.
2.2 Hot Deployment
To avoid restarting after modifying code, add the following dependency.
<!-- Hot deployment -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
Note: If hot deployment fails in IntelliJ IDEA, enable automatic compilation: Shift+Ctrl+Alt+/ then select Registry.
2.3 Quick Project Creation
Demonstrate creating a SpringBoot project quickly in IDEA.
Section 3: SpringBoot Configuration Files
1. Configuration File Types
SpringBoot supports three types:
- application.properties
- application.yml
- application.yaml
SpringBoot loads application.properties or application.yml (or .yaml) from the resources directory by default.
2. YML Configuration
2.1 Introduction
YML (YAML Ain't Markup Language) is a human-readable data serialization format, more concise than XML. Files use .yml or .yaml extension.
2.2 Syntax
- Simple data:
key: value # note: space after colon
Example:
port: 9000
- Object/Map data:
key:
property1: value1
property2: value2
Example:
server:
port: 9000
Note: Same indentation level indicates same hierarchy.
- Array/List/Set data:
key:
- value1
- value2
# Inline format:
key: [value1, value2]
Example:
ages:
- 20
- 22
- 24
ages: [20, 22, 24]
Note: Space after the dash.
3. Configuration Properties Reference
To find available configuration keys, refer to the official documentation: Common Application Properties
Common examples:
# Server port
server.port=8080
# Context path
server.servlet.context-path=/property
YAML equivalent:
server:
port: 9000
servlet:
context-path: /property
4. Mapping Configuration to Java Beans
4.1 Using @Value
person:
name: zhangsan
age: 18
@RestController
public class UserController {
@Value("${person.name}")
private String name;
@Value("${person.age}")
private Integer age;
@RequestMapping("/welcome")
public String welcome() {
return "welcome to springboot, name=" + name + ", age=" + age;
}
}
4.2 Using @ConfigurationProperties
person:
name: zhangsan
age: 18
@RestController
@ConfigurationProperties(prefix = "person")
public class UserController {
private String name;
private Integer age;
@GetMapping("/welcome")
public String welcome() {
return "welcome to springboot, name=" + name + ", age=" + age;
}
public void setName(String name) { this.name = name; }
public void setAge(Integer age) { this.age = age; }
}
Note: @ConfigurationProperties requires setter methods; @Value does not.
Section 4: SpringBoot Principle Analysis
1. Starter Dependency Principle
1.1 Analyzing spring-boot-starter-parent
Click on spring-boot-starter-parent in pom.xml. It inherits from spring-boot-dependencies which defines version locks and dependency management.
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.0.1.RELEASE</version>
</parent>
In spring-boot-dependencies, common library versions, dependency management, and plugin management are predefined.
1.2 Analyzing spring-boot-starter-web
Clicking on spring-boot-starter-web reveals it bundles dependencies like spring-web, spring-webmvc, tomcat, etc.
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-json</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</dependency>
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
</dependency>
</dependencies>
Thus, starter dependencies simplify dependency management via transitive dependencies.
2. AutoConfiguration Principle
Analyzing the @SpringBootApplication annotation:
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = {
@Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class)
})
public @interface SpringBootApplication { ... }
@SpringBootConfiguration is equivalent to @Configuration. @EnableAutoConfiguration enables auto-configuration.
@EnableAutoConfiguration imports AutoConfigurationImportSelector which loads class names from META-INF/spring.factories. These class names are auto-configuration classes (e.g., ServletWebServerFactoryAutoConfiguration).
@Configuration
@ConditionalOnClass(ServletRequest.class)
@ConditionalOnWebApplication(type = Type.SERVLET)
@EnableConfigurationProperties(ServerProperties.class)
public class ServletWebServerFactoryAutoConfiguration { ... }
@EnableConfigurationProperties(ServerProperties.class) alllows binding properties with prefix server to the fields of ServerProperties:
@ConfigurationProperties(prefix = "server", ignoreUnknownFields = true)
public class ServerProperties {
private Integer port;
private InetAddress address;
// ...
}
Section 5: SpringBoot Integration with Other Technologies
1. Integrating MyBatis
1.1 Add Dependencies
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.1.1</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
1.2 Database Configuration
spring.datasource.driverClassName=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/property?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai
spring.datasource.username=root
spring.datasource.password=root
1.3 Create User Table
CREATE TABLE `user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(50) DEFAULT NULL,
`password` varchar(50) DEFAULT NULL,
`name` varchar(50) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO `user` VALUES ('1', 'zhangsan', '123', '张三');
INSERT INTO `user` VALUES ('2', 'lisi', '123', '李四');
1.4 Create Entity
public class User {
private Long id;
private String username;
private String password;
private String name;
// getters and setters omitted
}
1.5 Create Mapper Interface
@Mapper
public interface UserMapper {
List<User> queryUserList();
}
1.6 Mapper XML
Create src/main/resources/mapper/UserMapper.xml:
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.qf.spring.boot.mapper.UserMapper">
<select id="queryUserList" resultType="user">
select * from user
</select>
</mapper>
1.7 Configure MyBatis
mybatis.type-aliases-package=com.qf.spring.boot.model
mybatis.mapper-locations=classpath:mapper/*Mapper.xml
1.8 Controller
@RestController
public class UserController {
@Autowired
private UserMapper userMapper;
@GetMapping("/queryUser")
public List<User> queryUser() {
return userMapper.queryUserList();
}
}
2. Integrating JUnit
2.1 Add Dependency
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
2.2 Test Class
@RunWith(SpringRunner.class)
@SpringBootTest(classes = PropertyApplication.class)
public class MapperTest {
@Autowired
private UserMapper userMapper;
@Test
public void test() {
List<User> users = userMapper.queryUserList();
System.out.println(users);
}
}
SpringRunner extends SpringJUnit4ClassRunner. @SpringBootTest specifies the bootstrap class.
3. Integrating JPA
3.1 Add Dependencies
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
3.2 Configure JPA
# DB Configuration (same as above)
# JPA Configuration:
spring.jpa.database=MySQL
spring.jpa.show-sql=true
spring.jpa.generate-ddl=true
spring.jpa.hibernate.ddl-auto=update
spring.jpa.hibernate.naming_strategy=org.hibernate.cfg.ImprovedNamingStrategy
3.3 Entity
@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String username;
private String password;
private String name;
// getters and setters omitted
}
3.4 Repository
public interface UserRepository extends JpaRepository<User, Long> {
List<User> findAll();
}
3.5 Test
@RunWith(SpringRunner.class)
@SpringBootTest(classes = PropertyApplication.class)
public class JpaTest {
@Autowired
private UserRepository userRepository;
@Test
public void test() {
List<User> users = userRepository.findAll();
System.out.println(users);
}
}
3.6 JDK 9 Issue
If using JDK 9, add:
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.0</version>
</dependency>
Section 6: Creating a Custom Starter (rsa-starter)
1. Create Maven Project
(Image: new maven project)
2. Add Dependencies
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<version>2.5.6</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
<version>2.5.6</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<version>2.5.6</version>
</dependency>
</dependencies>
3. Configuration Properties Class
package com.qf.rsa.spring.boot.config;
import org.springframework.boot.context.properties.ConfigurationProperties;
@ConfigurationProperties(prefix = "rsa")
public class RsaProperties {
private String secret;
public String getSecret() { return secret; }
public void setSecret(String secret) { this.secret = secret; }
}
4. Auto-Configuration Class
package com.qf.rsa.spring.boot.config;
import com.qf.rsa.spring.boot.RsaUtil;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.security.NoSuchAlgorithmException;
@Configuration
@ConditionalOnClass(RsaUtil.class)
@EnableConfigurationProperties(RsaProperties.class)
public class RsaAutoConfiguration {
@Bean
@ConditionalOnMissingBean
public RsaUtil rsaUtil(RsaProperties rsaProperties) throws NoSuchAlgorithmException {
RsaUtil rsaUtil = new RsaUtil();
rsaUtil.setRsaProperties(rsaProperties);
rsaUtil.init();
return rsaUtil;
}
}
5. Create spring.factories
Create META-INF/spring.factories in resources:
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ncom.qf.rsa.spring.boot.config.RsaAutoConfiguration
6. Build & Package
Use mvn install.
7. Test in Another Project
Add the starter as a dependency.