精华内容
下载资源
问答
  • Springboot自动配置原理

    2021-01-12 13:20:03
  • SpringBoot自动配置原理

    2020-08-25 18:30:13
    SpringBoot自动配置原理

    配置文件到底能写什么?怎么写?SpringBoot官方文档中有大量的配置,我们无法全部记住

    分析自动配置原理

    我们以**HttpEncodingAutoConfiguration(Http编码自动配置)**为例解释自动配置原理;

    //表示这是一个配置类,和以前编写的配置文件一样,也可以给容器中添加组件;
    @Configuration 
    
    //自动配置属性
    //启动指定类的ConfigurationProperties功能;
      //进入这个HttpProperties查看,将配置文件中对应的值和HttpProperties绑定起来;
      //并把HttpProperties加入到ioc容器中
    @EnableConfigurationProperties({HttpProperties.class}) 
    
    //Spring底层@Conditional注解
      //根据不同的条件判断,如果满足指定的条件,整个配置类里面的配置就会生效;
      //这里的意思就是判断当前应用是否是web应用,如果是,当前配置类生效
    @ConditionalOnWebApplication(
        type = Type.SERVLET
    )
    
    //判断当前项目有没有这个类CharacterEncodingFilter;SpringMVC中进行乱码解决的过滤器;
    @ConditionalOnClass({CharacterEncodingFilter.class})
    
    //判断配置文件中是否存在某个配置:spring.http.encoding.enabled;
      //如果不存在,判断也是成立的
      //即使我们配置文件中不配置pring.http.encoding.enabled=true,也是默认生效的;
    @ConditionalOnProperty(
        prefix = "spring.http.encoding",
        value = {"enabled"},
        matchIfMissing = true
    )
    
    public class HttpEncodingAutoConfiguration {
        //他已经和SpringBoot的配置文件映射了
        private final Encoding properties;
        //只有一个有参构造器的情况下,参数的值就会从容器中拿
        public HttpEncodingAutoConfiguration(HttpProperties properties) {
            this.properties = properties.getEncoding();
        }
        
        //给容器中添加一个组件,这个组件的某些值需要从properties中获取
        @Bean
        @ConditionalOnMissingBean //判断容器没有这个组件?
        public CharacterEncodingFilter characterEncodingFilter() {
            CharacterEncodingFilter filter = new OrderedCharacterEncodingFilter();
            filter.setEncoding(this.properties.getCharset().name());
            filter.setForceRequestEncoding(this.properties.shouldForce(org.springframework.boot.autoconfigure.http.HttpProperties.Encoding.Type.REQUEST));
            filter.setForceResponseEncoding(this.properties.shouldForce(org.springframework.boot.autoconfigure.http.HttpProperties.Encoding.Type.RESPONSE));
            return filter;
        }
        //。。。。。。。
    }
    

    重点

    在配置文件中能配置的东西,都存在一个固有的规律,被xxxAutoConfigurartion自动装配:默认值

    存在一个xxxxProperties绑定配置文件,我们就可以使用自定义配置了

    xxxxProperties都存在一个@ConfigurationProperties(prefix = “spring.mvc”)的注解,作用是将配置文件中配置的每一个属性的值,会将配置文件中前缀是prefix="spring.mvc"映射到当前类中

    一句话总结 :根据当前不同的条件判断,决定这个配置类是否生效!

    • 一但这个配置类生效;这个配置类就会给容器中添加各种组件;
    • 这些组件的属性是从对应的properties类中获取的,这些类里面的每一个属性又是和配置文件绑定的;
    • 所有在配置文件中能配置的属性都是在xxxxProperties类中封装着;
    • 配置文件能配置什么就可以参照某个功能对应的这个属性类
    //从配置文件中获取指定的值和bean的属性进行绑定
    @ConfigurationProperties(prefix = "spring.http") 
    public class HttpProperties {
        // .....
    }
    

    我们去配置文件里面试试前缀,看提示!

    这就是自动装配的原理!

    精髓 重点

    1、SpringBoot启动会加载大量的自动配置类

    2、我们看我们需要的功能有没有在SpringBoot默认写好的自动配置类当中;

    3、我们再来看这个自动配置类中到底配置了哪些组件;(只要我们要用的组件存在在其中,我们就不需要再手动配置了)

    4、给容器中自动配置类添加组件的时候,会从properties类中获取某些属性。我们只需要在配置文件中指定这些属性的值即可;

    **xxxxAutoConfigurartion:自动配置类;**给容器中添加组件

    xxxxProperties:封装配置文件中相关属性;

    了解:@Conditional

    了解完自动装配的原理后,我们来关注一个细节问题,自动配置类必须在一定的条件下才能生效;

    @Conditional派生注解(Spring注解版原生的@Conditional作用)

    作用:必须是@Conditional指定的条件成立,才给容器中添加组件,配置配里面的所有内容才生效
    在这里插入图片描述
    那么多的自动配置类,必须在一定的条件下才能生效;也就是说,我们加载了这么多的配置类,但不是所有的都生效了。

    我们怎么知道哪些自动配置类生效?

    我们可以通过启用 debug=true属性;来让控制台打印自动配置报告,这样我们就可以很方便的知道哪些自动配置类生效;

    #开启springboot的调试类
    debug=true
    

    Positive matches:(自动配置类启用的:正匹配)

    Negative matches:(没有启动,没有匹配成功的自动配置类:负匹配)

    Unconditional classes: (没有条件的类)

    掌握吸收理解原理,即可以不变应万变!

    展开全文
  • springboot自动配置原理

    2019-07-22 18:04:01
    springboot自动配置原理

    配置文件到底能写什么?怎么写?自动配置原理

    配置文件能配置的属性参照

    自动配置原理:

    1. springboot启动时加载主配置类,开启了自动配置功能@EnableAutoConfiguration
    2. @EnableAutoConfiguration作用:
    • 利用AutoConfigurationImportSelector给容器中导入组件?
    • 查看selectImports()的内容
    • List configurations = this.getCandidateConfigurations(annotationMetadata, attributes);获取候选的配置
        SpringFactoriesLoader.loadFactoryNames
        扫描所有jar包类路径下 META-INF/spring.factories
        把扫描到的这些文件的内容包装成properties对象
        从properties中获取到EnableAutoConfiguration.class类(类名)对应的值,然后将它们添加到容器中.
    

    将类路径下META-INF/spring.factories里面配置的所有EnableAutoConfiguration的值加入到了容器中

    # Auto Configure
    org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
    org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration,\
    org.springframework.boot.autoconfigure.aop.AopAutoConfiguration,\
    org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration,\
    org.springframework.boot.autoconfigure.batch.BatchAutoConfiguration,\
    org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration,\
    ......
    

    每一个这样的xxxAutoConfiguration类都是容器中的一个组件,都加入到容器中;用他们来做自动配置;

    1. 每一个自动配置类进行自动配置功能
    2. 解释自动配置原理
      eg: HttpEncodingAutoConfiguration(Http编码自动配置)
    @Configuration   //表示这是一个配置类,类似以前编写的配置文件,也可以给容器中添加组件
    
    // 启动ConfigurationProperties功能	将配置文件中对应的值和HttpEncodingProperties绑定起来
    @EnableConfigurationProperties({HttpProperties.class}) 
    // spring底层@Conditional,根据不同的条件,如果满足指定的条件,
    //整个配置类里面的配置就会生效;判断当前应用是否为web应用,如果是当前配置类生效
    @ConditionalOnWebApplication(
        type = Type.SERVLET
    )
    //判断当前项目有没有这个类
    // CharacterEncodingFilter:springmvc 中用来乱码解决的过滤器
    @ConditionalOnClass({CharacterEncodingFilter.class})
    //判断配置文件中是否存在某个配置  spring.http.encoding.enabled如果不存在,判断也成立
    // 配置文件中不配置spring.http.encoding.enabled=true ,也是默认生效
    @ConditionalOnProperty(
        prefix = "spring.http.encoding",
        value = {"enabled"},
        matchIfMissing = true
    )
    public class HttpEncodingAutoConfiguration {
       // 已经和springboot的配置文件映射
       private final Encoding properties;
     
     //只有一个参数构造器的情况下,参数的值就会从容器中那=拿
     public HttpEncodingAutoConfiguration(HttpProperties properties) {
            this.properties = properties.getEncoding();
        }
    // 向容器中添加组件
         @Bean
          @ConditionalOnMissingBean
        public CharacterEncodingFilter characterEncodingFilter() {
            CharacterEncodingFilter filter = new OrderedCharacterEncodingFilter();
            filter.setEncoding(this.properties.getCharset().name());
            filter.setForceRequestEncoding(this.properties.shouldForce(org.springframework.boot.autoconfigure.http.HttpProperties.Encoding.Type.REQUEST));
            filter.setForceResponseEncoding(this.properties.shouldForce(org.springframework.boot.autoconfigure.http.HttpProperties.Encoding.Type.RESPONSE));
            return filter;
        }
    

    根据当前不同的条件,决定这个配置类是否生效
    一旦生效,这个配置类就会给容器中添加各种组件,这些组件的属性是从对应的properties类中获取的,这些类里面的属性又是和配置文件绑定的.

    1. 所有在配置文件中能配置的属性都在xxxxProperties类中封装着;配置文件可以配置什么,就可以参照该功能对应的属性类
    
    
    //从配置文件中获取指定的值和bean的属性进行绑定
    @ConfigurationProperties(
        prefix = "spring.http"
    )
    public class HttpProperties {
    

    6) springboot 精髓

    • springboot 启动会加载大量的配置类
    • 看springboot默认写好的自动配置类是否有我们需要的功能;
    • 在看自动配置类中都配置了哪些组件(只要我们要的组件有就不需要配置了)
    • 给容器中自动配置类添加组件时,会从properties类中获取某些属性,我们就可以在配置文件中指定这些属性的值

    xxxAutoConfiguration  自动配置类
    给容器中添加组件
    xxxProperties封装配置文件中相关属性

    1. 查看生效和没有生效的自动配置类

    在主配置类中配置 debug=true,运行项目,在控制台查看

    ============================
    CONDITIONS EVALUATION REPORT
    ============================
    
    
    Positive matches:(生效的自动配置类)
    -----------------
    
       CodecsAutoConfiguration matched:
          - @ConditionalOnClass found required class 'org.springframework.http.codec.CodecConfigurer' (OnClassCondition)
    
       CodecsAutoConfiguration.JacksonCodecConfiguration matched:
          - @ConditionalOnClass found required class 'com.fasterxml.jackson.databind.ObjectMapper' (OnClassCondition)
    
       CodecsAutoConfiguration.JacksonCodecConfiguration#jacksonCodecCustomizer matched:
          - @ConditionalOnBean (types: com.fasterxml.jackson.databind.ObjectMapper; SearchStrategy: all) found bean 'jacksonObjectMapper' (OnBeanCondition)
    
       DispatcherServletAutoConfiguration matched:
          - @ConditionalOnClass found required class 'org.springframework.web.servlet.DispatcherServlet' (OnClassCondition)
          - found 'session' scope (OnWebApplicationCondition)
    
    
    Negative matches:(未生效的自动配置包)
    -----------------
    
       ActiveMQAutoConfiguration:
          Did not match:
             - @ConditionalOnClass did not find required class 'javax.jms.ConnectionFactory' (OnClassCondition)
    
       AopAutoConfiguration:
          Did not match:
             - @ConditionalOnClass did not find required class 'org.aspectj.lang.annotation.Aspect' (OnClassCondition)
    
       ArtemisAutoConfiguration:
          Did not match:
             - @ConditionalOnClass did not find required class 'javax.jms.ConnectionFactory' (OnClassCondition)
    
    
    
    展开全文
  • springboot 自动配置原理 @SpringBootApplication public class DemoApplication { public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); } } @SpringBoot...

    springboot 自动配置原理

    @SpringBootApplication
    public class DemoApplication {
        public static void main(String[] args) {
            SpringApplication.run(DemoApplication.class, args);
        }
    }
    

    @SpringBootApplication 主要包含已下注解

    @SpringBootConfiguration
    @EnableAutoConfiguration
    @ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
    		@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
    

    @SpringBootConfiguration 标记当前类为配置类并注入容器中
    @EnableAutoConfiguration 开启自动配置功能
    @ComponentScan 扫描主类所在的同级包以及下级包里的Bean

    @EnableAutoConfiguration 是实现自动配置的核心注解,主要包含

    @AutoConfigurationPackage
    @Import(AutoConfigurationImportSelector.class)
    

    @AutoConfigurationPackage 添加该注解的类所在的package 作为 自动配置package 进行管理。

    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    @Inherited
    //导入AutoConfigurationPackages.Registrar.class
    @Import(AutoConfigurationPackages.Registrar.class)
    public @interface AutoConfigurationPackage {
    
    	/**
    	 * Base packages that should be registered with {@link AutoConfigurationPackages}.
    	 * <p>
    	 * Use {@link #basePackageClasses} for a type-safe alternative to String-based package
    	 * names.
    	 * @return the back package names
    	 * @since 2.3.0
    	 */
    	String[] basePackages() default {};
    
    	/**
    	 * Type-safe alternative to {@link #basePackages} for specifying the packages to be
    	 * registered with {@link AutoConfigurationPackages}.
    	 * <p>
    	 * Consider creating a special no-op marker class or interface in each package that
    	 * serves no purpose other than being referenced by this attribute.
    	 * @return the base package classes
    	 * @since 2.3.0
    	 */
    	Class<?>[] basePackageClasses() default {};
    
    }
    

    AutoConfigurationPackages.Registrar.class

    private static final String BEAN = AutoConfigurationPackages.class.getName();
    
    //BeanDefinitionRegistry 是bean的定义注册中心
    public static void register(BeanDefinitionRegistry registry, String... packageNames) {
    		//判断注册中心是否有AutoConfigurationPackages,如果有就设置BasePackages属性
    		//没有就NEW一个并设置BasePackages属性
    		if (registry.containsBeanDefinition(BEAN)) {
    			BasePackagesBeanDefinition beanDefinition = (BasePackagesBeanDefinition) registry.getBeanDefinition(BEAN);
    			beanDefinition.addBasePackages(packageNames);
    		}
    		else {
    			registry.registerBeanDefinition(BEAN, new BasePackagesBeanDefinition(packageNames));
    		}
    	}
    static class Registrar implements ImportBeanDefinitionRegistrar, DeterminableImports {
    
    		@Override
    		public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {
    			//获得主类所在的包名,通过register方法注册设置BasePackagesBeanDefinition的BasePackages属性
    			register(registry, new PackageImports(metadata).getPackageNames().toArray(new String[0]));
    		}
    
    		@Override
    		public Set<Object> determineImports(AnnotationMetadata metadata) {
    			return Collections.singleton(new PackageImports(metadata));
    		}
    
    	}
    

    @Import(AutoConfigurationImportSelector.class)
    AutoConfigurationImportSelector.class 主要的核心方法

    @Override
    	public String[] selectImports(AnnotationMetadata annotationMetadata) {
    		if (!isEnabled(annotationMetadata)) {
    			return NO_IMPORTS;
    		}
    		AutoConfigurationEntry autoConfigurationEntry = getAutoConfigurationEntry(annotationMetadata);
    		return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
    	}
    	protected AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {
    		if (!isEnabled(annotationMetadata)) {
    			return EMPTY_ENTRY;
    		}
    		AnnotationAttributes attributes = getAttributes(annotationMetadata);
    		List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes);
    		configurations = removeDuplicates(configurations);
    		Set<String> exclusions = getExclusions(annotationMetadata, attributes);
    		checkExcludedClasses(configurations, exclusions);
    		configurations.removeAll(exclusions);
    		configurations = getConfigurationClassFilter().filter(configurations);
    		fireAutoConfigurationImportEvents(configurations, exclusions);
    		return new AutoConfigurationEntry(configurations, exclusions);
    	}
    	protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
    		//getSpringFactoriesLoaderFactoryClass() ==EnableAutoConfiguration.class
    		//getBeanClassLoader() 获得class类加载器
    		//使用类加载器在META-INF/spring.factories所有的配置文件中查找 org.springframework.boot.autoconfigure.EnableAutoConfiguration返回 				   
    		List<String> configurations = SpringFactoriesLoader.loadFactoryNames(getSpringFactoriesLoaderFactoryClass(),
    				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;
    	}
    
    展开全文
  • springBoot自动配置原理

    2018-10-22 11:40:53
    springBoot自动配置原理 1、我们应用切入口的@EnableAutoConfiguration注解: springBoot启动的时候加载了主配置类,开启了自动配置功能@EnableAutoConfiguration @EnableAutoConfiguration注解作用: ...
  • SpringBoot 自动配置原理 1. SpringBoot 源码常用注解 这部分主要讲一下 SpringBoot 源码中经常使用到的注解,以扫清后面阅读源码时候的障碍 组合注解 当可能大量同时使用到几个注解到同一个类上,就可以考虑将这几...
  • SpringBoot自动配置原理前言:SpringBoot的最大的特点就是帮助我们自动配置了很多场景启动器,我们之前利用SSM开发一个项目时,那些繁琐的配置再也不需要自己配置了,自动配置原理也是面试必问的关于SpringBoot的知识点,...
  • SpringBoot自动配置原理源码解读1.@SpringBootApplication:通过这个注解,不仅仅标记这是一个SpringBoot应用,而且还开启自动配置的功能主要注解EnableAutoConfiguration@Target1.程序启动入口SpringApplication启动...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 5,433
精华内容 2,173
关键字:

springboot自动配置原理

spring 订阅