SpringBoot3-10.核心原理-自定义 starter

2023年12月29日 15:30 · 阅读(198) ·

场景:抽取聊天机器人场景,它可以打招呼。
效果:任何项目导入此 starter 都具有打招呼功能,并且问候语中的人名需要可以在配置文件中修改

● 1. 创建自定义 starter 项目,引入 spring-boot-starter 基础依赖
● 2. 编写模块功能,引入模块所有需要的依赖。
● 3. 编写 xxxAutoConfiguration 自动配置类,帮其他项目导入这个模块需要的所有组件
● 4. 编写配置文件 META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports 指定启动需要加载的自动配置
● 5. 其他项目引入即可使用

新建项目-boot3-08-robot-starter

  • 新建模块 boot3-08-robot-starter

  • 创建模块

名称 boot3-08-robot-starter
位置 D:\Study-Java\2023\SpringBoot3-Study
语言 Java
构建系统 Maven
JDK 版本:17
供应商:Eclipse Temurin(AdoptOpenJDK HotSpot)17.0.8
位置:C:\Users\Administrator.jdks\temurin-17.0.8
主 ID com.atguigu
工件 ID boot3-08-robot-starter
软件包名称 com.atguigu.boot3.starter
  • SpringBoot 3.2.0
  • 依赖项目
  1. Developer Tools
  2. -- Lombok
  3. Web
  4. -- Spring Web

目录结构

  1. pom.xml
  2. ├─src
  3. ├─main
  4. ├─java
  5. └─com
  6. └─atguigu
  7. └─boot3
  8. └─starter
  9. ├─Controller
  10. RobotController.java
  11. └─robot
  12. EnableRobot.java
  13. RobotAutoConfiguration.java
  14. RobotProperties.java
  15. RobotService.java
  16. └─resources
  17. └─META-INF
  18. └─spring
  19. org.springframework.boot.autoconfigure.AutoConfiguration.imports

pom.xml

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  3. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
  4. <modelVersion>4.0.0</modelVersion>
  5. <parent>
  6. <groupId>org.springframework.boot</groupId>
  7. <artifactId>spring-boot-starter-parent</artifactId>
  8. <version>3.2.1</version>
  9. <relativePath/> <!-- lookup parent from repository -->
  10. </parent>
  11. <groupId>com.atguigu</groupId>
  12. <artifactId>boot3-08-robot-starter</artifactId>
  13. <version>0.0.1-SNAPSHOT</version>
  14. <name>boot3-08-robot-starter</name>
  15. <description>boot3-08-robot-starter</description>
  16. <properties>
  17. <java.version>17</java.version>
  18. </properties>
  19. <dependencies>
  20. <dependency>
  21. <groupId>org.springframework.boot</groupId>
  22. <artifactId>spring-boot-starter-web</artifactId>
  23. </dependency>
  24. <dependency>
  25. <groupId>org.projectlombok</groupId>
  26. <artifactId>lombok</artifactId>
  27. <optional>true</optional>
  28. </dependency>
  29. <!-- 导入配置处理器,配置文件自定义的 properties 配置都会有提示-->
  30. <dependency>
  31. <groupId>org.springframework.boot</groupId>
  32. <artifactId>spring-boot-configuration-processor</artifactId>
  33. <optional>true</optional>
  34. </dependency>
  35. <dependency>
  36. <groupId>org.springframework.boot</groupId>
  37. <artifactId>spring-boot-starter-test</artifactId>
  38. <scope>test</scope>
  39. </dependency>
  40. </dependencies>
  41. <build>
  42. <plugins>
  43. <plugin>
  44. <groupId>org.springframework.boot</groupId>
  45. <artifactId>spring-boot-maven-plugin</artifactId>
  46. </plugin>
  47. </plugins>
  48. </build>
  49. </project>

属性类-RobotProperties

  1. package com.atguigu.boot3.starter.robot;
  2. import lombok.Data;
  3. import org.springframework.boot.context.properties.ConfigurationProperties;
  4. import org.springframework.stereotype.Component;
  5. /**
  6. * 属性类
  7. */
  8. @Data
  9. @Component
  10. @ConfigurationProperties(prefix = "robot")
  11. public class RobotProperties {
  12. private String name;
  13. private String age;
  14. private String email;
  15. }

服务类-RobotService

  1. package com.atguigu.boot3.starter.robot;
  2. import jakarta.annotation.Resource;
  3. import org.springframework.stereotype.Service;
  4. @Service
  5. public class RobotService {
  6. @Resource
  7. RobotProperties robotProperties;
  8. public String sayHello() {
  9. return String.format("姓名:%s,年龄:%s,邮箱:%s, Hello!",
  10. robotProperties.getName(),robotProperties.getAge(),robotProperties.getEmail());
  11. }
  12. }

控制器-RobotController

  1. package com.atguigu.boot3.starter.Controller;
  2. import com.atguigu.boot3.starter.robot.RobotService;
  3. import jakarta.annotation.Resource;
  4. import org.springframework.web.bind.annotation.GetMapping;
  5. import org.springframework.web.bind.annotation.RestController;
  6. @RestController
  7. public class RobotController {
  8. @Resource
  9. RobotService robotService;
  10. @GetMapping("/robot/hello")
  11. public String sayHello() {
  12. return robotService.sayHello();
  13. }
  14. }

修改项目-boot3-06-features

项目结构

  1. ├─src
  2. ├─main
  3. ├─java
  4. └─com
  5. └─atguigu
  6. └─boot306
  7. └─features
  8. Application.java
  9. └─resources
  10. application.properties

pom.xml 引入 boot3-08-robot-starter

  1. <!--自定义 starter 项目-->
  2. <dependency>
  3. <groupId>com.atguigu</groupId>
  4. <artifactId>boot3-08-robot-starter</artifactId>
  5. <version>0.0.1-SNAPSHOT</version>
  6. </dependency>

修改配置文件-application.properties

  1. robot.name=鲁班一号
  2. robot.age=1
  3. robot.email=luban1@qq.com

第一种方式-使用 @Import 导入自定义 starter

  • 自己写一个 RobotAutoConfiguration,给容器中导入这个场景需要的所有组件
    • 为什么这些组件默认不会扫描进去?
    • starter所在的包和引入它的项目的主程序所在的包不是父子层级
  • 别人引用这个 starter,直接导入这个 RobotAutoConfiguration ,就能把这个场景的组件导入进来
  • 功能生效。

boot3-08-robot-starter 项目新增 RobotAutoConfiguration

  1. package com.atguigu.boot3.starter.robot;
  2. import com.atguigu.boot3.starter.Controller.RobotController;
  3. import org.springframework.context.annotation.Configuration;
  4. import org.springframework.context.annotation.Import;
  5. /**
  6. * 给容器中导入 Robot 功能要用的所有组件的配置类
  7. */
  8. @Configuration
  9. @Import({RobotProperties.class, RobotService.class, RobotController.class})
  10. public class RobotAutoConfiguration {
  11. }

boot3-06-features 项目主启动类添加 @Import 注解

  1. @Slf4j
  2. @SpringBootApplication //主程序类
  3. //使用导入方式——导入自定义 starter 所有组件
  4. @Import(RobotAutoConfiguration.class)
  5. public class Application

测试

  1. 姓名:鲁班一号,年龄:1,邮箱:luban1@qq.com, Hello

第二种方式-使用 @EnableXxx 机制导入自定义 starter

boot3-08-robot-starter 项目新增 EnableRobot

  1. package com.atguigu.boot3.starter.robot;
  2. import org.springframework.context.annotation.Import;
  3. import java.lang.annotation.*;
  4. /**
  5. * 导入 RobotAutoConfiguration 的注解
  6. */
  7. @Documented
  8. @Target({ElementType.TYPE})
  9. @Retention(RetentionPolicy.RUNTIME)
  10. @Import(RobotAutoConfiguration.class)
  11. public @interface EnableRobot {
  12. }

boot3-06-features 项目主启动类添加 @EnableRobot 注解

别人引入 starter需要使用 @EnableRobot 开启功能

  1. @Slf4j
  2. @SpringBootApplication //主程序类
  3. //使用导入方式——导入自定义 starter 所有组件
  4. //@Import(RobotAutoConfiguration.class)
  5. //使用@EnableXxx机制——导入自定义 starter 所有组件
  6. @EnableRobot
  7. public class Application

测试

  1. 姓名:鲁班一号,年龄:1,邮箱:luban1@qq.com, Hello

第三种方式-完全自动配置

● 依赖 SpringBootSPI 机制
META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports 文件中编写好我们自动配置类的全类名即可
● 项目启动,自动加载我们的自动配置类

boot3-08-robot-starter 项目新增资源目录配置

  • resources 下新增文件 META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
  1. com.atguigu.boot3.starter.robot.RobotAutoConfiguration

boot3-06-features 项目主启动类去掉所有相关注解

  1. @Slf4j
  2. @SpringBootApplication //主程序类
  3. //使用导入方式——导入自定义 starter 所有组件
  4. //@Import(RobotAutoConfiguration.class)
  5. //使用@EnableXxx机制——导入自定义 starter 所有组件
  6. //@EnableRobot
  7. public class Application

测试

  1. 姓名:鲁班一号,年龄:1,邮箱:luban1@qq.com, Hello