spring-boot自定義start
技術標籤:spring boot
(我們以redis為例,我們自己製作一個starter)
1、首先建立一個專案;
2、加入依賴
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>3.1.0</version>
</dependency>
3、建立一個RedisProperties用於載入Redis需要的配置;
package com.bjpowernode. starter.properties;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
@Component
@ConfigurationProperties(prefix = "spring.cat.redis")
public class MyRedisProperties {
private String host;
private int port;
private String password;
public String getHost() {
return host;
}
public void setHost(String host) {
this.host = host;
}
public int getPort() {
return port;
}
public void setPort(int port) {
this.port = port;
}
public String getPassword () {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
4、建立一個配置類,這個配置類用於載入配置,並例項化Jedis客戶端;
package com.bjpowernode.starter.config;
import com.bjpowernode.starter.properties.MyRedisProperties;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
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;
import redis.clients.jedis.Jedis;
@Configuration //配置類,相當於一個spring的xml
@ConditionalOnClass(Jedis.class)
@EnableConfigurationProperties(MyRedisProperties.class) //開啟使用對映實體物件
@ConditionalOnProperty //存在對應配置資訊時初始化該配置類
(
prefix = "spring.cat.redis",//存在配置字首redis
value = "enabled",//開啟
matchIfMissing = true //缺失檢查
)
public class MyRedisAutoConfiguration {
/**
* 在spring ioc容器中要建立一個jedis物件
*
* @param redisProperties
* @return
*/
@Bean
@ConditionalOnMissingBean
public Jedis jedis(MyRedisProperties redisProperties) {
Jedis jedis = new Jedis(redisProperties.getHost(), redisProperties.getPort());
jedis.auth(redisProperties.getPassword());
return jedis;
}
}
自動化配置程式碼中有很多我們之前沒有用到的註解配置,分別介紹如下:
@Configuration:這個配置就不用多做解釋了,我們一直在使用;
@EnableConfigurationProperties:這是一個開啟使用配置引數的註解,value值就是我們配置實體引數對映的ClassType,將配置實體作為配置來源;
SpringBoot內建條件註解
@ConditionalOnXxx相關的註解為條件註解,也是我們配置的關鍵,可以把這些註解理解為具有Xxx條件:
@ConditionalOnBean:當SpringIoc容器記憶體在指定Bean的條件
@ConditionalOnClass:當Spring Ioc容器記憶體在指定Class的條件;
@ConditionalOnExpression:基於SpEL表示式作為判斷條件
@ConditionalOnJava:基於JVM版本作為判斷條件
@ConditionalOnMissingBean:當SpringIoc容器內不存在指定Bean的條件
@ConditionalOnMissingClass:當SpringIoc容器內不存在指定Class的條件
@ConditionalOnNotWebApplication:當前專案不是Web專案的條件
@ConditionalOnProperty:指定的屬性是否有指定的值;
@ConditionalOnResource:類路徑是否有指定的值
@ConditionalOnSingleCandidate:當指定Bean在SpringIoc容器內只有一個,或者雖然有多個但是指定首選的Bean;
@ConditionalOnWebApplication:當前專案是Web專案的條件
以上註解都是元註解@Conditional演變而來的,根據不用的條件對應建立以上的具體條件註解。
截止到專案我們還沒有完成自動化配置starter,我們先來了解Starter自動化配置原理:
在註解@SpringBootApplication上存在一個開啟自動化配置的註解@EnableAutoConfiguration來完成自動化配置,註解原始碼如下所示:
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {
String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";
Class<?>[] exclude() default {};
String[] excludeName() default {};
}
在@EnableAutoConfiguration註解內使用到了@import註解來完成匯入配置的功能,而EnableAutoConfigurationImportSelector內部則是使用了SpringFactoriesLoader.loadFactoryNames方法進行掃描具有META-INF/spring.factories檔案的jar包。我們可以先來看下spring-boot-autoconfigure包內的spring.factories檔案內容,如下所示:
可以看到配置的結構形式是Key=>Value形式,多個Value時使用,隔開,目的是為了完成自動化配置,所以我們這裡Key則是需要使用:org.springframework.boot.autoconfigure.EnableAutoConfiguration
自定義spring.factories
在src/main/resource目錄下建立META-INF目錄,並在目錄內新增檔案spring.factories,具體內容如下:
# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.bjpowernode.starter.config.MyRedisAutoConfiguration
至此自定義的starter已經開發完畢;
然後就可以在其他專案裡面引用我們自己製作的starter的依賴,然後使用它進行開發;