SpringBoot起飞系列-自定义starter(十)
一、前言
到现在,我们可以看出来,如果我们想用一些功能,基本上都是通过添加spring-boot-starter的方式来使用的,因为各种各样的功能都被封装成了starter,然后把相关服务注入到容器中去,那么如果我们想用一下自己的某些功能呢,那就也要编写一个自定义的starter,所以今天我们就来看看,怎么编写自己的starter,来实现在springboot中实现自己想要的一些功能。
二、原理
回想一下, 当我们使用一个官方的starter的时候,只需要将相应的starter依赖包添加到pom.xml中去就可以了,然后maven自动下载依赖包,并且springboot在启动后会自动配置相关的服务,然后注入的到容器中去。那么springboot是如何知道要去调用哪些方法,加载哪些配置,并注入哪些bean呢?
基本步骤如下:
1.首先,springboot在启动的时候会去找starter包下resources/META-INF/spring.factories文件,然后根据文件中配置的自动配置类运行,加载autoconfigure类。
2.根据@Conditional注解的条件,决定Bean是否要注入的容器中去。
3.然后我们一般用的就是这个Bean,来使用其中的一些功能。
三、编写自己的Starter
3.1 创建maven项目
首先我们创建一个maven项目,按照如下名字起名,其实starter说白了也只是一个jar:
一般的,官方的starter命名方式是spring-boot-start-xxx的形式,为了区分,我们自定义的starter用xxx-spring-boot-starter的命名方式。
1.添加springboot的依赖,因为要成为一个spring-boot-starter是需要依赖springboot的这套流程的,所以我们引入以下依赖:
<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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion> <groupId>com.example.demo</groupId>
<artifactId>person-spring-boot-starter</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging> <dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
<version>2.0.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<version>2.0.0.RELEASE</version>
<optional>true</optional>
</dependency>
</dependencies> </project>
2.添加配置类PersonProperties,主要来从配置文件中读取配置绑定到这个类上:
package com.example.demo; import org.springframework.boot.context.properties.ConfigurationProperties; @ConfigurationProperties(prefix = "spring.person")
public class PersonProperties {
private String name; private Integer age; public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public Integer getAge() {
return age;
} public void setAge(Integer age) {
this.age = age;
}
}
3.添加我们的核心服务类,这里边是我们主要提供的功能,假设我们提供了一个sayHello方法,返回一段话:
package com.example.demo; public class PersonService {
private PersonProperties personProperties; public PersonService(PersonProperties personProperties) {
this.personProperties = personProperties;
}
public String sayHello() {
return "大家好,我叫: " + personProperties.getName() + ", 今年" + personProperties.getAge() + "岁";
}
}
4.添加自动配置类,这个类主要是给springboot来用的,springboot会用这个类来启动,激活我们的服务,注册都容器中去:
@Configuration
@EnableConfigurationProperties(PersonProperties.class)
@ConditionalOnClass(PersonService.class)
@ConditionalOnProperty(prefix = "spring.person", value = "enabled", matchIfMissing = true)
public class PersonServiceAutoConfiguration {
@Autowired
private PersonProperties personProperties; @Bean
public PersonService personService(){
return new PersonService(personProperties);
}
}
解释一下代码中用到的几个注解:
- @ConditionalOnClass,当classpath下发现该类的情况下进行自动配置。
- @ConditionalOnMissingBean,当Spring Context中不存在该Bean时。
- @ConditionalOnProperty(prefix = "srping.person",value = "enabled",havingValue = "true"),当配置文件中spring.perons.enabled=true时。如果没有,使用matchIfMissing的值,也为true。
- @Bean,把返回的PersonService对象添加的spring容器中去,这样我们再使用的使用就可以直接装配了。
其他注解:
- @ConditionalOnBean:当容器中有指定的Bean的条件下
- @ConditionalOnClass:当类路径下有指定的类的条件下
- @ConditionalOnExpression:基于SpEL表达式作为判断条件
- @ConditionalOnJava:基于JVM版本作为判断条件
- @ConditionalOnJndi:在JNDI存在的条件下查找指定的位置
- @ConditionalOnMissingBean:当容器中没有指定Bean的情况下
- @ConditionalOnMissingClass:当类路径下没有指定的类的条件下
- @ConditionalOnNotWebApplication:当前项目不是Web项目的条件下
- @ConditionalOnProperty:指定的属性是否有指定的值
- @ConditionalOnResource:类路径下是否有指定的资源
- @ConditionalOnSingleCandidate:当指定的Bean在容器中只有一个,或者在有多个Bean的情况下,用来指定首选的Bean
- @ConditionalOnWebApplication:当前项目是Web项目的条件下
5. 在resources下添加spring.factories文件,目录结构如下/resources/META-INF/spring.factories,springboot会自动识别这个文件,加载运行我们的PersonServiceAutoConfiguration类。
6.编译运行,用maven install安装jar,默认会安装的maven的仓库里边,用于后来我们使用。
3.2 创建springboot项目测试
这一步简单就不说了,直接按模板创建一个springboot的web项目就行了,然后我们在pom.xml中添加我们刚才写好的person-spring-boot-starter:
<dependency>
<groupId>com.example.demo</groupId>
<artifactId>person-spring-boot-starter</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
配置文件中添加starter的配置项:
spring.person.age=12
spring.person.name=songlin
添加一个控制器测试:
@RestController
public class HelloController { @Autowired
PersonService personService; @GetMapping("/hello")
public String hello(){
String s = personService.sayHello();
return s;
}
}
访问http://localhost:8080/hello,显示如下:
四、总结
当我们想往springboot集成一个功能的时候,就可以用这种方式了,关于starter的写法,大家还可以参看源码,理解了源码我们就能写出更好用的starter了。springboot的基本入门系列就先到这了,往后我们就开始学习springboot集成高级功能了。
SpringBoot起飞系列-自定义starter(十)的更多相关文章
- SpringBoot起飞系列-Web开发(四)
一.前言 从今天你开始我们就开始进行我们的web开发,之前的一篇用SpringBoot起飞系列-使用idea搭建环境(二)已经说明了我们如何进行开发,当然这是搭建起步,接下来我们就开始进行详细的开发, ...
- SpringBoot起飞系列-国际化(六)
一.前言 国际化这个功能可能我们不常用,但是在有需要的地方还是必须要上的,今天我们就来看一下怎么在我们的web开发中配置国际化,让我们的网站可以根据语言来展示不同的形式.本文接续上一篇SpringBo ...
- SpringBoot起飞系列-配置文件(三)
一.SpringBoot中的配置文件 说起到配置文件,大家并不陌生,早在springboot之前,我们用ssh,ssm框架开发的时候整天都要接触配置文件,那时候的配置文件基本上都是.propertie ...
- SpringBoot起飞系列-入门(一)
一.SpringBoot简介 1.1 什么是SpringBoot 说到spring系列,可能大家都很熟悉,spring.springmvc,美之名曰:spring全家桶,那么springboot其实也 ...
- SpringBoot起飞系列-数据访问(九)
一.前言 前边我们已经学些了开发的基本流程,最重要的一步来了,怎么样和数据库交互才是最重要的,毕竟没有数据那就相当于什么也没做,本文我们来学习使用springboot整合jdbc.mybatis.jp ...
- SpringBoot起飞系列-配置嵌入式Servlet容器(八)
一.前言 springboot中默认使用的是tomcat容器,也叫做嵌入式的servlet容器.因为它和我们平常使用的tomcat容器不一样,这个tomcat直接嵌入到的springboot,平常我们 ...
- SpringBoot起飞系列-拦截器和统一错误处理(七)
一.前言 在前边部分我们已经学会了基本的web开发流程,在web开发中,我们通常会对请求做统一处理,比如未登录的用户要拦截掉相关请求,报错页面统一显示等等,这些都需要配置,可以大大简化我们的代码,实现 ...
- SpringBoot学习(2) - 自定义starter
自己开发一个spring boot starter的步骤1.新建一个项目(全部都基于maven),比如新建一个spring-boot-starter-redis的maven项目 pom.xml: &l ...
- SpringBoot起飞系列-日志使用(四)
一.SpringBoot中的日志组件 日志是一个系统中不可缺少的组件.在项目中,我们常用的日志组件有JUL.JCL.Jboss-logging.logback.log4j.log4j2.slf4j.. ...
随机推荐
- Git 提交代码和更新代码
首先,操作之前一定要看清分支!! 其次,提交代码之前一定要先更新代码!! git branch -----查看当前分支 git pull -----更新代码到本地 ...
- Selenium报错:StaleElementReferenceException
一个学生在操作页面跳转时遇到一个Selenium报错, 如下图所示: StaleElementReferenceException: Message: stale element reference: ...
- [转载]作为理工科学生,我们为什么要练就好的文笔?我们需要发blog来记录学习历程?
文/JoeyChen 工程师该怎样才能突破自己的能力瓶颈?写 blog! 工程师该怎样精进自己在职涯上所需要的能力?写 blog! 工程师该怎样才能保持学习与成长的动能?写 blog! 工程师该怎样才 ...
- 软件开发中什么是CI/CD
持续集成(Continuous integration)是一种软件开发实践,每次集成都通过自动化的构建(包括编译,发布,自动化测试)来验证,从而尽早地发现集成错误. 持续部署(continuous d ...
- vsftp的安装和使用
检查Linux系统是否安装了vsftpd的命令: rpm -qa|grep vsftpd 2.安装命令: yum -y install vsftpd 3.卸载命令: yum remove vsftpd ...
- Linux文件的加压缩解压缩tar命令
linux下使用tar命令 解压 语法:tar [主选项+辅选项] 文件或者目录 使用该命令时,主选项是必须要有的,它告诉tar要做什么事情,辅选项是辅助使用的,可以选用.主选项:c 创建新的档案 ...
- uni-app 的更新及碰到的问题
uni-app 的更新 我这个是针对 app 的测试,没有考虑 小程序 及 h5,如需考虑请参考 uni-app 的条件编译 当我们将文件打包好之后,我们在手机上就可以下载 apk 文件,安装到我们的 ...
- Flutter移动电商实战 --(11)首页_屏幕适配方案和制作
1.flutter_ScreenUtil插件简介 flutter_ScreenUtil屏幕适配方案,让你的UI在不同尺寸的屏幕上都能显示合理的布局. 插件会让你先设置一个UI稿的尺寸,他会根据这个尺寸 ...
- Failed to execute aapt
Failed to execute aapt 没错,看到这个表示你的资源出错了.不用想别的. 比如: Failed to execute aapt com.android.ide.common.pro ...
- 如何打开DOS控制台
A:xp下如何打开DOS控制台? a:开始--程序--附件--命令提示符 b:开始--运行--cmd--回车 c:win+r--cmd--回车 B:win7下如何打开DOS控制台? a:开始--所有程 ...