为什么要用 Spring Boot ?原理剖析

目录

  1. [Spring Boot 概述](#Spring Boot 概述 "#1-spring-boot-%E6%A6%82%E8%BF%B0")
  2. 核心原理
  3. 启动流程详解
  4. 自动配置机制
  5. 内嵌服务器原理
  6. 外部化配置
  7. Actuator监控
  8. 最佳实践

1. Spring Boot 概述

1.1 什么是Spring Boot

Spring Boot是一个基于Spring框架的快速开发框架,它简化了Spring应用的初始搭建和开发过程。Spring Boot的核心思想是"约定优于配置",通过自动配置、起步依赖、内嵌服务器等特性,让开发者能够快速构建生产就绪的Spring应用。

1.2 Spring Boot的优势

  • 快速启动:内嵌Tomcat、Jetty等服务器,无需部署WAR文件
  • 自动配置:根据classpath中的jar包自动配置Spring应用
  • 起步依赖:提供了一系列starter依赖,简化Maven配置
  • 生产就绪:提供监控、健康检查、外部化配置等特性
  • 无代码生成:无需XML配置,完全基于Java配置

2. 核心原理

2.1 核心注解

@SpringBootApplication

这是Spring Boot的核心注解,它是一个组合注解,包含了以下三个注解:

java 复制代码
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan
public @interface SpringBootApplication {
    // ...
}
  • @SpringBootConfiguration:标识这是一个Spring Boot的配置类
  • @EnableAutoConfiguration:启用Spring Boot的自动配置机制
  • @ComponentScan:启用组件扫描,自动扫描包下的组件

@EnableAutoConfiguration

这个注解是Spring Boot自动配置的核心,它通过以下机制实现自动配置:

java 复制代码
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {
    // ...
}

2.2 自动配置原理

Spring Boot的自动配置基于以下机制:

  1. 条件注解:使用@ConditionalOnClass、@ConditionalOnMissingBean等条件注解
  2. 配置类:通过@Configuration注解的配置类
  3. 属性绑定:通过@ConfigurationProperties绑定配置文件中的属性
  4. Bean定义:通过@Bean注解定义Bean

3. 启动流程详解

3.1 启动入口

Spring Boot应用的启动入口是SpringApplication.run()方法:

java 复制代码
public class LearningApplication {
    public static void main(String[] args) {
        SpringApplication.run(LearningApplication.class, args);
    }
}

3.2 启动流程步骤

第一步:创建SpringApplication对象

java 复制代码
public SpringApplication(Class<?>... primarySources) {
    this(null, primarySources);
}

public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {
    this.resourceLoader = resourceLoader;
    Assert.notNull(primarySources, "PrimarySources must not be null");
    this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources));
    this.webApplicationType = WebApplicationType.deduceFromClasspath();
    this.bootstrapRegistryInitializers = new ArrayList<>(
            getSpringFactoriesInstances(BootstrapRegistryInitializer.class));
    setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));
    setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
    this.mainApplicationClass = deduceMainApplicationClass();
}

第二步:运行SpringApplication

java 复制代码
public ConfigurableApplicationContext run(String... args) {
    StopWatch stopWatch = new StopWatch();
    stopWatch.start();
    DefaultBootstrapContext bootstrapContext = null;
    ConfigurableApplicationContext context = null;
    Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList<>();
    
    try {
        // 1. 创建BootstrapContext
        bootstrapContext = createBootstrapContext();
        
        // 2. 设置系统属性
        configureHeadlessProperty();
        
        // 3. 获取SpringApplicationRunListeners
        SpringApplicationRunListeners listeners = getRunListeners(args);
        listeners.starting(bootstrapContext, this.mainApplicationClass);
        
        // 4. 准备环境
        ConfigurableEnvironment environment = prepareEnvironment(listeners, bootstrapContext, args);
        configureIgnoreBeanInfo(environment);
        
        // 5. 打印Banner
        Banner printedBanner = printBanner(environment);
        
        // 6. 创建ApplicationContext
        context = createApplicationContext();
        
        // 7. 准备ApplicationContext
        prepareContext(context, environment, listeners, printedBanner, args);
        
        // 8. 刷新ApplicationContext
        refreshContext(context);
        
        // 9. 刷新后的处理
        afterRefresh(context, args);
        
        stopWatch.stop();
        if (this.logStartupInfo) {
            new StartupInfoLogger(this.mainApplicationClass).logStarted(getApplicationLog(), stopWatch);
        }
        
        // 10. 发布ApplicationStartedEvent事件
        listeners.started(context);
        
        // 11. 调用ApplicationRunner和CommandLineRunner
        callRunners(context, args);
        
    } catch (Throwable ex) {
        handleRunFailure(context, ex, exceptionReporters, listeners);
        throw new IllegalStateException(ex);
    }
    
    try {
        // 12. 发布ApplicationReadyEvent事件
        listeners.running(context);
    } catch (Throwable ex) {
        handleRunFailure(context, ex, exceptionReporters, null);
        throw new IllegalStateException(ex);
    }
    
    return context;
}

3.3 关键步骤详解

3.3.1 环境准备

java 复制代码
private ConfigurableEnvironment prepareEnvironment(SpringApplicationRunListeners listeners,
        DefaultBootstrapContext bootstrapContext, String[] args) {
    ConfigurableEnvironment environment = getOrCreateEnvironment();
    configureEnvironment(environment, args);
    ConfigurationPropertySources.attach(environment);
    listeners.environmentPrepared(bootstrapContext, environment);
    DefaultPropertiesPropertySource.moveToEnd(environment);
    Assert.state(!environment.containsProperty("spring.main.environment-prefix"),
            "Environment prefix cannot be modified once set");
    bindToSpringApplication(environment);
    if (!this.isCustomEnvironment) {
        environment = new EnvironmentConverter(getClassLoader()).convertEnvironmentIfNecessary(environment,
                deduceEnvironmentClass());
    }
    ConfigurationPropertySources.attach(environment);
    return environment;
}

3.3.2 创建ApplicationContext

java 复制代码
protected ConfigurableApplicationContext createApplicationContext() {
    Class<?> contextClass = this.applicationContextClass;
    if (contextClass == null) {
        try {
            switch (this.webApplicationType) {
                case SERVLET:
                    contextClass = Class.forName(DEFAULT_SERVLET_WEB_CONTEXT_CLASS);
                    break;
                case REACTIVE:
                    contextClass = Class.forName(DEFAULT_REACTIVE_WEB_CONTEXT_CLASS);
                    break;
                default:
                    contextClass = Class.forName(DEFAULT_CONTEXT_CLASS);
            }
        } catch (ClassNotFoundException ex) {
            throw new IllegalStateException(
                    "Unable create a default ApplicationContext, please specify an ApplicationContextClass", ex);
        }
    }
    return (ConfigurableApplicationContext) BeanUtils.instantiateClass(contextClass);
}

3.3.3 刷新ApplicationContext

java 复制代码
private void refreshContext(ConfigurableApplicationContext context) {
    if (this.registerShutdownHook) {
        try {
            context.registerShutdownHook();
        } catch (AccessControlException ex) {
            // Not allowed in some environments.
        }
    }
    refresh(context);
}

4. 自动配置机制

4.1 自动配置原理

Spring Boot的自动配置通过以下步骤实现:

  1. 扫描classpath:扫描classpath中存在的类
  2. 加载配置:从META-INF/spring.factories加载配置类
  3. 条件判断:根据条件注解判断是否需要创建Bean
  4. 创建Bean:满足条件时创建相应的Bean

4.2 spring.factories文件

Spring Boot通过META-INF/spring.factories文件来配置自动配置类:

properties 复制代码
# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration,\
org.springframework.boot.autoconfigure.aop.AopAutoConfiguration,\
org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration,\
org.springframework.boot.autoconfigure.batch.BatchAutoConfiguration,\
org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration,\
org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfiguration,\
org.springframework.boot.autoconfigure.cloud.CloudServiceConnectorsAutoConfiguration,\
org.springframework.boot.autoconfigure.context.ConfigurationPropertiesAutoConfiguration,\
org.springframework.boot.autoconfigure.context.MessageSourceAutoConfiguration,\
org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration,\
org.springframework.boot.autoconfigure.couchbase.CouchbaseAutoConfiguration,\
org.springframework.boot.autoconfigure.dao.PersistenceExceptionTranslationAutoConfiguration,\
org.springframework.boot.autoconfigure.data.cassandra.CassandraDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.cassandra.CassandraRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.couchbase.CouchbaseDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.couchbase.CouchbaseRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchAutoConfiguration,\
org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.jpa.JpaRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.ldap.LdapDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.ldap.LdapRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.mongo.MongoDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.mongo.MongoRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.neo4j.Neo4jDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.neo4j.Neo4jRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.solr.SolrRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration,\
org.springframework.boot.autoconfigure.data.redis.RedisRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.rest.RepositoryRestMvcAutoConfiguration,\
org.springframework.boot.autoconfigure.data.web.SpringDataWebAutoConfiguration,\
org.springframework.boot.autoconfigure.elasticsearch.jest.JestAutoConfiguration,\
org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration,\
org.springframework.boot.autoconfigure.freemarker.FreeMarkerAutoConfiguration,\
org.springframework.boot.autoconfigure.gson.GsonAutoConfiguration,\
org.springframework.boot.autoconfigure.h2.H2ConsoleAutoConfiguration,\
org.springframework.boot.autoconfigure.hateoas.HypermediaAutoConfiguration,\
org.springframework.boot.autoconfigure.hazelcast.HazelcastAutoConfiguration,\
org.springframework.boot.autoconfigure.hazelcast.HazelcastJpaDependencyAutoConfiguration,\
org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration,\
org.springframework.boot.autoconfigure.http.codec.CodecsAutoConfiguration,\
org.springframework.boot.autoconfigure.influx.InfluxDbAutoConfiguration,\
org.springframework.boot.autoconfigure.info.ProjectInfoAutoConfiguration,\
org.springframework.boot.autoconfigure.integration.IntegrationAutoConfiguration,\
org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.JndiDataSourceAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.XADataSourceAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.h2.H2ConsoleAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.metadata.DataSourcePoolMetadataProvidersConfiguration,\
org.springframework.boot.autoconfigure.jms.JmsAutoConfiguration,\
org.springframework.boot.autoconfigure.jmx.JmxAutoConfiguration,\
org.springframework.boot.autoconfigure.jms.JndiConnectionFactoryAutoConfiguration,\
org.springframework.boot.autoconfigure.jms.activemq.ActiveMQAutoConfiguration,\
org.springframework.boot.autoconfigure.jms.artemis.ArtemisAutoConfiguration,\
org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration,\
org.springframework.boot.autoconfigure.groovy.template.GroovyTemplateAutoConfiguration,\
org.springframework.boot.autoconfigure.jersey.JerseyAutoConfiguration,\
org.springframework.boot.autoconfigure.jooq.JooqAutoConfiguration,\
org.springframework.boot.autoconfigure.kafka.KafkaAutoConfiguration,\
org.springframework.boot.autoconfigure.ldap.embedded.EmbeddedLdapAutoConfiguration,\
org.springframework.boot.autoconfigure.ldap.LdapAutoConfiguration,\
org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration,\
org.springframework.boot.autoconfigure.mail.MailSenderAutoConfiguration,\
org.springframework.boot.autoconfigure.mail.MailSenderValidatorAutoConfiguration,\
org.springframework.boot.autoconfigure.mobile.DeviceResolverAutoConfiguration,\
org.springframework.boot.autoconfigure.mobile.DeviceDelegatingViewResolverAutoConfiguration,\
org.springframework.boot.autoconfigure.mobile.SitePreferenceAutoConfiguration,\
org.springframework.boot.autoconfigure.mongo.embedded.EmbeddedMongoAutoConfiguration,\
org.springframework.boot.autoconfigure.mustache.MustacheAutoConfiguration,\
org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration,\
org.springframework.boot.autoconfigure.reactor.ReactorAutoConfiguration,\
org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration,\
org.springframework.boot.autoconfigure.security.servlet.SecurityRequestMatcherProviderAutoConfiguration,\
org.springframework.boot.autoconfigure.security.servlet.UserDetailsServiceAutoConfiguration,\
org.springframework.boot.autoconfigure.security.servlet.SecurityFilterAutoConfiguration,\
org.springframework.boot.autoconfigure.sendgrid.SendGridAutoConfiguration,\
org.springframework.boot.autoconfigure.session.SessionAutoConfiguration,\
org.springframework.boot.autoconfigure.social.SocialWebAutoConfiguration,\
org.springframework.boot.autoconfigure.social.FacebookAutoConfiguration,\
org.springframework.boot.autoconfigure.social.LinkedInAutoConfiguration,\
org.springframework.boot.autoconfigure.social.TwitterAutoConfiguration,\
org.springframework.boot.autoconfigure.solr.SolrAutoConfiguration,\
org.springframework.boot.autoconfigure.thymeleaf.ThymeleafAutoConfiguration,\
org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration,\
org.springframework.boot.autoconfigure.transaction.jta.JtaAutoConfiguration,\
org.springframework.boot.autoconfigure.validation.ValidationAutoConfiguration,\
org.springframework.boot.autoconfigure.web.client.RestTemplateAutoConfiguration,\
org.springframework.boot.autoconfigure.web.embedded.EmbeddedWebServerFactoryCustomizerAutoConfiguration,\
org.springframework.boot.autoconfigure.web.reactive.ReactiveWebServerFactoryAutoConfiguration,\
org.springframework.boot.autoconfigure.web.reactive.ReactiveWebServerFactoryCustomizerAutoConfiguration,\
org.springframework.boot.autoconfigure.web.reactive.WebFluxAutoConfiguration,\
org.springframework.boot.autoconfigure.web.reactive.error.ErrorWebFluxAutoConfiguration,\
org.springframework.boot.autoconfigure.web.reactive.function.client.WebClientAutoConfiguration,\
org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration,\
org.springframework.boot.autoconfigure.web.servlet.error.ErrorMvcAutoConfiguration,\
org.springframework.boot.autoconfigure.web.servlet.HttpEncodingAutoConfiguration,\
org.springframework.boot.autoconfigure.web.servlet.MultipartAutoConfiguration,\
org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration,\
org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration,\
org.springframework.boot.autoconfigure.websocket.reactive.WebSocketReactiveAutoConfiguration,\
org.springframework.boot.autoconfigure.websocket.servlet.WebSocketServletAutoConfiguration,\
org.springframework.boot.autoconfigure.websocket.servlet.WebSocketMessagingAutoConfiguration,\
org.springframework.boot.autoconfigure.webservices.WebServicesAutoConfiguration,\
org.springframework.boot.autoconfigure.webservices.client.WebServiceTemplateAutoConfiguration

4.3 条件注解详解

Spring Boot使用条件注解来控制Bean的创建:

@ConditionalOnClass

当classpath中存在指定的类时,条件成立:

java 复制代码
@Configuration
@ConditionalOnClass({DataSource.class, EmbeddedDatabaseType.class})
@EnableConfigurationProperties(DataSourceProperties.class)
@Import({DataSourcePoolMetadataProvidersConfiguration.class, DataSourceInitializationConfiguration.class})
public class DataSourceAutoConfiguration {
    // ...
}

@ConditionalOnMissingBean

当Spring容器中不存在指定的Bean时,条件成立:

java 复制代码
@Bean
@ConditionalOnMissingBean
public DataSource dataSource() {
    return new EmbeddedDataSourceBuilder()
        .setType(EmbeddedDatabaseType.H2)
        .build();
}

@ConditionalOnProperty

当指定的属性满足条件时,条件成立:

java 复制代码
@Configuration
@ConditionalOnProperty(name = "spring.datasource.type", havingValue = "com.zaxxer.hikari.HikariDataSource")
public class HikariAutoConfiguration {
    // ...
}

4.4 自定义自动配置

4.4.1 创建配置类

java 复制代码
@Configuration
@ConditionalOnClass(MyService.class)
@EnableConfigurationProperties(MyServiceProperties.class)
public class MyServiceAutoConfiguration {
    
    @Autowired
    private MyServiceProperties properties;
    
    @Bean
    @ConditionalOnMissingBean
    public MyService myService() {
        return new MyService(properties.getPrefix(), properties.getSuffix());
    }
}

4.4.2 创建属性类

java 复制代码
@ConfigurationProperties(prefix = "my.service")
public class MyServiceProperties {
    private String prefix = "Hello";
    private String suffix = "World";
    
    // getters and setters
}

4.4.3 注册自动配置

META-INF/spring.factories中添加:

properties 复制代码
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.example.MyServiceAutoConfiguration

5. 内嵌服务器原理

5.1 支持的服务器

Spring Boot支持以下内嵌服务器:

  • Tomcat:默认的Servlet容器
  • Jetty:轻量级的Servlet容器
  • Undertow:高性能的Servlet容器

5.2 服务器选择逻辑

java 复制代码
private WebApplicationType deduceFromClasspath() {
    if (ClassUtils.isPresent("org.springframework.web.reactive.DispatcherHandler", null)
            && !ClassUtils.isPresent("org.springframework.web.servlet.DispatcherServlet", null)
            && !ClassUtils.isPresent("org.glassfish.jersey.servlet.ServletContainer", null)) {
        return WebApplicationType.REACTIVE;
    }
    for (String className : SERVLET_INDICATOR_CLASSES) {
        if (!ClassUtils.isPresent(className, null)) {
            return WebApplicationType.NONE;
        }
    }
    return WebApplicationType.SERVLET;
}

5.3 服务器配置

5.3.1 端口配置

properties 复制代码
# application.properties
server.port=8080

5.3.2 上下文路径配置

properties 复制代码
server.servlet.context-path=/myapp

5.3.3 连接器配置

java 复制代码
@Component
public class MyTomcatConnectorCustomizer implements TomcatConnectorCustomizer {
    
    @Override
    public void customize(Connector connector) {
        connector.setProperty("connectionTimeout", "20000");
        connector.setProperty("maxThreads", "200");
    }
}

5.4 服务器启动流程

  1. 创建WebServer:根据WebApplicationType创建相应的WebServer
  2. 配置连接器:配置端口、协议等连接器参数
  3. 启动服务器:启动内嵌的Web服务器
  4. 注册Servlet:注册DispatcherServlet等核心Servlet

6. 外部化配置

6.1 配置源优先级

Spring Boot的配置源按以下优先级加载(从高到低):

  1. 命令行参数
  2. JNDI属性
  3. Java系统属性(System.getProperties())
  4. 操作系统环境变量
  5. 配置文件(application.properties/application.yml)
  6. @ConfigurationProperties注解的类

6.2 配置文件

6.2.1 application.properties

properties 复制代码
# 数据库配置
spring.datasource.url=jdbc:mysql://localhost:3306/test
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

# JPA配置
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true

# 日志配置
logging.level.root=INFO
logging.level.com.example=DEBUG

6.2.2 application.yml

yaml 复制代码
spring:
  datasource:
    url: jdbc:mysql://localhost:3306/test
    username: root
    password: 123456
    driver-class-name: com.mysql.cj.jdbc.Driver
  
  jpa:
    hibernate:
      ddl-auto: update
    show-sql: true

logging:
  level:
    root: INFO
    com.example: DEBUG

6.3 环境特定配置

6.3.1 配置文件命名

  • application-dev.properties:开发环境
  • application-test.properties:测试环境
  • application-prod.properties:生产环境

6.3.2 激活配置

properties 复制代码
# 激活开发环境配置
spring.profiles.active=dev

6.4 配置属性绑定

6.4.1 使用@ConfigurationProperties

java 复制代码
@ConfigurationProperties(prefix = "app")
@Component
public class AppProperties {
    private String name;
    private String version;
    private List<String> features;
    
    // getters and setters
}

6.4.2 使用@Value

java 复制代码
@Component
public class MyComponent {
    
    @Value("${app.name}")
    private String appName;
    
    @Value("${app.version:1.0.0}")
    private String appVersion;
}

7. Actuator监控

7.1 启用Actuator

7.1.1 添加依赖

xml 复制代码
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

7.1.2 配置端点

properties 复制代码
# 启用所有端点
management.endpoints.web.exposure.include=*

# 配置端点路径
management.endpoints.web.base-path=/actuator

# 配置端点超时
management.endpoint.health.timeout=10s

7.2 内置端点

7.2.1 健康检查端点

  • /actuator/health:应用健康状态
  • /actuator/health/{component}:特定组件的健康状态

7.2.2 信息端点

  • /actuator/info:应用信息
  • /actuator/env:环境变量
  • /actuator/configprops:配置属性

7.2.3 运行时端点

  • /actuator/metrics:应用指标
  • /actuator/threaddump:线程转储
  • /actuator/heapdump:堆转储

7.3 自定义端点

7.3.1 创建自定义端点

java 复制代码
@Component
@Endpoint(id = "custom")
public class CustomEndpoint {
    
    @ReadOperation
    public Map<String, Object> custom() {
        Map<String, Object> result = new HashMap<>();
        result.put("timestamp", System.currentTimeMillis());
        result.put("message", "Hello from custom endpoint");
        return result;
    }
}

7.3.2 创建健康指示器

java 复制代码
@Component
public class CustomHealthIndicator implements HealthIndicator {
    
    @Override
    public Health health() {
        try {
            // 执行健康检查逻辑
            if (isHealthy()) {
                return Health.up()
                    .withDetail("message", "Service is healthy")
                    .build();
            } else {
                return Health.down()
                    .withDetail("message", "Service is unhealthy")
                    .build();
            }
        } catch (Exception e) {
            return Health.down()
                .withDetail("error", e.getMessage())
                .build();
        }
    }
    
    private boolean isHealthy() {
        // 实现健康检查逻辑
        return true;
    }
}

8. 最佳实践

8.1 项目结构

bash 复制代码
src/
├── main/
│   ├── java/
│   │   └── com/example/
│   │       ├── Application.java
│   │       ├── config/
│   │       ├── controller/
│   │       ├── service/
│   │       ├── repository/
│   │       └── model/
│   └── resources/
│       ├── application.properties
│       ├── application-dev.properties
│       ├── application-prod.properties
│       └── static/
└── test/
    └── java/
        └── com/example/

8.2 配置管理

8.2.1 使用配置类

java 复制代码
@Configuration
@ConfigurationProperties(prefix = "app")
@Data
public class AppConfig {
    private String name;
    private String version;
    private DatabaseConfig database;
    
    @Data
    public static class DatabaseConfig {
        private String url;
        private String username;
        private String password;
    }
}

8.2.2 条件配置

java 复制代码
@Configuration
@ConditionalOnProperty(name = "app.feature.enabled", havingValue = "true")
public class FeatureConfiguration {
    
    @Bean
    public FeatureService featureService() {
        return new FeatureService();
    }
}

8.3 异常处理

8.3.1 全局异常处理器

java 复制代码
@ControllerAdvice
public class GlobalExceptionHandler {
    
    @ExceptionHandler(Exception.class)
    public ResponseEntity<String> handleException(Exception e) {
        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
            .body("An error occurred: " + e.getMessage());
    }
    
    @ExceptionHandler(ResourceNotFoundException.class)
    public ResponseEntity<String> handleResourceNotFound(ResourceNotFoundException e) {
        return ResponseEntity.status(HttpStatus.NOT_FOUND)
            .body("Resource not found: " + e.getMessage());
    }
}

8.4 日志配置

8.4.1 logback-spring.xml

xml 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <springProfile name="dev">
        <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
            <encoder>
                <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
            </encoder>
        </appender>
        <root level="DEBUG">
            <appender-ref ref="CONSOLE"/>
        </root>
    </springProfile>
    
    <springProfile name="prod">
        <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
            <file>logs/application.log</file>
            <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
                <fileNamePattern>logs/application.%d{yyyy-MM-dd}.log</fileNamePattern>
                <maxHistory>30</maxHistory>
            </rollingPolicy>
            <encoder>
                <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
            </encoder>
        </appender>
        <root level="INFO">
            <appender-ref ref="FILE"/>
        </root>
    </springProfile>
</configuration>

8.5 性能优化

8.5.1 连接池配置

properties 复制代码
# HikariCP连接池配置
spring.datasource.hikari.maximum-pool-size=20
spring.datasource.hikari.minimum-idle=5
spring.datasource.hikari.connection-timeout=30000
spring.datasource.hikari.idle-timeout=600000
spring.datasource.hikari.max-lifetime=1800000

8.5.2 缓存配置

java 复制代码
@Configuration
@EnableCaching
public class CacheConfig {
    
    @Bean
    public CacheManager cacheManager() {
        SimpleCacheManager cacheManager = new SimpleCacheManager();
        cacheManager.setCaches(Arrays.asList(
            new ConcurrentMapCache("users"),
            new ConcurrentMapCache("products")
        ));
        return cacheManager;
    }
}

总结

Spring Boot通过以下核心机制实现了快速开发和部署:

  1. 自动配置:基于classpath和条件注解的智能配置
  2. 起步依赖:预配置的依赖组合,简化Maven配置
  3. 内嵌服务器:无需外部Web容器,直接运行
  4. 外部化配置:灵活的配置管理,支持多环境
  5. 监控管理:内置Actuator,提供生产就绪的监控能力

Spring Boot的设计哲学是"约定优于配置",它通过合理的默认配置和自动配置机制,让开发者能够专注于业务逻辑,而不是框架配置。同时,Spring Boot保持了Spring框架的所有优势,如依赖注入、AOP、事务管理等,是一个真正意义上的"Spring之上的Spring"。

相关推荐
uhakadotcom10 分钟前
如何安装和使用开源的Meilisearch
后端·面试·github
高松燈13 分钟前
自动拆箱 导致的空指针问题复盘
后端
IT_陈寒36 分钟前
Java性能优化实战:5个立竿见影的技巧让你的应用提速50%
前端·人工智能·后端
陈随易2 小时前
10年老前端,分享20+严选技术栈
前端·后端·程序员
汪子熙2 小时前
计算机世界里的 blob:从数据库 BLOB 到 Git、Web API 与云存储的二进制宇宙
后端
十八旬2 小时前
苍穹外卖项目实战(日记十)-记录实战教程及问题的解决方法-(day3-2)新增菜品功能完整版
java·开发语言·spring boot·mysql·idea·苍穹外卖
鞋尖的灰尘2 小时前
springboot-事务
java·后端
元元的飞2 小时前
6、Spring AI Alibaba MCP结合Nacos自动注册与发现
后端·ai编程
Cisyam2 小时前
Go环境搭建实战:告别Java环境配置的复杂
后端
六月的雨在掘金2 小时前
狼人杀法官版,EdgeOne 带你轻松上手狼人杀
前端·后端