当前位置:   article > 正文

springboot的自动配置实现方式_springboot 手动实现自动配置

springboot 手动实现自动配置

Spring Boot的自动配置是指Spring Boot根据应用程序的依赖和配置信息,自动为应用程序进行配置,减少了开发人员手动配置的工作量。

Spring Boot的自动配置基于条件注解和Spring Boot Starter的机制。条件注解是通过判断一定的条件是否满足来决定是否应用某个配置。Spring Boot Starter是一种特殊的依赖,它包含了一组相关的依赖和配置,可以通过引入该Starter来自动配置相关的功能。

Spring Boot的自动配置可以通过以下几种方式实现:

                  1. 使用@EnableAutoConfiguration注解

2. 使用@ConfigurationProperties注解

3. 使用@Conditional注解

4. 使用Spring Boot Starter自定义配置


1. 使用@EnableAutoConfiguration注解

在Spring Boot的主配置类上添加@EnableAutoConfiguration注解,Spring Boot会根据类路径上的依赖自动进行配置。@Enable底层依赖于@Import注解导入一些类,使用@Import导入的类会被Spring加载到IOC容器中。而@Import提供4中用法: 

  • ​    ① 导入Bean 
  • ​    ② 导入配置类 
  • ​    ③ 导入 ImportSelector 实现类。一般用于加载配置文件中的类 
  • ​    ④ 导入 ImportBeanDefinitionRegistrar 实现类。     

@SpringBootApplication注解内部

  1.   @SpringBootConfiguration
  2.   @EnableAutoConfiguration
  3.   @ComponentScan(
  4.       excludeFilters = {@Filter(
  5.       type = FilterType.CUSTOM,
  6.       classes = {TypeExcludeFilter.class}
  7.   ), @Filter(
  8.       type = FilterType.CUSTOM,
  9.       classes = {AutoConfigurationExcludeFilter.class}
  10.   )}
  11.   )
  12.   public @interface SpringBootApplication {
  13.       // ......
  14.   }

@ComponentScan

  这个注解在Spring中很重要 ,它对应XML配置中的元素。

  作用:自动扫描并加载符合条件的组件或者bean , 将这个bean定义加载到IOC容器中

@SpringBootConfiguration

  作用:SpringBoot的配置类 ,标注在某个类上 , 表示这是一个SpringBoot的配置类;

  1. //@SpringBootConfiguration注解内部
  2.   //这里的 @Configuration,说明这是一个配置类 ,配置类就是对应Spring的xml 配置文件;
  3.   @Configuration
  4.   public @interface SpringBootConfiguration {}
  5.   //里面的 @Component 这就说明,启动类本身也是Spring中的一个组件而已,负责启动应用
  6.   @Component
  7.   public @interface Configuration {}

@AutoConfigurationPackage :自动配置包

  1. //AutoConfigurationPackage的子注解
  2. //Registrar.class 作用:将主启动类的所在包及包下面所有子包里面的所有组件扫描到Spring容器 
  3. @Import({Registrar.class})
  4. public @interface AutoConfigurationPackage {
  5. }

@EnableAutoConfiguration开启自动配置功能

以前我们需要自己配置的东西,而现在SpringBoot可以自动帮我们配置 ;需要告诉SpringBoot开启自动配置功能,这样自动配置才能生效;

@Import({AutoConfigurationImportSelector.class}) :给容器导入组件 

@AutoConfigurationImportSelector :自动配置导入选择器,给容器中导入一些组件

  1. AutoConfigurationImportSelector.class
  2.             ↓
  3.     selectImports方法
  4.             ↓
  5. this.getAutoConfigurationEntry(annotationMetadata)方法
  6.             ↓
  7. this.getCandidateConfigurations(annotationMetadata, attributes)方法
  8.             ↓
  9. 方法体:
  10.  List<String> configurations = SpringFactoriesLoader.loadFactoryNames(this.getSpringFactoriesLoaderFactoryClass(), this.getBeanClassLoader());
  11.         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.");
  12.         return configurations;
  13.             ↓
  14. 在所有包名叫做autoConfiguration的包下面都有META-INF/spring.factories文件

总结原理:

- @EnableAutoConfiguration 注解内部使用                             

-@Import(AutoConfigurationImportSelector.**class**)来加载配置类。 
- 配置文件位置:META-INF/spring.factories,该配置文件中定义了大量的配置类,当 SpringBoot 应用启动时,会自动加载这些配置类,初始化Bean 
- 并不是所有的Bean都会被初始化,在配置类中使用Condition来加载满足条件的Bean

2. 使用@ConfigurationProperties注解

通过在配置类中使用@ConfigurationProperties注解,可以将配置文件中的属性值自动绑定到配置类的属性上。以导入Redis为例

RedisProperties

  1. @ConfigurationProperties(prefix = "spring.redis")
  2. public class RedisProperties {
  3. private String host="localhost";
  4. private int port=6379;
  5. public String getHost() {
  6. return host;
  7. }
  8. public void setHost(String host) {
  9. this.host = host;
  10. }
  11. public int getPort() {
  12. return port;
  13. }
  14. public void setPort(int port) {
  15. this.port = port;
  16. }
  17. }

主配置类中自动加载RedisProperties

  1. @Configuration
  2. @EnableConfigurationProperties(RedisProperties.class)
  3. public class RedisAutoconfiguration {
  4. //注入jedis
  5. //@ConditionalOnBean
  6. @Bean
  7. public Jedis jedis(RedisProperties redisProperties){
  8. return new Jedis(redisProperties.getHost(),redisProperties.getPort());
  9. }
  10. }

3. 使用@Conditional注解

通过在配置类或Bean上使用@Conditional注解,可以根据条件来决定是否应用某个配置或创建某个Bean。

- ConditionalOnProperty:判断配置文件中是否有对应属性和值才初始化Bean 
- ConditionalOnClass:判断环境中是否有对应字节码文件才初始化Bean 
- ConditionalOnMissingBean:判断环境中没有对应Bean才初始化Bean
- ConditionalOnBean:判断环境中有对应Bean才初始化Bean

 以导入Jedis坐标后创建Bean为例,基本思路是:判断redis.clients.jedis.Jedis.class文件是否存在

  • 首先创建一个User类,可以是空类;
  • 其次创建ClassCondition继承自Condition
    1. public class ClassCondition implements Condition {
    2. /**
    3. *
    4. * @param context 上下文对象。用于获取环境,IOC容器,ClassLoader对象
    5. * @param metadata 注解元对象。 可以用于获取注解定义的属性值
    6. * @return
    7. */
    8. @Override
    9. public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
    10. //1.需求: 导入Jedis坐标后创建Bean
    11. //思路:判断redis.clients.jedis.Jedis.class文件是否存在
    12. boolean flag = true;
    13. try{
    14. Class<?> cls = Class.forName("redis.clients.jedis.Jedis");
    15. } catch (ClassNotFoundException e) {
    16. flag = false;
    17. }
    18. return flag;
    19. }
    20. }
  • 将ClassCondition加入主配置类
    1. @Configuration
    2. public class UserConfig {
    3. @Bean
    4. @Conditional(value = ClassCondition.class)
    5. public User user(){
    6. return new User();
    7. }
    8. }
  • 测试
    1. @SpringBootApplication
    2. public class DemoApplication {
    3. public static void main(String[] args) {
    4. ConfigurableApplicationContext context = SpringApplication.run(DemoApplication.class, args);
    5. //获取Bean,redisTemplate
    6. //情况1 没有添加坐标前,发现为空
    7. //情况2 有添加坐标前,发现有对象
    8. // Object redisTemplate = context.getBean("redisTemplate");
    9. // System.out.println(redisTemplate);
    10. /********************案例1********************/
    11. Object user = context.getBean("user");
    12. System.out.println(user);
    13. }
    14. }

4. 使用Spring Boot Starter自定义配置

通过引入Spring Boot Starter依赖,可以自动配置相关的功能。例如,引入spring-boot-starter-web依赖可以自动配置Web应用程序所需的相关功能。可以在模块中引入自定义的配置。

  1. <!--引入自定义的redis-spring-boot-autoconfigure-->
  2. <dependency>
  3. <groupId>com.apesource</groupId>
  4. <artifactId>redis-spring-boot-autoconfigure</artifactId>
  5. <version>0.0.1-SNAPSHOT</version>
  6. </dependency>

实现步骤

- 创建redis-spring-boot-autoconfigure模块
- 创建redis-spring-boot-starter模块,依赖redis-spring-boot-autoconfigure的模块
- 在redis-spring-boot-autoconfigure模块中初始化Jedis的Bean,并定义META-INF/spring.factories文件
- 在测试模块中引入自定义的redis-starter依赖,测试获取Jedis的Bean,操作redis。
 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/运维做开发/article/detail/796458
推荐阅读
相关标签
  

闽ICP备14008679号