Springboot---学习过程---Springboot运行原理初探

Springboot—学习过程—Springboot的自动装配原理探索

1.通过POM文件可以看到什么

  1. 它是依赖一个父项目,主要是管理项目的资源过滤及插件!

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.5.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    
    资源过滤:在这里插入图片描述

    插件:(飘红的见笑了,看一下就好,嘿嘿)
    在这里插入图片描述

  2. 点击spring-boot-starter-parent发现里面还有一个父依赖

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-dependencies</artifactId>
        <version>2.2.5.RELEASE</version>
        <relativePath>../../spring-boot-dependencies</relativePath>
    </parent>
    
    1. spring-boot-dependencies才是真正管理SpringBoot应用里面所有依赖版本的地方,是SpringBoot的版本控制中心,里面全是版本信息;以后我们导入依赖默认是不需要写版本;如果导入的包没有在依赖中管理着就需要手动配置版本了;
    2. 所以说我们在引入springboot的版本依赖的时候不需要指定版本,因为有这些版本仓库
      在这里插入图片描述

2.通过POM文件中的启动器看

  1. 启动器:springboot-boot-starter-xxx,就是springboot的xxx启动场景
    <!--启动器-->
    <dependency>
    	   <groupId>org.springframework.boot</groupId>
    	   <artifactId>spring-boot-starter</artifactId>
    </dependency>
    
    举个例子: spring-boot-starter-web启动器就会帮我们自动导入web环境所有的依赖
    注: SpringBoot将所有的功能场景都抽取出来,做成一个个的starter (启动器),只需要在项目中引入这些starter即可,所有相关的依赖都会导入进来 , 我们要用什么功能就导入什么样的场景启动器即可 ;我们未来也可以自己自定义 starter;
    <dependency>
       <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    

3.通过主启动类看

  1. 查看表面
    1. 通过 @SpringBootApplication 注解标注一个主程序类,说明这是一个Spring Boot应用
    //通过 @SpringBootApplication 注解标注一个主程序类,说明这是一个Spring Boot应用,而且继承了@EnableAutoConfiguration所以是启动类下的所有资源都被导入
    
    @SpringBootApplication
    public class SpringbootApplication {
       public static void main(String[] args) {
         //以为是启动了一个方法,其实是启动了一个服务,将springboot应用启动
          SpringApplication.run(SpringbootApplication.class, args);
       }
    
    }
    
  2. 查看注解
    1. 点击@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} ) } )
      这个是扫描剔除包的

    2. @SpringBootConfigurationSpringboot的配置类,标注在某个类上 , 表示这是一个SpringBoot的配置类

      1. 点击@SpringBootConfiguration注解发现里面有@Configuration这个注解,表示是spring的配置类
        @Target({ElementType.TYPE})
        @Retention(RetentionPolicy.RUNTIME)
        @Documented
        @Configuration
        public @interface SpringBootConfiguration { . . .}
        
      2. 点击@Configuration这个注解,发现里面还有一个注解@Component,说明这也是Spring中的一个组件而已,启动类本身也是Spring中的一个组件而已,负责启动应用
        	@Target({ElementType.TYPE})
        	@Retention(RetentionPolicy.RUNTIME)
        	@Documented
        	@Component
        	public @interface Configuration { . . . }
        
    3. @EnableAutoConfiguration:自动配置

      1. 点击@EnableAutoConfiguration注解可以看到有一个注解@AutoConfigurationPackage

      2. @AutoConfigurationPackage自动配置包的意思,点击这个@AutoConfigurationPackage注解后发现另一个注解@Import(AutoConfigurationPackages.Registrar.class)导入“选择器”包注册器,之后查看AutoConfigurationPackages的内容是一个类文件.java结尾的,作用是将主启动类的所在包及包下面所有子包里面的所有组件扫描到Spring容器

      3. @Import(AutoConfigurationImportSelector.class)注解,这个注解意思是:导入自动配置导入选择器的类,点击AutoConfigurationImportSelector这个类进去一看,可以看到导入了环境,资源加载器

        //环境
        private Environment environment;
        
        private ClassLoader beanClassLoader;
        //资源加载器
        private ResourceLoader resourceLoader;
        
        选择组件的方法:选择组件是干嘛的,是要选择配置在pom.xml文件中的东西,因为不导入进来就是用不了,所以真正选择的是pom.xml文件中的组件
        public String[] selectImports(AnnotationMetadata annotationMetadata) {
        	if (!isEnabled(annotationMetadata)) {
        		return NO_IMPORTS;
        	}
        	AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader
        			//loadMetadata表示加载源数据
        			.loadMetadata(this.beanClassLoader);
        	AutoConfigurationEntry autoConfigurationEntry = getAutoConfigurationEntry(autoConfigurationMetadata,
        			annotationMetadata);
        	return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
        }
        

        顺着代码在下一个方法中:发现List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes);是获取所有的配置

        protected AutoConfigurationEntry getAutoConfigurationEntry(AutoConfigurationMetadata autoConfigurationMetadata,
        		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 = filter(configurations, autoConfigurationMetadata);
        	fireAutoConfigurationImportEvents(configurations, exclusions);
        	return new AutoConfigurationEntry(configurations, exclusions);
        }
        
        之后点击查看 getCandidateConfigurations 方法 这个是获取候选配置的方法
        protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
        									//通过一个加载器加载所有的
        	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;
        }
        
        之后点击查看 getBeanClassLoader 方法 ,beanClassLoader也是一个加载器
        protected ClassLoader getBeanClassLoader() {
        	return this.beanClassLoader;
        }
        
        之后点击查看 getSpringFactoriesLoaderFactoryClass() 方法 ,他作为参数在 getBeanClassLoader()方法前面,这个方法返回了EnableAutoConfiguration.class,也就是EnableAutoConfiguration类的所有包和所有配置
        protected Class<?> getSpringFactoriesLoaderFactoryClass() {
        		return EnableAutoConfiguration.class;
        	}
        
        继续往下看有个Assert.notEmpty ,这是断言 非空的意思,其中有一个META-INF/spring.factories,这个是自动配置的核心文件,如下图
        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.");
        

        在这里插入图片描述
        点开spring.factories文件发现有好多配置
        在这里插入图片描述
        这时候在通过方法loadFactoryNames( )查找,点击这个方法

        public static List<String> loadFactoryNames(Class<?> factoryType, @Nullable ClassLoader classLoader) {
            String factoryTypeName = factoryType.getName();
            return (List)loadSpringFactories(classLoader).getOrDefault(factoryTypeName, Collections.emptyList());
        }
        

        loadFactoryNames这个方法在SpringFactoriesLoader.class这个类中,看第一个参数factoryType了解到加载了一个类,是标注了@SpringbootAPPlication这样的一个类
        在这里插入图片描述
        上图中:

        //所有资源加载到配置类中
        Properties properties = PropertiesLoaderUtils.loadProperties(resource);
        

结论:

  1. SpringBoot在启动的时候从类路径下的META-INF/spring.factories中获取EnableAutoConfiguration指定的值

  2. 将这些值作为自动配置类导入容器 , 自动配置类就生效 , 帮我们进行自动配置工作;

  3. 整个J2EE的整体解决方案和自动配置都在springboot-autoconfigure的jar包中;

  4. 它会给容器中导入非常多的自动配置类 (xxxAutoConfiguration), 就是给容器中导入这个场景需要的所有组件 , 并配置好这些组件 ;

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

梳理过程的不完全截图,看起来估计费劲

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
数字乡村和智慧农业的数字化转型是当前农业发展的新趋势,旨在通过应用数字技术,实现农业全流程的再造和全生命周期的管理服务。中国政府高度重视这一领域的发展,提出“数字中国”和“乡村振兴”战略,以提升国家治理能力,推动城乡融合发展。 数字乡村的建设面临乡村治理、基础设施、产业链条和公共服务等方面的问题,需要分阶段实施《数字乡村发展战略纲要》来解决。农业数字化转型的需求包括满足市民对优质农产品的需求、解决产销对接问题、形成优质优价机制、提高农业劳动力素质、打破信息孤岛、提高农业政策服务的精准度和有效性,以及解决农业融资难的问题。 数字乡村建设的关键在于构建“1+3+4+1”工程,即以新技术、新要素、新商业、新农民、新文化、新农村为核心,推进数据融合,强化农业大数据的汇集功能。数字农业大数据解决方案以农业数字底图和数据资源为基础,通过可视化监管,实现区域农业的全面数字化管理。 数字农业大数据架构基于大数据、区块链、GIS和物联网技术,构建农业大数据中心、农业物联网平台和农村综合服务指挥决策平台三大基础平台。农业大数据中心汇聚各类涉农信息资源和业务数据,支持大数据应用。信息采集系统覆盖市、县、乡、村多级,形成高效的农业大数据信息采集体系。 农业物联网平台包括环境监测系统、视频监控系统、预警预报系统和智能控制系统,通过收集和监测数据,实现对农业环境和生产过程的智能化管理。综合服务指挥决策平台利用数据分析和GIS技术,为农业决策提供支持。 数字乡村建设包括三大服务平台:治理服务平台、民生服务平台和产业服务平台。治理服务平台通过大数据和AI技术,实现乡村治理的数字化;民生服务平台利用互联网技术,提供各类民生服务;产业服务平台融合政企关系,支持农业产业发展。 数字乡村的应用场景广泛,包括农业生产过程、农产品流通、农业管理和农村社会服务。农业生产管理系统利用AIoT技术,实现农业生产的标准化和智能化。农产品智慧流通管理系统和溯源管理系统提高流通效率和产品追溯能力。智慧农业管理通过互联网+农业,提升农业管理的科学性和效率。农村社会服务则通过数字化手段,提高农村地区的公共服务水平。 总体而言,数字乡村和智慧农业的建设,不仅能够提升农业生产效率和管理水平,还能够促进农村地区的社会经济发展,实现城乡融合发展,是推动中国农业现代化的重要途径。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值