SpringBoot3基础特性+事件驱动开发+自定义starter

在这里插入图片描述

SpringBoot3基础特性


自定义banner

类路径添加banner.txt或设置spring.banner.location就可以定制banner

# 默认是classpath:banner.txt
spring.banner.location=classpath:banner.txt

# 关闭banner,默认是console,控制台输出
spring.main.banner-mode=off

自定义SpringApplication

方法一

@SpringBootApplication
public class DemoApplication {

    public static void main(String[] args) {
        // SpringBoot应用的核心API入口
        //SpringApplication.run(DemoApplication.class, args);

        //自定义SpringApplication的底层设置
        SpringApplication application = new SpringApplication(DemoApplication.class);
        // 设置banner在控制台输出
        // 注意:这里的配置不优先,如果配置文件里指定了,以配置文件为准,配置文件的优先级高于程序化调整的优先级
        application.setBannerMode(Banner.Mode.CONSOLE);
        // 启动
        application.run(args);
    }
}

方法二

@SpringBootApplication
public class DemoApplication {

    public static void main(String[] args) {
        // SpringBoot应用的核心API入口
        //SpringApplication.run(DemoApplication.class, args);

        // Builder方式构建SpringApplication
        new SpringApplicationBuilder()
                .main(DemoApplication.class)
                .sources(DemoApplication.class)
                .bannerMode(Banner.Mode.CONSOLE)
                .run(args);
    }
}

Profiles


环境隔离能力,快速切换开发、测试、生产环境

1.标识环境

任何@Component、@Configuration或@ConfigurationProperties可以使用@Profile标记,来指定何时被加载 (容器中的组件都可以被@Profile标记)

  • 区分环境:dev(开发环境)、test(测试环境)、prod(生产环境)、default(默认环境)
  • 使用@Profile指定每个组件在哪个环境下生效,如果组件没有使用@Profile,表示任意环境下都生效
  • 只有激活组件对应的环境,组件才生效

2.激活环境

  • 配置文件激活:spring.profiles.active=dev
  • 命令行激活:java -jar xxx.jar --spring.profiles.active=dev

3.配置文件使用Profile功能

  • 主配置文件application.properties,任何环境下都生效
  • 其他环境下命名规范:application-{环境标识}.properties
    如:application-dev.properties
  • 激活指定环境即可
    注意:spring.profiles.active和spring.profiles.default只在主配置文件中生效,其他环境配置文件中不生效
  • 生效配置项 = 激活环境配置文件所有配置项 + 主配置文件与激活环境配置文件不冲突的所有配置项 (如果发生冲突,以激活环境配置项为准)
# 激活环境
spring.profiles.active=prod

# 默认环境,默认是default
spring.profiles.default=default

# 包含指定环境,无论激活哪个环境,都有以下环境,总是要生效的环境
spring.profiles.include=dev,test
@Profile("dev")  //只有指定环境被激活,整个类的所有配置才生效
@Configuration
public class AppConfig {

    @Bean
    public User userBean() {
        return new User();
    }

    @Bean
    @ConditionalOnClass(name = "com.xust.demo.entity.User")
    public Cat catBean1() {
        return new Cat();
    }

    @Bean
    @ConditionalOnBean(value = User.class)
    public Cat catBean2() {
        return new Cat();
    }
}

生效环境 = 激活环境/默认环境 + 包含环境

1.基础的配置mybatis、log、… 写到包含环境中

2.需要动态切换的db、redis、… 写到激活环境中

外部化配置


SpringBoot使用配置优先级 + 外部配置,简化配置更新、简化运维。只需要给jar应用所在的文件夹放一个application.properties最新配置文件,重启项目就能自动应用最新配置

配置优先级

1.配置优先级:命令行 > 配置文件 > SpringApplication配置

2.配置文件优先级:jar包外的配置文件 > jar包内的配置文件

3.如果application.properties和application.yml同时存在,则application.properties优先

属性占位符

配置文件中可以使用 ${name:default}形式取出之前配置过的值

server.port=8080
myPort=${server.port}
@RestController
public class UserController {

    @Value("${myPort:9999}")  //如果配置文件中没有myPort,默认值9999
    String myPort;

    @GetMapping("/getPort")
    public String getPort() {
        return "我的端口是"+ myPort;
    }
}

单元测试


@Test:表示方法是测试方法
@RepeatedTest:表示方法可重复执行
@DisplayName:为测试类或者测试方法设置展示名称
@BeforeEach:表示在每个单元测试之前执行
@AfterEach:表示在每个单元测试之后执行
@BeforeAll:表示在所有单元测试之前执行
@AfterAll:表示在所有单元测试之后执行

@SpringBootTest  //具备测试SpringBoot应用容器中所有组件的功能
class DemoApplicationTests {

    @Autowired
    UserService userService;

    @DisplayName("测试求和")
    @Test
    void test01() {
        Integer sum = userService.sum(1, 2);
        Assertions.assertEquals(3, sum);
    }

    @DisplayName("测试打印")
    @Test
    void test02() {
        System.out.println("Hello World");
    }

    @BeforeAll  //所有测试方法运行之前先运行这个方法,只执行一次
    static void test03() {
        System.out.println("BeforeAll");
    }

    @BeforeEach  //每个测试方法运行之前先运行这个方法,每个方法运行都执行一次
    void test04() {
        System.out.println("BeforeEach");
    }
}

事件驱动开发


controller / LoginController.java

@RestController
public class LoginController {

    @Autowired
    EventPublisher eventPublisher;

    @GetMapping("/login")
    public String login(@RequestParam("username") String username,
                        @RequestParam("password") String password) {

        System.out.println("=====登录业务逻辑开始=====");

        //todo 发送事件
        //1.创建事件
        LoginSuccessEvent event = new LoginSuccessEvent(new User(username, password));
        //2.发送事件
        eventPublisher.sendEvent(event);
        return username + "登录成功...";
    }
}

event / EventPublisher.java

@Service
public class EventPublisher implements ApplicationEventPublisherAware {

    //底层发送事件的组件,通过ApplicationEventPublisherAware接口自动注入
    ApplicationEventPublisher applicationEventPublisher;

    /**
     * 所有事件都可以发送
     */
    public void sendEvent(ApplicationEvent event) {
        applicationEventPublisher.publishEvent(event);
    }

    /**
     * 会被自动调用,把真正发事件的底层组件注入进来
     */
    @Override
    public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
        this.applicationEventPublisher = applicationEventPublisher;
    }
}

event / LoginSuccessEvent.java

/**
 * 登录成功事件,所有事件都推荐继承ApplicationEvent
 */
public class LoginSuccessEvent extends ApplicationEvent {

    public LoginSuccessEvent(User source) {
        super(source);
    }
}

service / AccountService.java

方法一:实现ApplicationListener接口

@Order(2)
@Service
public class AccountService implements ApplicationListener<LoginSuccessEvent> {

    public void addAccountScore(String username) {
        System.out.println(username + "加1积分");
    }

    @Override
    public void onApplicationEvent(LoginSuccessEvent event) {
        System.out.println("=====AccountService收到事件=====");
        User source = (User) event.getSource();
        addAccountScore(source.getUsername());
    }
}

service / CouponService.java

方法二:使用@EventListener注解

@Service
public class CouponService {

    @Order(1) // 指定触发顺序,值越小,优先级越高
    @EventListener
    public void onEvent(LoginSuccessEvent loginSuccessEvent) {
        System.out.println("=====CouponService收到事件=====");
        User source = (User) loginSuccessEvent.getSource();
        sendCoupon(source.getUsername());
    }

    public void sendCoupon(String username) {
        System.out.println(username + "获取到一张优惠卷");
    }
}

功能开关


1.使用@EnableXXX手动控制开启哪些功能

2.@EnableXXX都是利用@Import导入此功能需要的组件

@SpringBootApplication注解


1.@SpringBootApplication由三个注解组成@SpringBootConfiguration、@EnableAutoConfiguration、@ComponentScan

2.@SpringBootConfiguration就是一个@Configuration,代表这是一个配置类,也是容器中的组件

3.@EnableAutoConfiguration开启自动配置,它由@AutoConfigurationPackage和@Import({AutoConfigurationImportSelector.class})组成。@AutoConfigurationPackage利用@Import({AutoConfigurationPackages.Registrar.class})批量导入主程序所在包的所有组件,加载自己的组件。@Import({AutoConfigurationImportSelector.class})加载所有的自动配置类,加载starter导入的组件

4.@ComponentScan组件扫描,排除前面已经扫描进来的配置类

自定义starter


1.创建自定义starter项目,引入spring-boot-starter基础依赖

2.编写模块功能,引入模块所有需要的依赖

3.编写xxxAutoConfiguration自动配置类,帮其他项目导入这个模块需要的所有组件

4.编写配置文件META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports指定启动需要加载的自动配置

5.其他项目引入自定义starter即可使用

controller / RobotController.java

@RestController
public class RobotController {

    @Autowired
    RobotService robotService;

    @GetMapping("/robot")
    public String sayHello() {
        return robotService.sayHello();
    }
}

service / RobotService.java

@Service
public class RobotService {

    @Autowired
    RobotProperties robotProperties;

    public String sayHello() {
        return "Hello " + robotProperties.getName();
    }
}

properties / RobotProperties.java

@Component
@ConfigurationProperties(prefix = "robot")
@Data
public class RobotProperties {

    private String name;
    private Integer age;
}

RobotAutoConfiguration.java

@Configuration
//使用@Import给容器中导入需要的组件
@Import({RobotController.class, RobotProperties.class, RobotService.class})
public class RobotAutoConfiguration {
}

annotation / EnableRobot.java

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
@Documented
@Import({RobotAutoConfiguration.class})
public @interface EnableRobot {
}

resources / META-INF / spring / org.springframework.boot.autoconfigure.AutoConfiguration.imports

com.xust.robotstarter.robot.RobotAutoConfiguration

总结


以上主要介绍了SpringBoot3基础特性、事件驱动开发、自定义starter相关知识。想学习SpringBoot3更多实战实用技巧的小伙伴,请关注往期发布的文章,认真看完一定能让你有所收获。

  • 28
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
自定义 Spring Boot Starter 连接数据库的步骤如下: 1. 添加数据库依赖:在你的自定义 Starter 的 `pom.xml` 文件中,添加适当的数据库依赖,例如 MySQL、PostgreSQL 或者 H2 数据库依赖。可以使用 Spring Boot 提供的自动配置模块,如 `spring-boot-starter-data-jpa` 或 `spring-boot-starter-jdbc`,或者根据需要选择其他数据库驱动依赖。 2. 创建数据库配置类:在你的自定义 Starter 中创建一个数据库配置类,用于配置数据库连接信息。可以使用 Spring Boot 提供的 `application.properties` 或 `application.yml` 文件进行配置,或者创建一个自定义的配置类。 3. 配置数据库连接信息:在数据库配置类中,通过使用 Spring Boot 提供的 `@ConfigurationProperties` 注解,将数据库连接信息映射到对应的属性上。例如,你可以创建一个 `DatabaseProperties` 类,并使用 `@ConfigurationProperties(prefix = "database")` 注解将配置属性映射到该类上。 4. 创建数据源:在数据库配置类中,使用配置信息创建数据源。可以使用 Spring Boot 提供的 `DataSourceBuilder` 类来创建数据源对象,并将其注入到 Spring 容器中。例如,可以使用以下代码创建一个基于 HikariCP 的数据源: ```java @Configuration public class DatabaseConfiguration { @Bean @ConfigurationProperties(prefix = "database") public DataSource dataSource() { return DataSourceBuilder.create().build(); } } ``` 5. 配置 JdbcTemplate 或者 JPA:根据你的需求,可以选择使用 Spring Boot 提供的 JdbcTemplate 或者 JPA 进行数据库操作。如果你选择使用 JdbcTemplate,可以在数据库配置类中创建一个 `JdbcTemplate` Bean,并将数据源注入到该 Bean 中。如果你选择使用 JPA,可以在数据库配置类中创建一个 `EntityManagerFactory` Bean,并将数据源和其他适当的 JPA 配置注入到该 Bean 中。 6. 在自定义 Starter 中使用数据库:通过将数据库相关的依赖添加到你的自定义 Starter 中,其他开发人员在使用该 Starter 时可以直接使用数据库相关的功能。 以上是连接数据库的一般步骤,具体实现可能会根据你的需求和选择的数据库框架有所不同。请根据你的具体情况进行相应的配置和实现。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值