SpringBoot中的starter是一种非常重要的机制(自动化配置),能够抛弃以前繁杂的配置,将其统一集成进starter,应用者只需要在maven中引入starter依赖,SpringBoot就能自动扫描到要加载的信息并启动相应的默认配置。starter让我们摆脱了各种依赖库的处理,需要配置各种信息的困扰。
SpringBoot会自动通过classpath路径下的类发现需要的Bean,并注册进IOC容器。SpringBoot提供了针对日常企业应用研发各种场景的spring-boot-starter依赖模块。
所有这些依赖模块都遵循着约定成俗的默认配置,并允许我们调整这些配置,即遵循“约定大于配置”的理念。
我们的日常开发工作中,可能会需要开发一个通用模块,以供其它工程复用。SpringBoot就为我们提供这样的功能机制,我们可以把我们的通用模块封装成一个个starter,这样其它工程复用的时候只需要在pom中引用依赖即可,由SpringBoot为我们完成自动装配。
常见应用场景:
SpringBoot的自动加载核心注解是@SpringBootApplication。这个注解是Spring Boot最核心的注解,用于标识这是一个Spring Boot应用,并开启Spring Boot的各项能力。
实际上,@SpringBootApplication注解主要组合了以下几个核心注解:
starter项目和SpringBoot工程结构没有什么区别。必须引入的依赖:
org.springframework.boot spring-boot-configuration-processortrue
spring-boot-configuration-processor 是一个注解处理器,用于处理 Spring Boot 配置类的注解,并生成配置属性的元数据。它在开发过程中起到以下几个重要的作用:
生成配置属性的元数据: 当你使用 @ConfigurationProperties 注解来声明配置类时,spring-boot-configuration-processor 会解析该注解,并生成与配置属性相关的元数据。这些元数据包括属性的名称、类型、描述、默认值等信息。这些信息可以帮助 IDE 在开发过程中提供代码提示、自动补全和验证功能。
提供配置属性的编译时验证: 使用 @ConfigurationProperties 注解时,你可以使用其他注解(如 @Value、@Valid 等)来描述配置属性的约束条件。spring-boot-configuration-processor 可以处理这些注解,并在编译时进行验证。这样,你可以在开发阶段及早发现配置属性的错误或不一致,而不是在运行时才遇到问题。
简化配置类的编写: 通过使用 spring-boot-configuration-processor,你可以更轻松地编写配置类。它会自动处理 @ConfigurationProperties 注解及其相关注解,生成属性的 getter、setter 方法,并提供默认的配置文件映射规则。这样,你可以专注于定义配置属性的结构和业务逻辑,而不需要手动编写重复的代码。
提升开发体验: spring-boot-configuration-processor 增强了开发工具的功能,例如在 IDE 中提供配置属性的智能提示、文档、类型检查等功能。这可以减少开发过程中的错误,并提高代码的可读性和可维护性。
spring-boot-configuration-processor 可以简化 Spring Boot 配置类的开发,提供编译时验证和开发工具的支持,从而改善开发体验并减少潜在的配置错误。它是 Spring Boot 框架中重要的辅助工具,帮助开发者更高效地处理配置属性。
SpringBoot官方命名方式:
spring-boot-starter-{模块名}例如:spring-boot-starter-web
提供accessKeyId和accessKeySecret属性的getter、setter方法。
package com.zl.smsspringbootstart; import lombok.Data; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Component; import org.springframework.stereotype.Controller; @Data //@Component //@ConfigurationProperties 会自动去yml文件中找到需要的配置将它放到对应的属性中 @ConfigurationProperties(prefix = "sms") public class SmsProperties { /** * 应用标识 */ // @Value("${sms.key}") private String key; /** * 应用密钥 */ // @Value("${sms.secret}") private String secret; /** * 关闭 */ private String enable; }
service
package com.zl.smsspringbootstart.service; public interface ISmsService { /** * 发送短信 * * @param phone 要发送的手机号 * @param data 要发送的内容 */ void send(String phone, String data); }
接口实现impl
package com.zl.smsspringbootstart.service.impl; import com.zl.smsspringbootstart.SmsProperties; import com.zl.smsspringbootstart.service.ISmsService; public class SmsServiceImpl implements ISmsService { private SmsProperties smsProperties; //null public SmsServiceImpl(SmsProperties smsProperties) { this.smsProperties = smsProperties; } @Override public void send(String phone, String data) { String key = smsProperties.getKey(); String secret = smsProperties.getSecret(); System.out.println("接入短信系统,Key=" + key + ",Secret=" + secret); System.out.println("短信发送,phone=" + phone + ",data=" + data); } }
@EnableConfigurationProperties注解的作用是@ConfigurationProperties注解生效。
如果只配置@ConfigurationProperties注解,在IOC容器中是获取不到properties配置文件转化的bean的。
package com.zl.smsspringbootstart; import com.zl.smsspringbootstart.service.ISmsService; import com.zl.smsspringbootstart.service.impl.SmsServiceImpl; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration //开启配置加载 @EnableConfigurationProperties({SmsProperties.class}) //添加一个条件 sms.enable @ConditionalOnProperty(prefix = "sms", name = "enable", havingValue = "true") public class SmsConfig { //控制当前的service是否加载到spring里面去 @Autowired private SmsProperties smsProperties; //@Bean 方法会在spring运行的时候自动执行,返回值会被放到spring容器中 @Bean public ISmsService smsService() { return new SmsServiceImpl(smsProperties); } }
在resources下新建META-INF文件夹,然后创建spring.factories文件。在该文件中加入如下配置,该配置指定上步骤中定义的配置类为自动装配的配置:
org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.zl.smsspringbootstart.SmsConfig其中AutoConfig是starter配置文件的类限定名,多个之间逗号分割,还可以\进行转义即相当于去掉后面换行和空格符号。
com.zl sms-spring-boot-start0.0.1-SNAPSHOT
配置application.yml文件
enable如果为false则不使用
# 配置 sms: key: 11115 secret: 100006 enable: true
创建Junit测试
package com.example.springboot01; import com.zl.smsspringbootstart.service.ISmsService; import com.zl.weblog.WebLogProperties; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; @SpringBootTest class Springboot01ApplicationTests { // 使用短信功能 @Autowired private ISmsService iSmsService; @Test void contextLoads() { iSmsService.send("137", "123456"); } }
测试结果
enabled属性用于控制是否开关日志,请提供enabled属性的getter、setter方法。
package com.zl.weblog; import org.springframework.boot.context.properties.ConfigurationProperties; // 添加@ConfigurationProperties注解,将配置文件中的属性映射到WebLogProperties类中 @ConfigurationProperties(prefix = "spcloud.weblog") public class WebLogProperties { // 定义一个boolean类型的变量 private boolean enabled; // 构造函数 public WebLogProperties() { } // 获取enabled属性 public boolean isEnabled() { return enabled; } // 设置enabled属性 public void setEnabled(boolean enabled) { this.enabled = enabled; } }
package com.zl.weblog; import lombok.extern.slf4j.Slf4j; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.annotation.AfterReturning; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.aspectj.lang.annotation.Pointcut; import org.springframework.stereotype.Component; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; import javax.servlet.http.HttpServletRequest; import java.util.Arrays; @Aspect @Component @Slf4j public class WebLogAspect { //@Pointcut("execution(public * com.zl..controller.*.*(..))") // 定义一个切入点,拦截com.zl..controller.*.*(..)方法 @Pointcut("execution(* *..*Controller.*(..))") public void webLog() { } @Before("webLog()") // 在执行方法之前执行 public void doBefore(JoinPoint joinPoint) throws Throwable { // 接收到请求,记录请求内容 ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); HttpServletRequest request = attributes.getRequest(); // 记录下请求内容 log.info("开始服务:{}", request.getRequestURL().toString()); log.info("客户端IP :{}", request.getRemoteAddr()); log.info("参数值 :{}", Arrays.toString(joinPoint.getArgs())); } @AfterReturning(returning = "ret", pointcut = "webLog()") // 在执行方法之后执行 public void doAfterReturning(Object ret) throws Throwable { // 处理完请求,返回内容 log.info("返回值 : {}", ret); } }
package com.zl.weblog; //import com.zl.spcloudspringbootstarter.properties.WebLogProperties; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; /** * @ConditionalOnProperty 配置属性a: * 1:不配置a matchifmissing=false 不满足 matchifmissing=true 满足 * 2:配置a=false matchifmissing=false 不满足 matchifmissing=true 不满足 * 3:配置a=true matchifmissing=false 满足 matchifmissing=true 满足 */ @Configuration @EnableConfigurationProperties({WebLogProperties.class}) @ConditionalOnProperty(prefix = "spcloud.weblog", value="enabled",matchIfMissing = true) public class WebLogConfig { @Bean @ConditionalOnMissingBean public WebLogAspect webLogAspect() { return new WebLogAspect(); } }
在resources下新建META-INF文件夹,然后创建spring.factories文件。在该文件中加入如下配置,该配置指定上步骤中定义的配置类为自动装配的配置:
org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.zl.weblog.WebLogConfig其中AutoConfig是starter配置文件的类限定名,多个之间逗号分割,还可以\进行转义即相当于去掉后面换行和空格符号。
com.zl WebLog0.0.1-SNAPSHOT
配置application.yml文件
enable如果为false则不使用
# 配置 spcloud: weblog: enabled: true
创建Controller层测试
在这里可以使用自己的Controller层测试
package com.example.springboot01.controller; import com.example.springboot01.entity.TBook; import com.example.springboot01.page.PageBean; import com.example.springboot01.service.TBookService; import com.github.pagehelper.PageHelper; import org.aspectj.lang.annotation.Aspect; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; import java.util.List; @RestController @RequestMapping("/book") public class TBookController { @Autowired private TBookService tBookService; @RequestMapping("/list") public Object list2(PageBean pageBean) { ListtBooks = tBookService.selectAll(pageBean); return tBooks; } }
测试结果
分享就到这里!欢迎搭建在评论区进行讨论!