🎉🎉欢迎来到我的CSDN主页!🎉🎉
🏅我是Java方文山,一个在CSDN分享笔记的博主。📚📚
🌟推荐给大家我的专栏《SpringBoot》。🎯🎯
👉点击这里,就可以查看我的主页啦!👇👇
Java方文山的个人主页
🎁如果感觉还不错的话请给我点赞吧!🎁🎁
💖期待你的加入,一起学习,一起进步!💖💖
SpringBoot中的starter是一种非常重要的机制(自动化配置),能够抛弃以前繁杂的配置,将其统一集成进starter,应用者只需要在maven中引入starter依赖,SpringBoot就能自动扫描到要加载的信息并启动相应的默认配置。starter让我们摆脱了各种依赖库的处理,需要配置各种信息的困扰。
SpringBoot会自动通过classpath路径下的类发现需要的Bean,并注册进IOC容器。SpringBoot提供了针对日常企业应用研发各种场景的spring-boot-starter依赖模块。
所有这些依赖模块都遵循着约定成俗的默认配置,并允许我们调整这些配置,即遵循“约定大于配置”的理念。
在我们的日常开发工作中,经常会有一些独立于业务之外的配置模块,我们经常将其放到一个特定的包下,然后如果另一个工程需要复用这块功能的时候,需要将代码硬拷贝到另一个工程,重新集成一遍,麻烦至极。如果我们将这些可独立于业务代码之外的功能配置模块封装成一个个starter,复用的时候只需要将其在pom中引用依赖即可, SpringBoot为我们完成自动装配,简直不要太爽。
在我们的日常开发工作中,可能会需要开发一个通用模块,以供其它工程复用。SpringBoot就为我们提供这样的功能机制,我们可以把我们的通用模块封装成一个个starter,这样其它工程复用的时候只需要在pom中引用依赖即可,由SpringBoot为我们完成自动装配。
常见应用场景如下:
1)通用模块-短信发送模块
2)基于AOP技术实现日志切面
3)分布式雪花ID,Long转String,解决精度问题
4)微服务项目的数据库连接池配置
5)微服务项目的每个模块都要访问redis数据库,每个模块都要配置redisTemplate
下面我用案例的方式教会大家如何使用starter启动器。
首先我们搭建一个SpringBoot项目,需要注意的是以下图片内容,有关后期导入依赖
导入一个注解处理器,用于处理 Spring Boot 配置类的注解,并生成配置属性的元数据。
org.springframework.boot spring-boot-configuration-processortrue
开发过程中起到以下几个重要的作用:
在这之前需要知道以下我们启动器与springboot官方提供的依赖有什么关系
SpringBoot官方命名方式:
spring-boot-starter-{模块名}例如:spring-boot-starter-web
自定义命名方式:
{模块名}-spring-boot-starter例如:mystarter-spring-boot-starter
/** * 短信服务配置类 */ @Data @ConfigurationProperties(prefix = "sms") public class SmsProperties { private String key;//访问ID、即帐号 private String secret;//访问凭证,即密钥 private String enabled;//用于操作是否启用该模块 }
提供该配置类的set\get方法并且将配置文件中以sms为前缀的属性值绑定到该类对应的属性上。
ISmsService代码
public interface ISmsService { /** * 发送短信 * * @param phone 要发送的手机号 * @param data 要发送的内容 */ void send(String phone, String data); }
SmsServiceImpl代码
public class SmsServiceImpl implements ISmsService { private SmsProperties smsProperties ; 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); } }
@Configuration @EnableConfigurationProperties({SmsProperties.class}) @ConditionalOnProperty(prefix = "sms",name = "enable",havingValue = "true") public class SmsConfig { @Autowired private SmsProperties smsProperties; //通过@Bean注解将其注入到Spring上下文中 @Bean public ISmsService smsService(){ //调用SMS短信服务接口时,必须通过账号和密码的方式进行调用。 return new SmsServiceImpl(smsProperties); } }
该类的作用是将这个类交与spring管理的同时也把SmsProperties这个类交给spring管理,并且将这个配置类放入spring容器让其他类可以获取到,这里还有个条件就是如果我sms.enable的值不为true,那么就都不会加入到spring中。
注释小课堂:
@Configuration注解:用于定义该类是一个配置类,相当于传统Spring XML配置文件中的
标签,表示其中包含有一个或多个@Bean注解的方法,用于构建bean对象并放入Spring容器中管理。 @EnableConfigurationProperties({SmsProperties.class})注解:用于启用指定类型的配置属性(Configuration Properties)。在这里,它启用了SmsProperties类作为配置属性类,使得可以在SmsConfig类中通过@Autowired注解自动注入SmsProperties对象。
@Bean注解:用于定义一个bean,并将其注入到Spring上下文中。在这个例子中,smsService方法返回的SmsServiceImpl对象会被纳入到Spring容器的管理范围内。
@ConditionalOnProperty(prefix = "sms", name = "enable", havingValue = "true")注解的作用是根据配置文件中的属性值来条件性地加载或禁用Bean。
具体而言,它基于以下三个条件进行判断:
prefix:指定属性的前缀,即在配置文件中以什么前缀开始的属性。
name:指定属性的名称,即需要判断的属性的具体名称。
havingValue:指定属性的期望值,当该属性的值与havingValue指定的值相等时,才满足条件。
我们在application.properties配置一下SmsProperties
sms: sms.key=j7fj8eoji92d sms.secret=8u8u8u
在测试类调用一下SmsServiceImpl的send方法
@SpringBootTest class SmsApplicationTests { @Autowired private SmsProperties smsProperties ; @Test void contextLoads() { new SmsServiceImpl(smsProperties).send("110", "爱你"); } }
控制台输出结果
因为我们的自动装配类,启动的spring就会将本身以及配置类注入到spring中,而配置类又与配置文件也就是application.properties做了匹配,只要配置文件中填了sms.key和sms.secret就会将填写的内容注入到配置类中。
①首先需要编写spring.factories文件加载自动配置类
在resources下新建META-INF文件夹,然后创建spring.factories文件;
org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.csdn.sms.Properties.SmsConfig
②打包安装
直接install即可
在本地仓库就会有你刚刚所打包的依赖
注意:打包的时候请注释application.properties,否则这里的配置就定死了,不会随着我们调用者的配置而改动!!!
③引用并测试
引入依赖
com.csdn sms0.0.1-SNAPSHOT
配置application.yml
如果enable不为true,那么就不会注入javabean就会报错
测试模块功能
@SpringBootTest class BootApplicationTests { @Autowired private SmsProperties smsProperties; @Test void contextLoads() { new SmsServiceImpl(smsProperties).send("15574117565","其他模块"); } }
看到这里我们的starter的短信模块就完成了
我现有一个基于AOP的Log日志功能,这个切面定义了一个切入点webLog(),它匹配所有以Controller结尾的类的所有方法。在这些方法执行之前和之后,分别执行了doBefore()和doAfterReturning()方法,这两个方法中包含了对请求信息的记录和处理。
@Component @Slf4j @Aspect public class WebLogAspect { @Pointcut("execution(public * com.zking..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); } }
我现在要用刚刚的短信发送模块中的方式,通过yml配置enable的属性来控制是否开启日志模块
2.1.创建配置类Properties
@Data @ConfigurationProperties(prefix = "weblog") public class WebLogProperties { private String enable;//控制是否开启切面 }
@Configuration @EnableConfigurationProperties({WebLogProperties.class}) @ConditionalOnProperty(prefix = "weblog", value="enable",havingValue = "true") public class WebLogAutoConfig { @Bean @ConditionalOnMissingBean public WebLogAspect webLogAspect(){ return new WebLogAspect(); } }
或者直接在切面类上加上注解
@ConditionalOnProperty(prefix = "weblog", value="enable",havingValue = "true")
当我们配置weblog.enable等于true的时候才会开启Log日志管理,下面演示一下
到这里我的分享就结束了,欢迎到评论区探讨交流!!
💖如果觉得有用的话还请点个赞吧 💖