zoukankan      html  css  js  c++  java
  • SpringBoot自动装配

    什么是SpringBoot自动装配?

    SpringBoot方便在于我们需要第三方依赖直接引入starter即可,通过少量的注解和一些简单的配置就能使用第三方组件的功能。SpringBoot的核心就在于自动装配,带来了极大地方便。

    SpringBoot是如何自动装配?

    SpringBoot 的核心注解 @SpringBootApplication

    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    @Inherited
    @SpringBootConfiguration
    @EnableAutoConfiguration
    @ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
    		@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
    public @interface SpringBootApplication {
    
    	@AliasFor(annotation = EnableAutoConfiguration.class)
    	Class<?>[] exclude() default {};
    
    	@AliasFor(annotation = EnableAutoConfiguration.class)
    	String[] excludeName() default {};
    	// 根据包路径扫描
    	@AliasFor(annotation = ComponentScan.class, attribute = "basePackages")
    	String[] scanBasePackages() default {};
    	// 直接根据class类扫描
    	@AliasFor(annotation = ComponentScan.class, attribute = "basePackageClasses")
    	Class<?>[] scanBasePackageClasses() default {};
    
    	@AliasFor(annotation = ComponentScan.class, attribute = "nameGenerator")
    	Class<? extends BeanNameGenerator> nameGenerator() default BeanNameGenerator.class;
    
    	@AliasFor(annotation = Configuration.class)
    	boolean proxyBeanMethods() default true;
    
    }
    
    

    @SpringBootApplication看作是 @Configuration@EnableAutoConfiguration@ComponentScan 注解的集合。

    • @Configuration:允许在上下文中注册额外的 bean 或导入其他配置类。
    • @EnableAutoConfiguration:代表开启springboot的自动装配。
    • @ComponentScan:自动扫描并加载符合条件的组件或bean定义,最终将这些bean定义加载到容器中。

    关于@EnableAutoConfiguration实现自动装配注解

    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    @Inherited
    @AutoConfigurationPackage
    //  加载自动装配类 xxxAutoconfiguration
    @Import(AutoConfigurationImportSelector.class)
    public @interface EnableAutoConfiguration {
    	String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";
    
            //按类型排序不需要自动装配的类
    	Class<?>[] exclude() default {};
    
            //按名称排除不需要自动装配的类
    	String[] excludeName() default {};
    
    }
    
    

    重点看看AutoConfigurationImportSelector 类做了什么

    	private static final String[] NO_IMPORTS = {};
    	@Override
    	public String[] selectImports(AnnotationMetadata annotationMetadata) {
                     //  自动装配是否打开
    		if (!isEnabled(annotationMetadata)) {
    			return NO_IMPORTS;
    		}
                    // 获取所有需要装配的bean
    		AutoConfigurationEntry autoConfigurationEntry = getAutoConfigurationEntry(annotationMetadata);
    		return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
    	}
    

    getAutoConfigurationEntry()方法主要负责加载自动配置类。

    	protected AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {
                    // 1.判断自动装配开关是否打开。默认spring.boot.enableautoconfiguration=true,可在 application.properties 或 application.yml 中设置
    		if (!isEnabled(annotationMetadata)) {
    			return EMPTY_ENTRY;
    		}
                    // 2.用于获取EnableAutoConfiguration注解中的 exclude 和 excludeName。
    		AnnotationAttributes attributes = getAttributes(annotationMetadata);
                    // 3.获取需要自动装配的所有配置类,读取META-INF/spring.factories
    		List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes);
    		configurations = removeDuplicates(configurations);
    		Set<String> exclusions = getExclusions(annotationMetadata, attributes);
    		checkExcludedClasses(configurations, exclusions);
    		configurations.removeAll(exclusions);
                    // 4.这一步有经历了一遍筛选,@ConditionalOnXXX 中的所有条件都满足,该类才会生效。
    		configurations = getConfigurationClassFilter().filter(configurations);
    		fireAutoConfigurationImportEvents(configurations, exclusions);
    		return new AutoConfigurationEntry(configurations, exclusions);
    	}
    
    1. 判断自动装配开关是否打开。默认spring.boot.enableautoconfiguration=true,可在 application.properties 或 application.yml 中设置

    2. 用于获取EnableAutoConfiguration注解中的 exclude 和 excludeName。

    3. 获取需要自动装配的所有配置类,读取META-INF/spring.factories

      从下图可以看到这个文件的配置内容都被我们读取到了。XXXAutoConfiguration的作用就是按需加载组件。

    不光是这个依赖下的META-INF/spring.factories被读取到,所有 Spring Boot Starter 下的META-INF/spring.factories都会被读取到。
    所以,你可以清楚滴看到, druid 数据库连接池的 Spring Boot Starter 就创建了META-INF/spring.factories文件。

    1. spring.factories中这么多配置,不是每次启动都要全部加载。
      经历了一遍筛选,@ConditionalOnXXX 中的所有条件都满足,该类才会生效。
  • 相关阅读:
    找到关注点
    c中printf必须在所有的变量申明之后才能用?
    在eclipse里面运行项目,并未出现中文乱码的问题;但是打成war包运行, tomcat运行startup.bat后控制台中文乱码
    《分工与贸易》笔记
    《范围:为什么通才能在专业化的世界中取胜》笔记
    《不充分均衡》笔记
    ”苦“没有价值
    《为什么佛学是真的》笔记
    《强力瞬间》笔记
    你和你的渴望
  • 原文地址:https://www.cnblogs.com/hsug/p/15251422.html
Copyright © 2011-2022 走看看