赞
踩
什么是Spring Boot Starter呢?我们直接来看看官网是怎么介绍的吧。
Starters are a set of convenient dependency descriptors that you can include in your application. You get a one-stop shop for all the Spring and related technologies that you need without having to hunt through sample code and copy-paste loads of dependency descriptors. For example, if you want to get started using Spring and JPA for database access, include the spring-boot-starter-data-jpa dependency in your project.
我们以上述官网的例子来进行说明比如说我们需要在Spring 中适应JPA来操作数据库。在没有springBoot-starter之前,我们需要引入jpa的步骤
通过maven 引入 jdbc 的依赖、以及 jpa 相关的各种依赖
编写jpa相关的配置文件
网上各种查询找资料进行调试,调试的过程对于新手可能会有点奔溃会遇到各种奇奇怪怪的问题,jar包冲突啊,这个jar包下载不下来,缺少某个jar包。
终于在经历千辛万苦,哼次哼次的解决各种问题之后终于把项目跑起来了,然后把这次整合jpa遇到的问题,以及整合的步骤都一一的详细记录下来。方便下次在需要整合jpa的时候直接copy就好了。我们以前在没有starter之前是不是都是这么玩的。这样的缺点是不是也非常显著,比如过程复杂、需要不停的粘贴复制(不过这是程序员经常干的事情了,也不在乎多一两次了)、整合其它组件到自己的项目变的困难,效率低下。
我们可以看下SpringBoot 现在都为我们提供有哪些starter,这截图了部分starter,更多的请点击https://github.com/spring-projects/spring-boot/tree/master/spring-boot-project/spring-boot-starters
- starter的实现:
虽然我们每个组件的starter实现各有差异,但是它们基本上都会使用到两个相同的内容:ConfigurationProperties和AutoConfiguration
。- 因为SpringBoot提倡“「约定大于配置」”这一理念,所以
我们使用ConfigurationProperties来保存我们的配置,并且这些配置都可以有一个默认值,即在我们没有主动覆写原始配置的情况下,默认值就会生效。
- 除此之外,starter的ConfigurationProperties还
使得所有的配置属性被聚集到一个文件中(一般在resources目录下的application.properties),这样我们就告别了Spring项目中XML地狱
。starter的出现帮把我们把各种复杂的配置都封装起来了,让我们真正的可以达到了开箱即用。不仅降低了我们使用它的门槛,并且还大大提高了我们的开发效率。
Spring Boot也是有一个命名的建议的。所以名字是不能够随随便便取得,可以按照官方的建议来取
。What’s in a nameAll official starters follow a similar naming pattern; spring-boot-starter-*, where * is
a particular type of application. This naming structure is intended to help when you need to find a
starter. The Maven integration in many IDEs lets you search dependencies by name. For example, with the
appropriate Eclipse or STS plugin installed, you can press ctrl-space in the POM editor and type
“spring-boot-starter” for a complete list.As explained in the “Creating Your Own Starter” section, third
party starters should not start with spring-boot, as it is reserved for official Spring Boot artifacts.
Rather, a third-party starter typically starts with the name of the project. For example, a third-
party starter project called thirdpartyproject would typically be named thirdpartyproject-spring-boot-
starter.
大概意思是:
- 官方的 starter 的命名格式为 spring-boot-starter-{xxxx}比如spring-boot-starter-activemq
- 第三方我们自己的命名格式为{xxxx}-spring-boot-starter。比如mybatis-spring-boot-starter。
- 如果我们忽略这种约定,是不是会显得我们写的东西不够“专业“。
发短信我们需要配置一些账号信息,不同的短信供应商,账户信息是不一样的,所以我们需要定义一个XXXXProperties 来自动装配这些账户信息。下面我们就以腾讯云和阿里云两家供应商为例;
//配置前缀,区别各个组件的参数 @ConfigurationProperties(prefix = "sms") @Data public class SmsProperties { private SmsMessage aliyun = new SmsMessage(); private SmsMessage tencent = new SmsMessage(); @Data public static class SmsMessage{ /** * 用户名 */ private String userName; /** * 密码 */ private String passWord; /** * 秘钥 */ private String sign; /** * */ private String url; @Override public String toString() { return "SmsMessage{" + "userName='" + userName + '\'' + ", passWord='" + passWord + '\'' + ", sign='" + sign + '\'' + ", url='" + url + '\'' + '}'; } } }
@EnableConfigurationProperties(value = SmsProperties.class) @Configuration public class SmsAutoConfiguration { /** * 阿里云发送短信的实现类 * @param smsProperties * @return */ @Bean public AliyunSmsSenderImpl aliYunSmsSender(SmsProperties smsProperties){ return new AliyunSmsSenderImpl(smsProperties.getAliyun()); } /** * 腾讯云发送短信的实现类 * @param smsProperties * @return */ @Bean public TencentSmsSenderImpl tencentSmsSender(SmsProperties smsProperties){ return new TencentSmsSenderImpl(smsProperties.getTencent()); } }
@ConditionalOnMissingBean({SmsMessage.class})
public class AliyunSmsSenderImpl implements SmsSender{
private final SmsMessage smsMessage;
public AliyunSmsSenderImpl(SmsMessage smsProperties) {
this.smsMessage = smsProperties;
}
@Override
public boolean send(String message) {
System.out.println(smsMessage.toString()+"开始发送短信==》短信内容:"+message);
return true;
}
}
starter集成应用有两种方式(被动生效和主动生效
):
通过SpringBoot的SPI的机制来去加载我们的 starter
org.springframework.boot.autoconfigure.EnableAutoConfiguration
, value是我们的SmsAutoConfiguration 全限定名(「记得去除前后的空格,否则会不生效
」)。前提是先注销spring.factories
集成到我们的Spring Boot应用时需要主动声明启用该starter才生效,通过自定义一个@Enable注解然后在把自动配置类通过Import注解引入进来
。@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import({SmsAutoConfiguration.class})
public @interface EnableSms {
}
使用的时候需要在启动类上面开启这个注解即可。
至此,我们的自定义starter已经写好了,接下来就是打包生成starter.jar。下面是工程完整结构:
注意,不是传统的可运行jar项目,所以没有主入口
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.5.3</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.cristiano</groupId> <artifactId>sms-spring-boot-starter</artifactId> <version>0.0.1</version> <name>sms-spring-boot-starter</name> <description>sms-spring-boot-starter</description> <properties> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-configuration-processor</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <!--安装到仓库后,引用时不出现 BOOT-INF文件夹(会导致找不到相关类)--> <configuration> <skip>true</skip> </configuration> </plugin> </plugins> </build> </project>
重点注意:如果maven没有这么配置,那么打包成jar的时候,会出现BOOT-INF文件夹,导致使用模块的时候,找不到类,详细参考这篇文章
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<!--安装到仓库后,引用时不出现 BOOT-INF文件夹(会导致找不到相关类)-->
<configuration>
<skip>true</skip>
</configuration>
</plugin>
</plugins>
Lifecycle下install就可以将模块引用到本地仓库了
<dependency>
<groupId>com.cristiano</groupId>
<artifactId>sms-spring-boot-starter</artifactId>
<version>0.0.1</version>
</dependency>
@SpringBootApplication
@EnableSms
public class TeststarterApplication {public static void main(String[] args) {
SpringApplication.run(TeststarterApplication.class, args);
}
}
上面的例子加不加@EnableSms,都能正常打印信息
,因为我们在Starter的spring.factories中已经配置了自动配置类,属于被动加载。@EnableConfigurationProperties(value = SmsProperties.class) @Configuration public class SmsAutoConfiguration { /** * 阿里云发送短信的实现类 * @param smsProperties * @return */ @Bean //表示在EnableSms注解存在的情况下,该bean才会被注册 @ConditionalOnBean(annotation = EnableSms.class) public AliyunSmsSenderImpl aliYunSmsSender(SmsProperties smsProperties){ return new AliyunSmsSenderImpl(smsProperties.getAliyun()); } /** * 腾讯云发送短信的实现类 * @param smsProperties * @return */ @Bean public TencentSmsSenderImpl tencentSmsSender(SmsProperties smsProperties){ return new TencentSmsSenderImpl(smsProperties.getTencent()); } }
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import({SmsAutoConfiguration.class})
public @interface EnableSms {
}
//不使用@EnableSms
@SpringBootApplication
public class TeststarterApplication {public static void main(String[] args) {
SpringApplication.run(TeststarterApplication.class, args);
}
}
可以看到报错,原因是AliyunSmsSenderImpl
没有注册到bean中,所以使用条件注解可以实现starter的插拔式应用
正式使用
@EnableSms
@SpringBootApplication
public class TeststarterApplication {public static void main(String[] args) {
SpringApplication.run(TeststarterApplication.class, args);
}
}
//注入AliyunSmsSenderImpl
@Autowired
AliyunSmsSenderImpl aliyunSmsSender;
public void test(){
aliyunSmsSender.send("from aliyun");
}
配置
sms:
aliyun:
pass-word: aa
user-name: aa
url: www.aliyun.com
sign: alibaba
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。