javascript
【Spring框架家族】SpringBoot自动配置基本实现
SpringBoot自動配置-Condition_1
Condition是Spring4.0后引入的條件化配置接口,通過實現Condition接口可以完成有條件的加載相應的Bean
@Conditional要配和Condition的實現類(ClassCondition)進行使用
- ClassCondition
- UserConfig
測試
@SpringBootApplicationpublic class SpringbootConditionApplication {public static void main(String[] args) {//啟動SpringBoot的應用,返回Spring的IOC容器ConfigurableApplicationContext context = SpringApplication.run(SpringbootConditionApplication.class, args);Object user = context.getBean("user");System.out.println(user);}}SpringBoot自動配置-Condition_2
將類的判斷定義為動態的。判斷哪個字節碼文件存在可以動態指定。
自定義條件注解類
@Target({ElementType.TYPE, ElementType.METHOD})@Retention(RetentionPolicy.RUNTIME)@Documented@Conditional(ClassCondition.class)public @interface ConditionOnClass {String[] value();}注意:此處@ConditionOnClass為自定義注解
@Configurationpublic class UserConfig {@Bean//@Conditional(ClassCondition.class)@ConditionOnClass("com.alibaba.fastjson.JSON")public User user(){return new User();}@Bean@ConditionalOnProperty(name = "趙麗穎",havingValue = "廊坊")public User user2(){return new User();}}測試User對象的創建
@SpringBootApplicationpublic class SpringbootConditionApplication {public static void main(String[] args) {//啟動SpringBoot的應用,返回Spring的IOC容器ConfigurableApplicationContext context = SpringApplication.run(SpringbootConditionApplication.class, args);Object user = context.getBean("user");System.out.println(user);}}SpringBoot 提供的常用條件注解:
- ConditionalOnProperty:判斷配置文件中是否有對應屬性和值才初始化Bean
- ConditionalOnClass:判斷環境中是否有對應字節碼文件才初始化Bean
- ConditionalOnMissingBean:判斷環境中沒有對應Bean才初始化Bean
SpringBoot自動配置-切換內置web服務器
SpringBoot的web環境中默認使用tomcat作為內置服務器,其實SpringBoot提供了4中內置服務器供我們選擇,我們可以很方便的進行切換
查看繼承關系圖
排除Tomcat
pom文件中的排除依賴效果
SpringBoot自動配置-Enable注解原理
SpringBoot中提供了很多Enable開頭的注解,這些注解都是用于動態啟用某些功能的。而其底層原理是使用@Import注解導入一些配置類,實現Bean的動態加載。
SpringBoot不能直接獲取在其他工程中定義的Bean
演示代碼:
springboot-enable工程
/*** @ComponentScan 掃描范圍:當前引導類所在包及其子包** cs.wy.springbootenable* cs.wy.config* //1.使用@ComponentScan掃描cs.wy.config包* //2.可以使用@Import注解,加載類。這些類都會被Spring創建,并放入IOC容器* //3.可以對Import注解進行封裝。*///@ComponentScan("cs.wy.config")//@Import(UserConfig.class)@EnableUser@SpringBootApplicationpublic class SpringbootEnableApplication {public static void main(String[] args) {ConfigurableApplicationContext context = SpringApplication.run(SpringbootEnableApplication.class, args);//獲取BeanObject user = context.getBean("user");System.out.println(user);}}pom中引入springboot-enable-other
<dependency><groupId>cs.wy</groupId><artifactId>springboot-enable-other</artifactId><version>0.0.1-SNAPSHOT</version></dependency>springboot-enable-other工程
UserConfig
@Configurationpublic class UserConfig {@Beanpublic User user() {return new User();}}EnableUser注解類
@Target(ElementType.TYPE)@Retention(RetentionPolicy.RUNTIME)@Documented@Import(UserConfig.class)public @interface EnableUser {}SpringBoot自動配置-@Import詳解
@Enable*底層依賴于@Import注解導入一些類,使用@Import導入的類會被Spring加載到IOC容器中。而@Import提供4中用法:
- 導入Bean @Import(User.class)只能導入一個Bean,如果有多個Bean,則需要使用多個@Import注解,不方便
- 導入配置類 @Import(UserConfig.class)可以在配置類中配置多個Bean,只需要使用@Import注解導入配置類即可,等同于spring中的配置文件
- 導入 ImportSelector 實現類 @Import(MyImportSelector.class) 使用ImportSelector接口中的方法 selectImports ,可以假裝要創建Bean的全類名,返回值為String[]。
- 導入 ImportBeanDefinitionRegistrar 實現類。 @Import({MyImportBeanDefinitionRegistrar.class}) 使用ImportBeanDefinitionRegistrar接口中的registerBeanDefinitions方法去創建Bean實例,并且指定Bean的ID,Bean實例的創建工作由BeanDefinitionRegistry 參數調用 registerBeanDefinition 完成Bean的
導入 ImportSelector 實現類 @Import(MyImportSelector.class)
public class MyImportSelector implements ImportSelector {@Overridepublic String[] selectImports(AnnotationMetadata importingClassMetadata) {return new String[]{"cs.wy.domain.User", "cs.wy.domain.Role"};}}導入 ImportBeanDefinitionRegistrar 實現類。@Import({MyImportBeanDefinitionRegistrar.class})
public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {@Overridepublic void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.rootBeanDefinition(User.class).getBeanDefinition();registry.registerBeanDefinition("user", beanDefinition);}}SpringbootEnableApplication測試代碼
/*** Import4中用法:* 1. 導入Bean* 2. 導入配置類* 3. 導入ImportSelector的實現類。* 4. 導入ImportBeanDefinitionRegistrar實現類*///@Import(User.class)//@Import(UserConfig.class)//@Import(MyImportSelector.class)//@Import({MyImportBeanDefinitionRegistrar.class})@SpringBootApplicationpublic class SpringbootEnableApplication {public static void main(String[] args) {ConfigurableApplicationContext context = SpringApplication.run(SpringbootEnableApplication.class, args);/*//獲取Bean* Object user = context.getBean("user");* System.out.println(user);*//** User user = context.getBean(User.class);* System.out.println(user);** Role role = context.getBean(Role.class);* System.out.println(role);*//* * Object user = context.getBean("user");* System.out.println(user);*/Map<String, User> map = context.getBeansOfType(User.class);System.out.println(map);} }SpringBoot自動配置-@EnableAutoConfiguration詳解
@EnableAutoConfiguration中使用的是第三種方式:@Import(AutoConfigurationImportSelector.class)
- @EnableAutoConfiguration 注解內部使用 @Import(AutoConfigurationImportSelector.class)來加載配置類。
- 配置文件位置:META-INF/spring.factories,該配置文件中定義了大量的配置類,當 SpringBoot 應用啟動時,會自動加載這些配置類,初始化Bean
- 并不是所有的Bean都會被初始化,在配置類中使用Condition來加載滿足條件的Bean
SpringBoot自動配置-自定義starter步驟分析
SpringBoot自動配置-自定義starter實現-1
1.創建redis-spring-boot-starter工程,pom文件中引入redis-spring-boot-autoconfigure
<!--引入configure,自己編寫的redis的自動化配置--><dependency><groupId>cs.wy</groupId><artifactId>redis-spring-boot-autoconfigure</artifactId><version>0.0.1-SNAPSHOT</version></dependency>2.創建redis-spring-boot-autoconfigure配置工程,創建RedisProperties配置文件參數綁定類
@ConfigurationProperties(prefix = "redis")public class RedisProperties {private String host = "localhost";private int port = 6379;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;}}創建RedisAutoConfiguration自動配置類
@Configuration// 啟用Redis的配置文件@EnableConfigurationProperties(RedisProperties.class)public class RedisAutoConfiguration {/*** 提供Jedis的bean*/@Beanpublic Jedis jedis(RedisProperties redisProperties) {return new Jedis(redisProperties.getHost(), redisProperties.getPort());}}在resource目錄下創建META-INF文件夾并創建spring.factories,注意:”\ “是換行使用的
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\cs.wy.redis.config.RedisAutoConfiguration3.在springboot-enable工程中引入自定義的redis的starter
<!--自定義的redis的starter--><dependency><groupId>cs.wy</groupId><artifactId>redis-spring-boot-starter</artifactId><version>0.0.1-SNAPSHOT</version></dependency>在SpringbootEnableApplication啟動類中測試
Jedis jedis = context.getBean(Jedis.class);System.out.println(jedis);SpringBoot自動配置-自定義starter實現-2
測試springboot-enable工程中的application.properties中的配置參數
redis.port=6666使用注解完成有條件加載配置類
@Configuration@EnableConfigurationProperties(RedisProperties.class)@ConditionalOnClass(Jedis.class)public class RedisAutoConfiguration {/*** 提供Jedis的bean*/@Bean@ConditionalOnMissingBean(name = "jedis")public Jedis jedis(RedisProperties redisProperties) {System.out.println("RedisAutoConfiguration....");return new Jedis(redisProperties.getHost(), redisProperties.getPort());}}總結
以上是生活随笔為你收集整理的【Spring框架家族】SpringBoot自动配置基本实现的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【Spring框架家族】SpringBo
- 下一篇: 【Spring框架家族】SpringBo