生活随笔
收集整理的這篇文章主要介紹了
spring boot 核心_SpringBoot 核心技术 — 自动配置
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
SpringBoot 能實現快速開發和部署的需求,越來越流行。
約定優于配置 SpringBoot 重要概念之一 約定優配置。這是一種開發模式吧,按照行業的規則,規定,減少不必要的開發。 如: 駝峰規則。 maven src 目錄放源文件,resources 放資源文件,test 放測試文件。 這就是種約定。 自動配置 自動配置是SpringBoot 的核心思想,也是實現 ‘開箱即用’ 的原理。 -加入依賴,按約定配置,即可以使用。 比如我們需要使用 Redis 我們只需要加入 Redis的依賴 和 按約定配置Redis地址,密碼就可以使用。無需再配置一大堆東西。 這就是開箱即用和約定幫我們簡化開發。 自動配置原理 使用SpringBoot 我們經常看到 xxx-starter ,無論是官方的還是第三方的 starter,這些 starter 就是實現 自動配置 的 ‘元兇’。 打開這些 starter 都會發現每個starter 的 META-INF 目錄下都會有一個 spring.factories 文件。
org.springframework.boot.autoconfigure.EnableAutoConfiguration= com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure 上面記錄了 一個該 starter 的 ‘啟動類’, SpringBoot 會掃描 ClassPath 下的 所有spring.factories 文件 并按照上面的‘啟動類’ 去初始化我們的類。
這種思想類似 Java SPI 類似。
DruidDataSourceAutoConfigure 這個啟動類就是去初始化我們數據源的啟動類。
自動配置源碼 完成自動裝配主要靠 @EnableAutoConfiguration 完成; @Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited @AutoConfigurationPackage @Import({EnableAutoConfigurationImportSelector.class}) public @interface EnableAutoConfiguration { String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration"; Class<?>[] exclude() default {}; String[] excludeName() default {}; } 里面初始化了一個 EnableAutoConfigurationImportSelector.class ; 掃描 spring.factories 就是由這個類完成的。該類基礎了 AutoConfigurationImportSelector.class 主要方法:
AutoConfigurationImportSelector:
protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) { List<String> configurations = SpringFactoriesLoader.loadFactoryNames(this.getSpringFactoriesLoaderFactoryClass(), this.getBeanClassLoader()); Assert.notEmpty(configurations, "No auto configuration classes found in META-INF/spring.factories. If you are using a custom packaging, make sure that file is correct."); return configurations; } SpringFactoriesLoader: 掃描 Classpath下 spring.factories
public static List<String> loadFactoryNames(Class<?> factoryClass, ClassLoader classLoader) { String factoryClassName = factoryClass.getName(); try { Enumeration<URL> urls = classLoader != null?classLoader.getResources("META-INF/spring.factories"):ClassLoader.getSystemResources("META-INF/spring.factories"); ArrayList result = new ArrayList(); while(urls.hasMoreElements()) { URL url = (URL)urls.nextElement(); Properties properties = PropertiesLoaderUtils.loadProperties(new UrlResource(url)); String factoryClassNames = properties.getProperty(factoryClassName); result.addAll(Arrays.asList(StringUtils.commaDelimitedListToStringArray(factoryClassNames))); } return result; } catch (IOException var8) { throw new IllegalArgumentException("Unable to load [" + factoryClass.getName() + "] factories from location [" + "META-INF/spring.factories" + "]", var8); } } 自定義自己的 Starter 命名規范: Spring 官方 Starter通常命名為spring-boot-starter-{name}如 spring-boot-starter-web, Spring官方建議非官方Starter命名應遵循 {name}-spring-boot-starter 的格式。 Starter一般有: 讀取配置類 提供服務類 自動配置類 配置文件
讀取配置類(MyProperties)用于讀取 .properties 或者 .yml 約定的配置。
package com.linving.starter.properties; import org.springframework.boot.context.properties.ConfigurationProperties; /** * Created by linli on 2018/1/20. */ @ConfigurationProperties("linving") public class MyProperties { 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; } } 提供服務類(MyProvider) 對外提供服務的類。
package com.linving.starter.service; /** * Created by linli on 2018/1/20. */ public class MyProvider { private String name; private Integer age; public MyProvider(String name, Integer age) { this.name = name; this.age = 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; } } 自動配置類 (MyAutoConfigure),給Springboot 自動配置的初始類 ,這個是必須的。
/** * Created by linli on 2018/1/20. */ @Configuration @ConditionalOnClass(MyProvider.class) @EnableConfigurationProperties(MyProperties.class) @ConditionalOnProperty(prefix="linving",value="enabled",matchIfMissing=true) public class MyAutoConfigure { @Autowired MyProperties properties; @Bean MyProvider myProvider(){ return new MyProvider(properties.getName(),properties.getAge()); } } @ConditionalOnClass,當classpath下發現該類(MyProvider)的情況下進行自動配置。 @ConditionalOnMissingBean,當Spring Context中不存在該Bean時。 @ConditionalOnProperty(prefix=”linving”,value=”enabled”,matchIfMissing=true) ,當配置文件中linving.enabled=true時,才會自動配置,初始化我們的 MyProvider等。
等還有很多配置
https://docs.spring.io/spring-boot/docs/1.5.9.RELEASE/reference/htmlsingle/#boot-features-bean-conditionsns
配置文件(spring.factories); 上面說過這個的作用了。
# Auto Configure org.springframework.boot.autoconfigure.EnableAutoConfiguration= com.linving.starter.MyAutoConfigure 最后打包發布到 maven。
加入依賴(沒有按規則命名):
<dependency> <groupId>com.linving.starter</groupId> <artifactId>demo</artifactId> <version>0.0.1-SNAPSHOT</version> </dependency> 在 application.properties 配置我們的約定
linving.name=dog linving.age=26 這里我們就可以直接使用 我們的MyProvider了。SpringBoot 啟動的時候已經幫我們自動裝配了。
@RestController public class HelloController { @Autowired MyProvider provider; @GetMapping("/hello") public String input(){ return provider.getName()+""; } } 這就是一個簡單的 Starter,也是SpringBoot 的核心思想。
總結
以上是生活随笔 為你收集整理的spring boot 核心_SpringBoot 核心技术 — 自动配置 的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔 網站內容還不錯,歡迎將生活随笔 推薦給好友。