Spring Boot的“开箱即用”的原则,使得企业应用开发中各种场景的Spring开发更加快速,更加高效,由于配置大量减少,开发效率相得益彰。

  启动原理:SpringBoot项目会有一个启动类,这个启动类会使用@SpringBootApplication声明。

下面是@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, attribute = "exclude")Class<?>[] exclude() default{};@AliasFor(annotation = EnableAutoConfiguration.class, attribute = "excludeName")String[] excludeName() default{};@AliasFor(annotation = EnableAutoConfiguration.class, attribute = "scanBasePackageClasses")Class<?>[] scanBasePackageClasses() default{};
}

@SpringbootApplication其实是一个组合注解,注意高亮的三个注解:

  @EnableAutoConfiguration:启动注解,该注解会让SpringBoot根据当前项目所依赖的jar包自动配置到项目中;

  @ComponentScan:自动扫描,SpringBoot默认会扫描@SpringbootApplication所在类的同级包,以及它的子包,因此建议将@SpringbootApplication修饰的入口类放在项目包(Group Id + Artifact Id)下,这样可以保证SpringBoot项目可以自动扫描所有依赖的包;

  @SpringBootConfiguration:源码如下:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Configuration
public @interface SpringBootConfiguration{}

@SpringBootConfiguration其实又是一个组合注解,注意又一个高亮注解:@Configuration,

  使用@Configuration声明的类,这个类就相当于一个xml配置文件。这样就容易理解了,我们使用Spring,springMVC时都会使用xml配置文件去加载相关依赖jar包的类,而SpringBoot使用@SpringBootConfiguration(推荐使用,来代替@Configuration),然后自动扫描(@ComponentScan),自动配置(@EnableAutoConfiguration)。

  下面就来讲述其自动配置原理:

  上面讲到一个使用了@SpringBootApplication声明的项目启动类,这个启动类有一个main方法,是程序的入口,main方法下面会创建SpringApplication类的run()方法(即SpringApplication.run(App.class,args),App.class是项目启动类)

run()方法源码:

public static ConfigurableApplicationContext run(Object[] sources, String[] args){return new SpringApplication(sources).run(args);
}

  可以看到,run方法实际上是创建SpringApplication实例,然后又调用run方法,重点在于创建SpringApplication对象,下面是SpringApplication的构造方法源码:

public SpringApplication(Object... sources){initialize(sources);
}

  以启动类作为参数,调用初始化方法initialize(sources),initialize(sources)源码:

@SuppressWarnings({"unchecked", "rawtypes"})
private void initialize(Object[] sources){if(sources != null && sources.length>0){this.sources.addAll(Arrays.asList(sources));}...setListeners(Collection) getSpringFactoriesInstances(ApplicationListener.class);...
}

其他源码不是这里的重点,关注高亮代码,接着再进入getSpringFactoriesInstances方法的源码:

private <T> Collection<? extends T> getSpringFactoriesInstances(Class<T> type, Class<?>[] parameterTypes, Object... args){ClassLoader classLoader = Thread.currentThread().getContextClassLoader();Set<String> names = new LinkedHashSet<String>(SpringFactoriesLoader.loadFactoryNames(type, classLoader));...
}

再进入SpringFactoriesLoader的loadFactoryNames方法的源码:

public static List<String> loadFactoryNames(Class<?> factoryClass, ClassLoader classLoader){String factoryClassName = factoryClass.getName();try{Enumeration<URL> urls = (classLoader != null ? classLoader.getSources(FACTORIES_RESOURCE_LOCATION) : ClassLoader.getSystemResources(FACTORIES_RESOURCE_LOCATION));List<String> result = new ArrayList<String>();while(urls.hasMoreElements()){URL url = urls.nextElement();Properties properties = PropertiesLoaderUtils.loadProperties(new UrlResource(url));String factoryClassNames = properties.getProperty(factoryClassName);result.addAll(Arrays.asList(StringUtils.commaDelimitedListToStringArray(factoryClassName)));}return result;}catch (IOException ex){throw new IllegalArgumentException("Unable to load ["+factoryClass.getName() + "]", ex);}
}        

上面源码用到了一个常量:FACTORIES_RESOURCE_LOCATION,这个常量源码如下:

public static final String FACTORIES_RESOURCE_LOCATION = "META-INF/spring.factories";

到目前为止,已经知道是怎样的了,最终SpringBoot是通过加载META-INF/spring.factories文件进行自动配置,这个文件是放在spring-boot-autoconfigure包下面的META-INF/spring.factories,该 文件时官方文件,里面写了很多相关类名,供其扫描,自动配置。譬如spring.factories文件下面有一行代码,这行代码是一个配置类的类名,叫做org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration,它会根据这个全路径类名,找到这个类,进行加载。

可以看一下org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration的源代码:

@Configuration
@ConditionalOnWebApplication
@ConditionOnClass({Servlet.class, DispatcherServlet.class, WebMvcConfigurerAdapter.class})
@ConditionalOnMissingBean(WebMvcConfigurationSupport.class)
@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE + 10)
@AutoConfigureAfter({DispatcherServletAutoConfiguration.class, ValidationAutoConfiguration.class})
public class WebMvcAutoConfiguration{...
}

  一开始也讲过了,使用了@Configuration的类,相当于一个xml文件,@ContionalOnClass是一个条件注解,意思是只有当当前项目运行环境中有Servlet类,并且有DispatcherServlet类,以及WebMvcConfigurerAdapter类,SpringBoot才会初始化加载这个类,说白了这个类,就相当于spring-servlet.xml文件。既然是spring-servlet.xml文件,那么肯定也会找到很多<bean/>配置类,这里拿视图配置类InternalResourceViewResolver,举个例子,

  在spring-servlet.xml文件里面,我们通常是这样配置声明InternalResourceViewResolver的:

<bean id="jspViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"><property name="prefix" value="/WEB-INF/view"/><property name="suffix" value=".jsp"/>
</bean>

  到了WebMvcAutoConfiguration类,下面可以找到一个defaultViewResolver方法,可以看一下源码:

@Bean
@ContionalOnMissingBean
public InternalResourceViewResolver defaultViewResolver(){InternalResourceViewResolver resolver = new InternalResourceViewResolver();resolver.setPrefix(this.mvcProperties.getView().getPrefix());resolver.setSuffix(this.mvcProperties.getView().getSuffix());return resolver;
}

@Bean,其实就相当于<bean/>标签,defaultViewResolver方法得返回值类型就是InternalResourceViewResolver类,里面的代码就是负责创建InternalResourceViewResolver对象,前后对比一下,清晰了很多,SpringBoot就是把Spring技术的配置换成了加载类,直接封装起来。这里有个问题,prefix和suffix的值怎么确定呢?很简单,就是到application.properties配置,对于springboot2.x,配置信息如下:

spring.mvc.view.prefix = /WEB-INF/view
spring.mvc.view.suffix= .jsp

  总结:自动配置原理:从classpath中搜寻所有的META-INF/spring.factories配置文件,并将其中org.springframework.boot.autoconfigure.EnableAutoConfiguration对应的配置项,通过反射机制实例化为IOC容器配置类(这些配置类都是使用了@Configuration注解声明的),然后汇总并加载到Spring框架的IOC容器。

转载于:https://www.cnblogs.com/SysoCjs/p/9781764.html

Spring Boot的自动装配原理相关推荐

  1. Spring Boot(一) 自动装配--约定大于配置

    欢迎去我的个人博客--晓坞坐坐,里面有很多有趣的文章,不止是技术.www.lixiaodongisme.com 随着spring体系的发展,我们在开发时需要配置整合的东西也越来越多,在进行开发时,繁琐 ...

  2. Spring Boot—SpringMVC自动配置原理以及扩展和全面接管SpringMVC

    文章目录 1.以下是SpringBoot对SpringMVC的默认配置 2.扩展SpringMVC 3.全面接管SpringMVC: 5.如何修改SpringBoot的默认配置 Spring MVC ...

  3. Spring Boot中自动配置原理以及日志的基本使用

    目录 自动配置原理 日志的基本使用 自动配置原理 自动配置原理: 1. Spring Boot启动时加载主配置类,开启了知道配置功能@EnableAutoConfiguration. 2. @Enab ...

  4. 【源码阅读】看Spring Boot如何自动装配ActiveMQ收发组件

    源于好奇,我研究了一下Spring Boot中ActiveMQ相关组件是如何自动装配的.记录如下. 源码路径 本文以Spring Boot 1.5.10.RELEASE版本为例. 在spring-bo ...

  5. 原理解析_SpringBoot自动装配原理解析

    自动装配是Spring Boot的核心部分,也是Spring Boot功能的基础,正是由于自动装配,才将我们从Bean的繁复配置中解脱出来.那么Spring Boot中的自动装配指的是什么?我们继 续 ...

  6. SpringBoot之自动装配原理

    1. 自动装配的使用 Spring Boot的核心理念是简化Spring应用的搭建和开发过程,提出了约定大于配置和自动装配的思想.开发Spring项目通常要配置xml文件,当项目变得复杂的时候,xml ...

  7. Spring Boot自动装配原理详解

    目录 1.环境和依赖 1.1.spring boot版本 1.2.依赖管理 2.自动装配 2.1.流程概述 2.2.三大步前的准备工作 2.2.1.注解入口 2.2.2.获取所有配置类 2.3.获取过 ...

  8. Spring自动装配原理理解

    Spring本质上就是一个管理程序应用的容器,而spring的一个核心功能就是自动装配,也就是在程序启动时就自动将应用所需的所有bean自动扫描.配置和装入到容器中去,方便程序的使用. 什么是Spri ...

  9. spring自动装配原理

    为了搞明白自动装配原理,需要知道spring容器管理bean的生命周期 Spring Bean 生命周期流程图 bean自身方法的生命周期 分为四步: //执行此段代码,spring容器的bean执行 ...

最新文章

  1. ShardedJedis 错误使用
  2. 安卓linux定时执行脚本,Android开机自动执行shell脚本
  3. Excel 设定密码保护特定的内容
  4. 【完结】 12篇文章带你完全进入NLP领域,掌握核心技术
  5. BAP 使用DYNP_VALUES_READ来获取屏幕字段值
  6. 前端学习(1388):多人管理项目8user登录
  7. OpenCV3学习(3)——视频文件的读取与写入
  8. SpringBoot Serverless 实战 | 监控调试
  9. 服务器更换主板后系统无法启动
  10. SignalTap II里面Power-Up Trigger的使用
  11. 在微型计算机中1G标准等于,微型计算机的基础知识概要.ppt
  12. Java速成系列-02-Java的版本
  13. 过来康康,一起来学VScode插件
  14. 铁道部售票网站怎么啦?
  15. 【Neo4j × 知识图谱】图形化数据库基本操作: 创建节点与关系、添加属性、查询节点 | 附:可视化 构建四大名著 知识图谱(含源代码)| word2vec实战: 构造斗罗大陆人物关系
  16. 2019年全套web前端视频教程链接分享
  17. java基础(个人笔记)
  18. 楼宇系统服务器,【产品介绍】楼宇管理平台
  19. 牛客刷题——Python入门总结
  20. python编程的就业方向_2021年python编程就业方向是怎样的?

热门文章

  1. 遍历目录下的所有文件-os.walk
  2. Oracle入门教程,新手必读
  3. ASPTODLL风火轮
  4. Etcd服务发现原理
  5. 解决Node.js 运行的时候出现中文乱码问题
  6. 零基础带你学习MySQL—Select语句以及注意事项(十)
  7. 【PHP学习】—PHP连接数据库实现表单页面的验证功能(七)
  8. 删除桌面图标的小箭头
  9. 拍人像的时候你喜欢哪种模特?
  10. 注册制后st还有投资价值吗?