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 中的所有条件都满足,该类才会生效。
  • 相关阅读:
    把git项目放到个人服务器上
    关于fcitx无法切换输入法的问题解决
    博客变迁通知
    (欧拉回路 并查集 别犯傻逼的错了) 7:欧拉回路 OpenJudge 数据结构与算法MOOC / 第七章 图 练习题(Excercise for chapter7 graphs)
    (并查集) HDU 1856 More is better
    (并查集 不太会) HDU 1272 小希的迷宫
    (并查集 注意别再犯傻逼的错了) HDU 1213 How Many Tables
    (最小生成树 Kruskal算法) 51nod 1212 无向图最小生成树
    (并查集) HDU 1232 畅通工程
    (最小生成树 Prim) HDU 1233 还是畅通工程
  • 原文地址:https://www.cnblogs.com/hsug/p/15251422.html
Copyright © 2011-2022 走看看