栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

SpringBoot Application注解原理及代码详解

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

SpringBoot Application注解原理及代码详解

1、SpringBoot 启动main()

@SpringBootApplication
public class TomcatdebugApplication {

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

}

1.1 @SpringBootApplication 注解,其实主要是@ComponentScan,@EnableAutoConfiguration,@SpringBootConfiguration三个注解

@ComponentScan 注解:

spring里有四大注解:@Service,@Repository,@Component,@Controller用来定义一个bean.@ComponentScan注解就是用来自动扫描被这些注解标识的类,最终生成ioc容器里的bean.

可以通过设置@ComponentScan basePackages,includeFilters,excludeFilters属性来动态确定自动扫描范围,类型已经不扫描的类型.

 默认情况下:它扫描所有类型,并且扫描范围是@ComponentScan注解所在配置类包及子包的类

@SpringBootConfiguration 注解:

@SpringBootConfiguration继承自@Configuration,二者功能也一致,标注当前类是配置类,
并会将当前类内声明的一个或多个以@Bean注解标记的方法的实例纳入到spring容器中,并且实例名就是方法名。

demo 说明:

(1) 注入spring ioc bean

@SpringBootConfiguration
public class Config {
  @Bean
  public Map createMap(){
    Map map = new HashMap();
    map.put("username","gxz");
    map.put("age",27);
    return map;
  }
}

(2)调用:

public static void main( String[] args )
  {
    //方式1 获取context
    ConfigurableApplicationContext context = SpringApplication.run(App.class, args);
    context.getBean(Runnable.class).run();
    context.getBean("createMap");  //注意这里直接获取到这个方法bean
    int age = (int) map.get("age");
    System.out.println("age=="+age);
//方式2. 使用@Autowired注解,应用bean 
// @Autowired// Map createMap
}

@EnableAutoConfiguration 注解

@EnableAutoConfiguration作用:从classpath中搜索所有的meta-INF/spring.factories配置文件,然后将其中key为org.springframework.boot.autoconfigure.EnableAutoConfiguration的value加载到spring容器中。

上图分析源码可知: @EnableAutoConfiguration = @import + @AutoConfigurationPackage

@AutoConfigurationPackage:主要作用是自动配置包

@import: Spring底层注解@import,给容器中导入一个组件;导入的组件由AutoConfigurationPackages.Registrar.class将主配置类(@SpringBootApplication标注的类)的所在包以及下面所有子包里面的所有组件扫描到Spring容器。

AutoConfigurationimportSelector的作用是导入哪些组件的选择器。将所有需要导入的组件以全类名的方式返回,这些组件就会被添加到容器中;也会给容器导入非常多的自动配置类(xxxAutoConfiguration),就是给容器中导入这个场景需要的所有组件,并配置好这些组件。

  有了自动配置类,免去了我们手动编写配置注入功能组件等的工作

具体工作流程图:

@EnableAutoConfiguration加载过程

 自动配置主要由AutoConfigurationimportSelector实现的,我们主要从这个类开始讲起。AutoConfigurationimportSelector是@EnableAutoConfiguration“@import”的DeferredimportSelector实现类,由于DeferredimportSelector作为importSelector的子接口,所以组件自动配置逻辑均在selectimports(Annotationmetadata)方法中实现

源码分析:  

AutoConfigurationimportSelector.java

根据以上代码分析自动配置加载过程主要分为以下几个步骤:

1.判断是否开启自动配置

2.从meta-INF/spring-autoconfigure-metadata.properties文件中载入属性配置

3.获取所有的配置列表

public String[] selectimports(Annotationmetadata annotationmetadata) {
    //1.是否开启自动配置,默认开启
  if (!this.isEnabled(annotationmetadata)) {
    return NO_importS;
  } else {
    try {
        //2.从meta-INF/spring-autoconfigure-metadata.properties文件中载入属性配置(有一些有默认值),获取注解信息

      AutoConfigurationmetadata autoConfigurationmetadata = AutoConfigurationmetadataLoader.loadmetadata(this.beanClassLoader);
       
       //3.获取所有的配置列表
      AnnotationAttributes attributes = this.getAttributes(annotationmetadata);
      List configurations = this.getCandidateConfigurations(annotationmetadata, attributes);
      configurations = this.removeDuplicates(configurations);
      configurations = this.sort(configurations, autoConfigurationmetadata);
      Set exclusions = this.getExclusions(annotationmetadata, attributes);
      this.checkExcludedClasses(configurations, exclusions);
      configurations.removeAll(exclusions);
      configurations = this.filter(configurations, autoConfigurationmetadata);
      this.fireAutoConfigurationimportEvents(configurations, exclusions);
      return (String[])configurations.toArray(new String[configurations.size()]);
    } catch (IOException var6) {
      throw new IllegalStateException(var6);
    }
  }
}

1.是否开启自动配置,默认开启

 protected boolean isEnabled(Annotationmetadata metadata) {
    return true;
  }

2.从meta-INF/spring-autoconfigure-metadata.properties文件中载入属性配置

protected static final String PATH = "meta-INF/spring-autoconfigure-metadata.properties";

  private AutoConfigurationmetadataLoader() {
  }

  public static AutoConfigurationmetadata loadmetadata(ClassLoader classLoader) {
    return loadmetadata(classLoader, "meta-INF/spring-autoconfigure-metadata.properties");
  }
  static AutoConfigurationmetadata loadmetadata(ClassLoader classLoader, String path) {
    try {
      Enumeration urls = classLoader != null ? classLoader.getResources(path) : ClassLoader.getSystemResources(path);
      Properties properties = new Properties();
      while(urls.hasMoreElements()) {
 properties.putAll(PropertiesLoaderUtils.loadProperties(new UrlResource((URL)urls.nextElement())));
      }
      return loadmetadata(properties);
    } catch (IOException var4) {
      throw new IllegalArgumentException("Unable to load @ConditionalOnClass location [" + path + "]", var4);
    }
  }

3、获取所有的配置列表

protected AnnotationAttributes getAttributes(Annotationmetadata metadata) {
    String name = this.getAnnotationClass().getName();
    AnnotationAttributes attributes = AnnotationAttributes.fromMap(metadata.getAnnotationAttributes(name, true));
    Assert.notNull(attributes, "No auto-configuration attributes found. Is " + metadata.getClassName() + " annotated with " + ClassUtils.getShortName(name) + "?");
    return attributes;
  }

总结:

springboot底层实现自动配置的步骤:

1.springboot应用启动

2.@SpringBootApplication起作用

3.@EnableAutoConfiguration

4.@AutoConfigurationPackage:这个组合注解主要是@import(AutoConfigurationPackages.Registrar.class),它通过将Registrar类导入到容器中,而Registrar类作用是扫描主配置类同级目录以及子包,并将相应的组件导入到springboot创建管理的容器中

5.@import(AutoConfigurationimportSelector.class):它通过将AutoConfigurationimportSelector类导入到容器中,AutoConfigurationimportSelector类作用是通过selectimports方法实现将配置类信息交给SpringFactory加载器进行一系列的容器创建过程,具体实现可查看上面的源码

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持考高分网。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/133776.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号