?? 漫畫SpringBoot實戰
?? 學習目標:掌握SpringBoot企業級開發,從零到一構建現代化Java應用
?? 目錄
- SpringBoot核心特性
- 自動配置原理
- Web開發實戰
- 數據訪問與事務
- 監控與部署
?? 漫畫引言
小明: “為什么SpringBoot這么受歡迎?”
架構師老王: “SpringBoot就像全自動洗衣機,你只需要放入衣服,它自動配置一切!”
? SpringBoot核心特性
?? 漫畫場景:SpringBoot魔法師
傳統Spring配置 ?? SpringBoot魔法 ??┌─────────────────┐ ┌─────────────────┐│ web.xml │ │ @SpringBootApp ││ applicationContext │ → │ main方法啟動 ││ 大量XML配置 │ │ 零配置文件 ││ 服務器部署 │ │ 內嵌服務器 │└─────────────────┘ └─────────────────┘繁瑣配置 開箱即用
??? SpringBoot項目腳手架
/*** SpringBoot主啟動類*/
@SpringBootApplication
@EnableScheduling
@EnableAsync
public class SpringBootDemoApplication {public static void main(String[] args) {// SpringBoot應用啟動SpringApplication app = new SpringApplication(SpringBootDemoApplication.class);// 自定義啟動配置app.setBannerMode(Banner.Mode.CONSOLE);app.setAdditionalProfiles("dev");ConfigurableApplicationContext context = app.run(args);// 打印應用信息Environment env = context.getEnvironment();String port = env.getProperty("server.port", "8080");String contextPath = env.getProperty("server.servlet.context-path", "");System.out.println("\n?? SpringBoot應用啟動成功!");System.out.println("?? 訪問地址: http://localhost:" + port + contextPath);System.out.println("?? 接口文檔: http://localhost:" + port + contextPath + "/swagger-ui.html");System.out.println("?? SpringBoot讓開發如此簡單!\n");}// 自定義Banner@Beanpublic Banner customBanner() {return (environment, sourceClass, out) -> {out.println(" ____ _ ____ _ ");out.println("/ ___| _ __ _ __(_)_ __ __ _ | __ ) ___ ___ | |_ ");out.println("\\___ \\| '_ \\| '__| | '_ \\ / _` || _ \\ / _ \\ / _ \\| __|");out.println(" ___) | |_) | | | | | | | (_| || |_) | (_) | (_) | |_ ");out.println("|____/| .__/|_| |_|_| |_|\\__, ||____/ \\___/ \\___/ \\__|");out.println(" |_| |___/ ");};}
}
?? Starter依賴管理
<!-- pom.xml SpringBoot父工程 -->
<parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.7.0</version><relativePath/>
</parent><dependencies><!-- Web開發 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- 數據訪問 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-jpa</artifactId></dependency><!-- Redis緩存 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency><!-- 安全框架 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-security</artifactId></dependency><!-- 監控端點 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId></dependency><!-- 測試框架 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency>
</dependencies>
?? 自動配置原理
?? 自動配置機制深度解析
/*** 自動配置原理示例*/
@Configuration
@ConditionalOnClass(DataSource.class)
@ConditionalOnMissingBean(DataSource.class)
@EnableConfigurationProperties(DataSourceProperties.class)
public class CustomDataSourceAutoConfiguration {@Bean@Primarypublic DataSource dataSource(DataSourceProperties properties) {System.out.println("?? 自動配置數據源...");HikariDataSource dataSource = new HikariDataSource();dataSource.setJdbcUrl(properties.getUrl());dataSource.setUsername(properties.getUsername());dataSource.setPassword(properties.getPassword());dataSource.setDriverClassName(properties.getDriverClassName());// HikariCP連接池優化配置dataSource.setMaximumPoolSize(20);dataSource.setMinimumIdle(5);dataSource.setConnectionTimeout(30000);dataSource.setIdleTimeout(600000);dataSource.setMaxLifetime(1800000);System.out.println("? 數據源配置完成: " + properties.getUrl());return dataSource;}
}/*** 條件裝配示例*/
@Component
@ConditionalOnProperty(name = "app.feature.enabled", havingValue = "true")
public class FeatureService {@PostConstructpublic void init() {System.out.println("?? 特性服務已啟用!");}public void doSomething() {System.out.println("執行特殊功能...");}
}/*** 自定義Starter*/
@Configuration
@EnableConfigurationProperties(MyStarterProperties.class)
public class MyStarterAutoConfiguration {private final MyStarterProperties properties;public MyStarterAutoConfiguration(MyStarterProperties properties) {this.properties = properties;}@Bean@ConditionalOnMissingBeanpublic MyService myService() {return new MyService(properties.getName(), properties.getTimeout());}@ConfigurationProperties(prefix = "mystarter")@Datapublic static class MyStarterProperties {private String name = "default";private int timeout = 5000;}public static class MyService {private String name;private int timeout;public MyService(String name, int timeout) {this.name = name;this.timeout = timeout;System.out.println("?? MyService初始化: " + name + ", timeout=" + timeout);}}
}
?? Web開發實戰
?? RESTful API開發
/*** 用戶管理Controller*/
@RestController
@RequestMapping("/api/users")
@Validated
@Slf4j
public class UserController {@Autowiredprivate UserService userService;/*** 獲取用戶列表*/@GetMappingpublic ResponseEntity<PageResult<UserVO>> getUsers(@RequestParam(defaultValue = "1") int page,@RequestParam(defaultValue = "10") int size,@RequestParam(required = false) String keyword) {log.info("獲取用戶列表: page={}, size={}, keyword={}", page, size, keyword);PageResult<UserVO> result = userService.getUsers(page, size, keyword);return ResponseEntity.ok(result);}/*** 獲取用戶詳情*/@GetMapping("/{userId}")public ResponseEntity<