解決springboot自定義配置Boolean屬性不能生效的問題
springboot自定義配置Boolean屬性不能生效
屬性名不能是is開頭,例如isLog屬性,你在配置文件中不管怎么給這個(gè)屬性設(shè)值都不會(huì)生效,只需改成log即可。
我使用的版本
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.6.RELEASE</version>
<relativePath/>
</parent>springboot自動(dòng)配置原理
springboot自動(dòng)配置
1、概述
自動(dòng)配置的功能是其簡(jiǎn)化運(yùn)用的關(guān)鍵技術(shù),思想就是約定大于配置,意思就是一個(gè)工程約定必須要有事務(wù)功能,要有aop功能,要有mvc功能等,所以springboot在創(chuàng)建工程的時(shí)候自動(dòng)把這些功能所需的類實(shí)例化并加入到spring容器了,這個(gè)就是約定大于配置,約定了必須要有這些功能。
2、springboot中的SPI機(jī)制
java原生的SPI,是一種服務(wù)發(fā)現(xiàn)機(jī)制( Service Provider Interface)。
它通過在ClassPath路徑下的META-INF/services文件夾查找文件,自動(dòng)加載文件里所定義的類。
這一機(jī)制為很多框架擴(kuò)展提供了可能,比如在Dubbo、JDBC中都使用到了SPI。
- 2.1、JDK中的SPI機(jī)制
public interface Log {
boolean support(String type);
void info();
}在resources/META-INF/services目錄創(chuàng)建文件,文件名稱必須跟接口的完整限定名相同。
這個(gè)接口文件中配置了該接口的所有實(shí)現(xiàn)類的完整限定名。
然后jdk api 加載配置文件
//jdk api 加載配置文件配置實(shí)例 ServiceLoader<Log> all = ServiceLoader.load(Log.class);
- 2.2、springboot中的SPI機(jī)制
具體流程和上面差不多,在工程的resources下面創(chuàng)建META-INF文件夾,在文件夾下創(chuàng)建spring.factories文件,在文件配置內(nèi)容如下:
com.ss.yc.spi.Log=\ com.ss.yc.spi.Log4j,\ com.ss.yc.spi.Logback,\ com.ss.yc.spi.Slf4j
配置的key就是接口完整限定名,value就是接口的各個(gè)實(shí)現(xiàn)類,用","號(hào)隔開。
loadFactoryNames方法獲取實(shí)現(xiàn)了接口的所有類的名稱
@Test
public void test() {
List<String> strings = SpringFactoriesLoader
.loadFactoryNames(Log.class, ClassUtils.getDefaultClassLoader());
for (String string : strings) { System.out.println(string);
}
}loadFactories方法獲取實(shí)現(xiàn)了接口的所有類的實(shí)例
@Test
public void test1() {
List<String> strings = SpringFactoriesLoader
.loadFactories(Log.class, ClassUtils.getDefaultClassLoader());
for (String string : strings) { System.out.println(string);
}
}- 2.3、我們以SpringFactoriesLoader.loadFactoryNames(Log.class, ClassUtils.getDefaultClassLoader());方法調(diào)用為例分析其源碼
可以看到springboot spi是加載了整個(gè)工程的jar包和自己工程定義的spring.factories文件的。
其核心代碼
Properties properties = PropertiesLoaderUtils.loadProperties(resource);
public static Properties loadProperties(Resource resource)
throws IOException {
Properties props = new Properties();
//核心代碼,把文件包裝成properties對(duì)象
fillProperties(props, resource);
return props;
}springboot中的SPI其實(shí)就是加載整個(gè)工程里面的spring.factories文件,然后把文件里面的內(nèi)容建立一個(gè)key和value的映射關(guān)系,只是這個(gè)映射關(guān)系是一個(gè)類型和list的映射關(guān)系。
3、@EnableAutoConfiguration
@EnableAutoConfiguration注解是springboot自動(dòng)配置的核心注解,就是因?yàn)橛羞@個(gè)注解存在就會(huì)把例如事務(wù),緩存,aop,mvc等功能自動(dòng)導(dǎo)入到springboot工程中,Spring框架提供的各種名字為@Enable開頭的Annotation定義,比如@EnableScheduling、@EnableMBeanExport等,@EnableAutoConfiguration的理念和做事方式其實(shí)一脈相承,簡(jiǎn)單概括一下就是,借助@Import的支持,收集和注冊(cè)特定場(chǎng)景相關(guān)的bean定義。
@SuppressWarnings("deprecation")
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(EnableAutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {
...
}@Import了一個(gè)類,這個(gè)AutoConfigurationImportSelector自動(dòng)配置類
- 3.1、DeferredImportSelector
DeferredImportSelector該接口是ImportSelector接口的一個(gè)子接口,那么它是如何使用的呢?
//
public class DeferredImportSelectorDemo implements DeferredImportSelector{
@Override
public String[] selectImports(AnnotationMetadata importingClassMetadata)
{
System.out.println("=====DeferredImportSelectorDemo.selectImports");
return newString[]{DeferredBean.class.getName()};
}
//要返回一個(gè)實(shí)現(xiàn)了Group接口的類
@Override
public Class<?extendsGroup> getImportGroup(){
return DeferredImportSelectorGroupDemo.class;
}
private static class DeferredImportSelectorGroupDemo implements Group{
List<Entry> list=new ArrayList<>();
//收集需要實(shí)例化的類
@Override
public void process(AnnotationMetadata metadata,DeferredImportSelector selector){
System.out.println("=====DeferredImportSelectorGroupDemo.process");
String[] strings=selector.selectImports(metadata);
for(String string:strings){
list.add(newEntry(metadata,string));
}
}
//把收集到的類返回給spring容器
@Override
public Iterable<Entry> selectImports(){
System.out.println("=====DeferredImportSelectorGroupDemo.selectImports");
return list;
}
}
}
//要實(shí)例的bean
public class DeferredBean{}該類必須是@Import導(dǎo)入進(jìn)來
@Component
//Import雖然是實(shí)例化一個(gè)類,Import進(jìn)來的類可以實(shí)現(xiàn)一些接口@Import({DeferredImportSelectorDemo.class})
public class ImportBean{}這樣就實(shí)現(xiàn)了一個(gè)類的實(shí)例化。
- 3.2、EnableAutoConfigurationImportSelector
而AutoCon?gurationImportSelector類,這個(gè)類就是@EnableAutoCon?guration注解中@Import進(jìn)來的類,可以看到該類正是實(shí)現(xiàn)了DeferredImportSelector接口的。
該類其實(shí)就是收集spring.factories文件中以@EnableAutoCon?guration類型為key的所有的類,然后把這些類交給spring去實(shí)例化,而這些類就是我們說的aop、事務(wù)、緩存、mvc等功能的支持類,這就是自動(dòng)配置的加載原理。
4、@Configuration
就是JavaConfig形式的Spring Ioc容器的配置類使用的那個(gè)@Configuration,SpringBoot社區(qū)推薦使用基于JavaConfig的配置形式,所以,這里的啟動(dòng)類標(biāo)注了@Configuration之后,本身其實(shí)也是一個(gè)IoC容器的配置類。
其中@Bean的方法,其返回值將作為一個(gè)bean定義注冊(cè)到Spring的IoC容器,方法名將默認(rèn)成該bean定義的id。
5、@ComponentScan
其實(shí)就是自動(dòng)掃描并加載符合條件的組件(比如@Component和@Repository等)或者bean定義,最終將這些bean定義加載到IoC容器中。
可以通過basePackages等屬性來細(xì)粒度的定制@ComponentScan自動(dòng)掃描的范圍,如果不指定,則默認(rèn)Spring框架實(shí)現(xiàn)會(huì)從聲明@ComponentScan所在類的package進(jìn)行掃描
自定義SpringBoot Starter
1.引入項(xiàng)目的配置依賴
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
<version>2.1.4.RELEASE</version>
</dependency>2.創(chuàng)建xxxService類
完成相關(guān)的操作邏輯
DemoService.java
@Data
public class DemoService{
private String str1;
private String str2;
}3.定義xxxProperties類
屬性配置類,完成屬性配置相關(guān)的操作,比如設(shè)置屬性前綴,用于在application.properties中配置
//指定項(xiàng)目在屬性文件中配置的前綴為str,即可以在屬性文件中通過 str.str1=springboot,就可以改變屬性類字段 str1 的值了
@SuppressWarnings("ConfigurationProperties")
@ConfigurationProperties(prefix = "str")
public class DemoProperties {
public static final String DEFAULT_STR1 = "I know, you need me";
public static final String DEFAULT_STR2 = "but I also need you";
private String str1 = DEFAULT_STR1;
private String str2 = DEFAULT_STR2;
}4.定義xxxAutoConfiguration類
自動(dòng)配置類,用于完成Bean創(chuàng)建等工作
// 定義 java 配置類
@Configuration
//引入DemoService
@ConditionalOnClass({DemoService.class})
// 將 application.properties 的相關(guān)的屬性字段與該類一一對(duì)應(yīng),并生成 Bean
@EnableConfigurationProperties(DemoProperties.class)
public class DemoAutoConfiguration {
// 注入屬性類
@Autowired
private DemoProperties demoProperties;
@Bean
// 當(dāng)容器沒有這個(gè) Bean 的時(shí)候才創(chuàng)建這個(gè) Bean
@ConditionalOnMissingBean(DemoService.class)
public DemoService helloworldService() {
DemoService demoService= new DemoService();
demoService.setStr1(demoProperties.getStr1());
demoService.setStr2(demoProperties.getStr2());
return demoService;
}
}5.在resources下創(chuàng)建目錄META-INF
在 META-INF 目錄下創(chuàng)建 spring.factories
在SpringBoot啟動(dòng)時(shí)會(huì)根據(jù)此文件來加載項(xiàng)目的自動(dòng)化配置類
org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.demo.springboot.config.DemoAutoConfiguration
6.其他項(xiàng)目中使用自定義的Starter
<!--引入自定義Starter-->
<dependency>
<groupId>com.lhf.springboot</groupId>
<artifactId>spring-boot-starter-demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>7.編寫屬性配置文件
#配置自定義的屬性信息 str.str1=為什么我的眼里常含淚水 str.str2=那是因?yàn)槲覍?duì)你愛的深沉
8.寫注解使用
@RestController
public class StringController {
@Autowired
private DemoService demoService; //引入自定義Starter中的DemoService
@RequestMapping("/")
public String addString(){
return demoService.getStr1()+ demoService.getStr2();
}
}總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
jpa使用manyToOne(opntional=true)踩過的坑及解決
這篇文章主要介紹了jpa使用manyToOne(opntional=true)踩過的坑及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-10-10
Java中sleep()與wait()的區(qū)別總結(jié)
因?yàn)樽罱鼘W(xué)習(xí)時(shí)正好碰到這兩個(gè)方法,就查閱相關(guān)資料,并通過程序?qū)崿F(xiàn),進(jìn)行區(qū)別總結(jié)一下,所以下面這篇文章主要給大家總結(jié)介紹了關(guān)于Java中sleep()與wait()區(qū)別的相關(guān)資料,需要的朋友可以參考,下面來一起看看吧。2017-05-05
Mybatis實(shí)現(xiàn)聯(lián)表查詢并且分頁功能
這篇文章主要介紹了Mybatis實(shí)現(xiàn)聯(lián)表查詢并且分頁功能,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-03-03
Spring Boot應(yīng)用實(shí)現(xiàn)圖片資源服務(wù)的方法
本文介紹如何使用SpringBoot創(chuàng)建REST API提供靜態(tài)圖片服務(wù),涵蓋路徑安全檢查、文件存在性驗(yàn)證及緩存控制功能,包含Maven依賴配置和代碼注釋,幫助開發(fā)者實(shí)現(xiàn)安全高效的圖片資源訪問,感興趣的朋友跟隨小編一起看看吧2025-08-08
一鍵解決?IntelliJ?IDEA中Java/Spring?Boot啟動(dòng)失敗(“命令行過長")問題
IDEA運(yùn)行Java程序時(shí)出錯(cuò),提示命令行過長,所以下面這篇文章主要介紹了如何一鍵解決?IntelliJ?IDEA中Java/Spring?Boot啟動(dòng)失敗(“命令行過長“)問題的相關(guān)資料,需要的朋友可以參考下2025-11-11
springboot項(xiàng)目關(guān)閉swagger如何防止漏洞掃描
這篇文章主要介紹了springboot項(xiàng)目關(guān)閉swagger如何防止漏洞掃描,本文通過示例代碼給大家介紹的非常詳細(xì),感興趣的朋友跟隨小編一起看看吧2024-05-05
Spring Cloud Gateway 啟動(dòng)流程源碼分析
文章詳細(xì)分析了Spring Cloud Gateway 4.1.0啟動(dòng)過程,從依賴引入、啟動(dòng)類配置到NettyServer的啟動(dòng),解析了關(guān)鍵方法和類的調(diào)用鏈,并探討了線程池的配置和潛在風(fēng)險(xiǎn),感興趣的朋友跟隨小編一起看看吧2026-01-01

