您好,登錄后才能下訂單哦!
這篇文章主要介紹“spring-boot-starter和自定義starter的區(qū)別是什么”,在日常操作中,相信很多人在spring-boot-starter和自定義starter的區(qū)別是什么問(wèn)題上存在疑惑,小編查閱了各式資料,整理出簡(jiǎn)單好用的操作方法,希望對(duì)大家解答”spring-boot-starter和自定義starter的區(qū)別是什么”的疑惑有所幫助!接下來(lái),請(qǐng)跟著小編一起來(lái)學(xué)習(xí)吧!
在前面我講用spring-boot-starter-mail發(fā)郵件的時(shí)候,我側(cè)重看的是spring boot發(fā)郵件的便利性,今天,我們聊下另外一個(gè)方面,spring-boot-starter自身的結(jié)構(gòu)。
之前使用starter的時(shí)候,都是用了就完事了,這次發(fā)郵件的時(shí)候,好奇心上來(lái)了,點(diǎn)開(kāi)了spring-boot-starter-mail的jar包內(nèi)容,發(fā)現(xiàn)竟然只有一個(gè)MANIFEST.MF文件,沒(méi)有class文件,沒(méi)有配置文件,非常的簡(jiǎn)單。
我們看下這個(gè)MANIFEST.MF里面都有些啥
Manifest-Version: 1.0 Implementation-Title: Spring Boot Mail Starter Automatic-Module-Name: spring.boot.starter.mail Implementation-Version: 2.1.8.RELEASE Built-By: Spring Build-Jdk-Spec: 1.8 Created-By: Maven Archiver 3.4.0
這個(gè)也非常的普通,比平平無(wú)奇的古天樂(lè)還要平平無(wú)奇,這不科學(xué)啊。如果只憑這個(gè)文件就能發(fā)郵件,那我早就靠收藏寫(xiě)真圖片娶到新垣結(jié)衣了??隙ùa在別的地方,在找代碼前,我們先動(dòng)手自己制作一個(gè)starter。
自己寫(xiě)個(gè)starter也很簡(jiǎn)單,我們先從https://start.spring.io/下載一個(gè)基本的項(xiàng)目結(jié)構(gòu)下來(lái),然后需要修改幾個(gè)地方。
首先是pom文件要修改,我的pom文件是這樣的
<?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> <groupId>com.skyblue</groupId> <artifactId>mystarter-spring-boot-starter</artifactId> <version>1.0</version> <name>mystarter</name> <description>spring boot starter demo</description> <properties> <java.version>1.8</java.version> </properties> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId> <version>2.1.9.RELEASE</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-autoconfigure</artifactId> <scope>compile</scope> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.6</version> <optional>true</optional> <scope>provided</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
比起原始的pom.xml,改動(dòng)了這么幾個(gè)地方。
<artifactId>mystarter-spring-boot-starter</artifactId>
spring 官方的推薦寫(xiě)artifactId的方法是這樣
官方命名格式為: spring-boot-starter-{name}
非官方建議命名格式:{name}-spring-boot-starter
所以,官方用來(lái)發(fā)mail的starter是spring-boot-starter-mail,我這邊用的就是mystarter-spring-boot-starter。
原始pom.xml會(huì)有這一段,是需要去掉的,否則打包的時(shí)候自己寫(xiě)的類(lèi)加不進(jìn)去,jar里面都是spring boot的類(lèi)
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.1.9.RELEASE</version> <relativePath /> <!-- lookup parent from repository --> </parent>
另外需要加至少兩個(gè)依賴(lài)進(jìn)去
<dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId> <version>2.1.9.RELEASE</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-autoconfigure</artifactId> <scope>compile</scope> </dependency> </dependencies>
其實(shí)把兩個(gè)依賴(lài)都放在<dependencies>節(jié)點(diǎn)里面也行,<dependencyManagement>和<dependencies>的區(qū)別請(qǐng)自行搜索。
pom.xml改好了后我們需要為自己的starter寫(xiě)class啦,我們這邊為了演示,就只實(shí)現(xiàn)打印兩個(gè)值的功能,看代碼
public interface MyStarterService { String getMessage(); Integer getCode(); } public class MyStarterServiceImpl implements MyStarterService{ @Autowired private MyStarterProperties myStarterProperties; public String getMessage() { return myStarterProperties.getMessage(); } public Integer getCode() { return myStarterProperties.getCode(); } }
這個(gè)接口和實(shí)現(xiàn)類(lèi)就是簡(jiǎn)單的返回屬性值而已,屬性值的配置文件是這樣的
@ConfigurationProperties(prefix = "mystarter") public class MyStarterProperties { String message; int code; public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } public int getCode() { return code; } public void setCode(int code) { this.code = code; } }
@ConfigurationProperties注解表示MyStarterProperties 里面的參數(shù)message和code都會(huì)從配置文件里面讀取,prefix = "mystarter"表示配置文件里面參數(shù)名稱(chēng)是有前綴的,前綴就是mystarter。舉個(gè)具體的例子,比如我們之前發(fā)郵件的參數(shù)也是配置在application.properties,參數(shù)的內(nèi)容是這樣的
spring.mail.host=smtp.163.com spring.mail.port=25 spring.mail.username=youname@163.com spring.mail.password=yourpassword
里面host,port,username,password就是參數(shù)的名稱(chēng),spring.mail就是前綴。
上面這些寫(xiě)好了相當(dāng)于業(yè)務(wù)功能部分,現(xiàn)在需要把業(yè)務(wù)功能申明到spring-boot-starter體系里面去,需要靠下面這個(gè)類(lèi)
@Configuration //告訴spring容器配置文件讀取用MyStarterProperties.class @EnableConfigurationProperties({MyStarterProperties.class}) //導(dǎo)入業(yè)務(wù)組件MyStarterServiceImpl @Import(MyStarterServiceImpl.class) public class MyStarterAutoConfiguration { }
我用的是最簡(jiǎn)單的方式,其實(shí)spring boot還提供了@Conditional 系列注解實(shí)現(xiàn)更加精確的配置加載Bean的條件,這里就不詳述了。
最后,我們需要告訴spring boot在哪里去找到這個(gè)MyStarterAutoConfiguration ,在resources/META-INF下面建一個(gè)spring.factories文件
內(nèi)容也很簡(jiǎn)單,就一句而已
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ com.skyblue.mystarter.MyStarterAutoConfiguration
這樣,其實(shí)一個(gè)自定義的starter就完成了,用mvn install就可以直接生成一個(gè)starter了。
在給starter取名字的時(shí)候說(shuō)了,官方命名格式是有固定格式的。其實(shí)官方的便利可不在名字上,而是代碼都包含在spring boot的jar里面,我們引入spring boot的依賴(lài)時(shí),會(huì)自動(dòng)加載spring-boot-autoconfigure.xxx.jar,打開(kāi)這個(gè)jar,就可以看到mail的真正代碼了
有沒(méi)有一種很熟悉的感覺(jué),MailProperties和上面的MyStarterProperties,MailSenderAutoConfiguration和上面的MyStarterAutoConfiguration,顯然都是一樣按照spring boot starter的規(guī)則寫(xiě)的,只是這個(gè)官方starter的代碼不放在starter的jar包,而是包裝到了spring-boot-autoconfigure的jar里面,我們看下MailSenderAutoConfiguration的源代碼,可以看到它就用到了@Configuration、@EnableConfigurationProperties、@Import,還用到了我們沒(méi)用到的@Conditional注解
@Configuration @ConditionalOnClass({ MimeMessage.class, MimeType.class, MailSender.class }) @ConditionalOnMissingBean(MailSender.class) @Conditional(MailSenderCondition.class) @EnableConfigurationProperties(MailProperties.class) @Import({ MailSenderJndiConfiguration.class, MailSenderPropertiesConfiguration.class }) public class MailSenderAutoConfiguration { /** * Condition to trigger the creation of a {@link MailSender}. This kicks in if either * the host or jndi name property is set. */ static class MailSenderCondition extends AnyNestedCondition { MailSenderCondition() { super(ConfigurationPhase.PARSE_CONFIGURATION); } @ConditionalOnProperty(prefix = "spring.mail", name = "host") static class HostProperty { } @ConditionalOnProperty(prefix = "spring.mail", name = "jndi-name") static class JndiNameProperty { } } }
還有一個(gè)spring.factories文件,也可以在spring-boot-autoconfigure.jar里面找到
在里面,我們可以看到完整的spring boot官方starter的AutoConfiguration類(lèi)列表
# Auto Configure org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration,\ org.springframework.boot.autoconfigure.aop.AopAutoConfiguration,\ org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration,\ org.springframework.boot.autoconfigure.batch.BatchAutoConfiguration,\ org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration,\ org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfiguration,\ org.springframework.boot.autoconfigure.cloud.CloudServiceConnectorsAutoConfiguration,\ ......
我這邊就不全列出來(lái)了,大家根據(jù)這個(gè)去找需要的官方starter就比較方便了。
我們另外用https://start.spring.io/再創(chuàng)建一個(gè)項(xiàng)目,然后在pom.xml里面加載starter的依賴(lài)
<dependency> <groupId>com.skyblue</groupId> <artifactId>mystart</artifactId> <version>1.0</version> <type>jar</type> <scope>system</scope> <systemPath>D:\\workspace\\mystart\\target\\mystarter-spring-boot-starter-1.0.jar</systemPath> </dependency>
我為了圖方便,就直接用pom.xml調(diào)用了本地打包的starter包,如果有maven的私服,就可以正常引入。配置application.properties文件
mystarter.message=hello world! mystarter.code=42
寫(xiě)一個(gè)調(diào)用starter的類(lèi)
@Service public class TestService { @Resource private MyStarterService myStarterService; public void message() { System.out.println("code:" + myStarterService.getCode()); System.out.println("message:" + myStarterService.getMessage()); } }
啟動(dòng)spring boot 查看結(jié)果
@SpringBootApplication public class StartdemoApplication { public static void main(String[] args) { ApplicationContext context = SpringApplication.run(StartdemoApplication.class, args); ((TestService)context.getBean("testService")).message(); } }
console可以看到打印出來(lái)的message和code
. ____ _ __ _ _ /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \ ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \ \\/ ___)| |_)| | | | | || (_| | ) ) ) ) ' |____| .__|_| |_|_| |_\__, | / / / / =========|_|==============|___/=/_/_/_/ :: Spring Boot :: (v2.1.9.RELEASE) 2019-10-10 22:13:49.521 INFO 21952 --- [ main] c.w.startdemo.StartdemoApplication : Starting StartdemoApplication on skyblue with PID 21952 (D:\workspace\startdemo\target\classes started by wphmo in D:\workspace\startdemo) 2019-10-10 22:13:49.527 INFO 21952 --- [ main] c.w.startdemo.StartdemoApplication : No active profile set, falling back to default profiles: default 2019-10-10 22:13:50.405 INFO 21952 --- [ main] c.w.startdemo.StartdemoApplication : Started StartdemoApplication in 1.353 seconds (JVM running for 1.983) code:42 message:hello world!
這樣,一個(gè)完整的自定義starter就運(yùn)行成功了。
到此,關(guān)于“spring-boot-starter和自定義starter的區(qū)別是什么”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實(shí)踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識(shí),請(qǐng)繼續(xù)關(guān)注億速云網(wǎng)站,小編會(huì)繼續(xù)努力為大家?guī)?lái)更多實(shí)用的文章!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。