Spring Boot Overview
Spring Boot is a framework designed to simplify the development of Spring-based applications. It integrates the entire Spring ecosystem and provides a comprehensive solution for enterprise-level J2EE development.
Microservices Architecture
Introduced around 2014 by Martin Fowler, microservices represent an architectural style where an application is composed of small, independent services. These services communicate via HTTP and can be individually replaced or upgraded, contrasting with the traditional monolithic "all in one" appproach.
Environment Setup
- JDK: Version 1.8 is recommended (Spring Boot supports 1.7+).
- Maven: Version 3.3 or higher (e.g., Apache Maven 3.3.9).
- IDE: IntelliJ IDEA 2017.2+ or Spring Tool Suite (STS).
- Spring Boot: Version 1.5.9.RELEASE is used in examples.
Maven Configuration
Add the following profile to your Maven settings.xml to enforce JDK 1.8:
<profile>
<id>jdk-1.8</id>
<activation>
<activeByDefault>true</activeByDefault>
<jdk>1.8</jdk>
</activation>
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<maven.compiler.compilerVersion>1.8</maven.compiler.compilerVersion>
</properties>
</profile>
Hello World Example
1. Create a Maven Project
Package as a JAR file.
2. Add Dependencies
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.9.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
3. Main Application Class
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
4. Create a Controller
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class GreetingController {
@ResponseBody
@RequestMapping("/greet")
public String greet() {
return "Hello World!";
}
}
5. Simplified Deployment
Add the Spring Boot Maven plugin to package the application as an executable JAR:
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
Run the application using java -jar your-app.jar.
How It Works
POM Structure
The parent POM (spring-boot-starter-parent) manages dependency versions. Starters (e.g., spring-boot-starter-web) bundle all required dependencies for specific functionalities.
Main Class Annotation
@SpringBootApplication combines:
@SpringBootConfiguration: Marks the class as a configuration class.@EnableAutoConfiguration: Enables automatic configuration.@ComponentScan: Scans components in the package and sub-packages.
Auto-configuration classes are loaded from META-INF/spring.factories under the classpath.
Quick Project Initialization
Use Spring Initializer in IntelliJ IDEA or STS to generate a project with pre-selected modules. The generated project includes:
- A main application class.
- Standard directory layout:
static/for resources,templates/for views, andapplication.propertiesfor configuraton.
Configuration Files
Spring Boot uses either application.properties or application.yml to override default auto-configuration settings.
YAML Syntax
YAML is a data-centric format:
server:
port: 8081
context-path: /api
Data Formats
- Literals:
key: value(strings usually don't need quotes). - Objects:
user: name: John age: 30 - Lists:
items: - item1 - item2
Property Injection
Bind configuration properties to a JavaBean:
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import java.util.Map;
import java.util.List;
import java.util.Date;
@Component
@ConfigurationProperties(prefix = "app.user")
public class AppUser {
private String firstName;
private Integer age;
private Boolean active;
private Date birthDate;
private Map<String, Object> attributes;
private List<String> roles;
// getters and setters
}
Corresponding YAML:
app:
user:
firstName: hello
age: 18
active: false
birthDate: 2017/12/12
attributes:
k1: v1
k2: 12
roles:
- admin
- user
Add the configuration processor for code completion:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
Configuration Sources
- Command-line arguments (highest priority).
- Java System properties.
- OS environment variables.
- External
application.propertiesorapplication.yml(profile-specific or default). - Internal
application.propertiesorapplication.yml.
Profiles
Define environment-specific configurations:
spring:
profiles:
active: dev
---
spring:
profiles: dev
server:
port: 8083
---
spring:
profiles: prod
server:
port: 8084
Activate a profile via spring.profiles.active=dev or command-line argument --spring.profiles.active=prod.
Auto-Configuration Logic
Spring Boot loads auto-configuration classes listed in META-INF/spring.factories. Each class uses @Conditional annotations to determine if it should apply.
Example: HttpEncodingAutoConfiguration applies only if:
- It is a web application (
@ConditionalOnWebApplication). CharacterEncodingFilteris present (@ConditionalOnClass).
Properties are bound via @ConfigurationProperties (e.g., HttpEncodingProperties).
Enable debug logging to see which auto-configurations are active:
debug=true
Logging
Spring Boot uses SLF4J with Logback by default.
Basic Usage
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class LogExample {
private static final Logger log = LoggerFactory.getLogger(LogExample.class);
public void demo() {
log.trace("Trace message");
log.debug("Debug message");
log.info("Info message");
log.warn("Warning message");
log.error("Error message");
}
}
Custom Configuration
Place logback-spring.xml in the classpath for advanced settings, including profile-specific logging:
<springProfile name="dev">
<pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n</pattern>
</springProfile>
Web Development
Static Resources
Static files are served from:
/META-INF/resources//resources//static//public/
WebJars (e.g., jQuery) are mapped to /webjars/**.
Template Engines
Thymeleaf is the recommended template engine. Place HTML files in classpath:/templates/.
Example:
<html xmlns:th="http://www.thymeleaf.org">
<body>
<h1 th:text="${message}">Default Text</h1>
</body>
</html>
Thymeleaf Expressions
${...}: Variable expression.*{...}: Selection expression.#{...}: Message (i18n) expression.@{...}: Link URL expression.
Extending Spring MVC
Create a configuration class extending WebMvcConfigurerAdapter (without @EnableWebMvc) to add view controllers or interceptors:
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
@Configuration
public class WebConfig extends WebMvcConfigurerAdapter {
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/home").setViewName("index");
}
}
Interceptors
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class AuthInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
if (request.getSession().getAttribute("user") == null) {
response.sendRedirect("/login");
return false;
}
return true;
}
}
Register it in your WebMvcConfigurerAdapter:
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new AuthInterceptor())
.addPathPatterns("/**")
.excludePathPatterns("/login", "/register");
}
Error Handling
Custom error pages can be placed in error/ directory (e.g., error/404.html). For JSON responses, use @ControllerAdvice:
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import java.util.HashMap;
import java.util.Map;
@ControllerAdvice
public class GlobalExceptionHandler {
@ResponseBody
@ExceptionHandler(Exception.class)
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
public Map<String, Object> handleException(Exception ex) {
Map<String, Object> error = new HashMap<>();
error.put("code", "internal_error");
error.put("message", ex.getMessage());
return error;
}
}
Embedded Servlet Containers
Default container is Tomcat. To switch:
- Jetty: Exclude
spring-boot-starter-tomcatand includespring-boot-starter-jetty. - Undertow: Exclude
spring-boot-starter-tomcatand includespring-boot-starter-undertow.
Customize container settings in application.properties:
server.port=8082
server.tomcat.uri-encoding=UTF-8
Registering Servlets, Filters, and Listeners
@Bean
public ServletRegistrationBean customServlet() {
return new ServletRegistrationBean(new CustomServlet(), "/custom/*");
}
@Bean
public FilterRegistrationBean customFilter() {
FilterRegistrationBean bean = new FilterRegistrationBean(new CustomFilter());
bean.setUrlPatterns(Arrays.asList("/api/*"));
return bean;
}
Data Access
JDBC
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
Configuration:
spring:
datasource:
url: jdbc:mysql://localhost:3306/mydb
username: root
password: secret
driver-class-name: com.mysql.jdbc.Driver
Use JdbcTemplate for database operations.
Druid DataSource
import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.sql.DataSource;
@Configuration
public class DataSourceConfig {
@Bean
@ConfigurationProperties(prefix = "spring.datasource")
public DataSource dataSource() {
return new DruidDataSource();
}
}
MyBatis
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.1</version>
</dependency>
Annotation-based mapper:
import org.apache.ibatis.annotations.*;
@Mapper
public interface ProductMapper {
@Select("SELECT * FROM product WHERE id = #{id}")
Product findById(Integer id);
@Insert("INSERT INTO product(name) VALUES(#{name})")
@Options(useGeneratedKeys = true, keyProperty = "id")
int insert(Product product);
}
Spring Data JPA
import javax.persistence.*;
@Entity
@Table(name = "customer")
public class Customer {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
@Column(name = "full_name")
private String fullName;
// getters and setters
}
import org.springframework.data.jpa.repository.JpaRepository;
public interface CustomerRepository extends JpaRepository<Customer, Integer> {
}
Configuration:
spring:
jpa:
hibernate:
ddl-auto: update
show-sql: true
Docker Basics
Docker packages applications into containers.
Common Commands
docker pull image_name:tag: Download an image.docker run -d -p host_port:container_port --name my_container image_name: Start a container.docker ps: List running containers.docker stop container_id: Stop a container.docker rm container_id: Remove a container.docker rmi image_id: Remove an image.
MySQL Example
docker run -p 3306:3306 --name mysql_db -e MYSQL_ROOT_PASSWORD=password -d mysql
Custom Starters
A starter includes:
- Dependency module: Groups required dependencies.
- Auto-configuration module: Contains configuration classes and properties.
Auto-configuration class example:
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.condition.ConditionalOnWebApplication;
@Configuration
@ConditionalOnWebApplication
@EnableConfigurationProperties(CustomProperties.class)
public class CustomAutoConfiguration {
@Bean
public CustomService customService() {
return new CustomService();
}
}
Register in META-INF/spring.factories:
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\n com.example.CustomAutoConfiguration
Application Startup Lifecycle
Key steps during SpringApplication.run():
- Initialize
SpringApplication(detect web environment, load initializers/listeners). - Start
SpringApplicationRunListeners. - Prepare and configure the environment.
- Create the ApplicationContext.
- Apply initializers and load context.
- Refresh the context (load beans, auto-configuration).
- Call
ApplicationRunnerandCommandLineRunnerbeans. - Notify listeners that the application is ready.