build anything with spring boot:spring boot is the starting point for building all spring-based applications. spring boot is designed to get you up and running as quickly as possible, with minimal upfront configuration of spring.
上面是引自官网的一段话,大概是说: spring boot 是所有基于 spring 开发的项目的起点。spring boot 的设计是为了让你尽可能快的跑起来 spring 应用程序并且尽可能减少你的配置文件。
回顾我们之前的 ssm 项目,搭建过程还是比较繁琐的,需要:
而使用 spring boot 来开发项目则只需要非常少的几个配置就可以搭建起来一个 web 项目,并且利用 idea 可以自动生成生成
<?xml version="1.0" encoding="utf-8"?> <project xmlns="http://maven.apache.org/pom/4.0.0" xmlns:xsi="http://www.w3.org/2001/xmlschema-instance" xsi:schemalocation="http://maven.apache.org/pom/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelversion>4.0.0</modelversion> <groupid>cn.chenhao</groupid> <artifactid>springboot</artifactid> <version>1.0.0-snapshot</version> <packaging>jar</packaging> <name>springboot</name> <description>demo project for spring boot</description> <parent> <groupid>org.springframework.boot</groupid> <artifactid>spring-boot-starter-parent</artifactid> <version>2.0.1.release</version> <relativepath/> </parent> <dependencies> <dependency> <groupid>org.springframework.boot</groupid> <artifactid>spring-boot-starter-web</artifactid> </dependency> </dependencies> <build> <plugins> <plugin> <groupid>org.springframework.boot</groupid> <artifactid>spring-boot-maven-plugin</artifactid> </plugin> </plugins> </build> </project>
/** * @springbootapplication来标注一个主程序类,说明这是一个springboot应用 */ @springbootapplication public class helloworldmainapplication { public static void main(string[] args) { //spring应用启动 springapplication.run(helloworldmainapplication.class, args); } }
@restcontroller public class hellocontroller { @requestmapping("/hello") public string hello(){ return "hello world"; } }
使用maven打包命令将其打包成jar包后,直接使用命令:
java -jar xxx.jar
<parent> <groupid>org.springframework.boot</groupid> <artifactid>spring-boot-starter-parent</artifactid> <version>2.0.1.release</version> <relativepath/> </parent>
其父项目是
<parent> <groupid>org.springframework.boot</groupid> <artifactid>spring-boot-dependencies</artifactid> <version>2.0.1.release</version> <relativepath>../../spring-boot-dependencies</relativepath> </parent>
该父项目是真正管理spring boot应用里面的所有依赖的版本:spring boot的版本仲裁中心,所以以后导入的依赖默认是不需要版本号。如下
还有很多版本号没有截图出来
<dependency> <groupid>org.springframework.boot</groupid> <artifactid>spring-boot-starter-web</artifactid> </dependency>
spring-boot-starter : spring boot场景启动器;帮助导入web模块正常运行所依赖的组件;
spring boot将所有的功能场景抽取出来,做成一个个的starter(启动器),只需要在项目中引入这些starter,那么相关的场景的所有依赖都会导入进项目中。要用什么功能就导入什么场景的启动器。
<dependency> <groupid>org.springframework.boot</groupid> <artifactid>spring-boot-starter-tomcat</artifactid> </dependency> <dependency> <groupid>org.springframework</groupid> <artifactid>spring-web</artifactid> </dependency> <dependency> <groupid>org.springframework</groupid> <artifactid>spring-webmvc</artifactid> </dependency>
添加了 spring-boot-starter-web 依赖,会自动添加 tomcat 和 spring mvc 的依赖
spring-boot-starter-web中又引入了spring-boot-starter-tomcat
@springbootapplication public class helloworldmainapplication { public static void main(string[] args) { //spring应用启动 springapplication.run(helloworldmainapplication.class, args); } }
@springbootapplication
注解定义如下:
@springbootconfiguration @enableautoconfiguration @componentscan(excludefilters = { @filter(type = filtertype.custom, classes = typeexcludefilter.class), @filter(type = filtertype.custom, classes = autoconfigurationexcludefilter.class) }) public @interface springbootapplication {}
@springbootconfiguration
注解定义如下:
@configuration public @interface springbootconfiguration {}
其实就是一个configuration配置类,意思是helloworldmainapplication最终会被注册到spring容器中
注解定义如下:
@autoconfigurationpackage @import(enableautoconfigurationimportselector.class) public @interface enableautoconfiguration {}
@autoconfigurationpackage
@import(autoconfigurationpackages.registrar.class) public @interface autoconfigurationpackage {}
@order(ordered.highest_precedence) static class registrar implements importbeandefinitionregistrar, determinableimports { @override public void registerbeandefinitions(annotationmetadata metadata, beandefinitionregistry registry) { //默认将会扫描@springbootapplication标注的主配置类所在的包及其子包下所有组件 register(registry, new packageimport(metadata).getpackagename()); } @override public set<object> determineimports(annotationmetadata metadata) { return collections.<object>singleton(new packageimport(metadata)); } }
@import(enableautoconfigurationimportselector.class)
enableautoconfigurationimportselector: 导入哪些组件的选择器,将所有需要导入的组件以全类名的方式返回,这些组件就会被添加到容器中。
1 //enableautoconfigurationimportselector的父类:autoconfigurationimportselector 2 @override 3 public string[] selectimports(annotationmetadata annotationmetadata) { 4 if (!isenabled(annotationmetadata)) { 5 return no_imports; 6 } 7 try { 8 autoconfigurationmetadata autoconfigurationmetadata = autoconfigurationmetadataloader 9 .loadmetadata(this.beanclassloader); 10 annotationattributes attributes = getattributes(annotationmetadata); 11 list<string> configurations = getcandidateconfigurations(annotationmetadata, attributes); 12 configurations = removeduplicates(configurations); 13 configurations = sort(configurations, autoconfigurationmetadata); 14 set<string> exclusions = getexclusions(annotationmetadata, attributes); 15 checkexcludedclasses(configurations, exclusions); 16 configurations.removeall(exclusions); 17 configurations = filter(configurations, autoconfigurationmetadata); 18 fireautoconfigurationimportevents(configurations, exclusions); 19 return configurations.toarray(new string[configurations.size()]); 20 } 21 catch (ioexception ex) { 22 throw new illegalstateexception(ex); 23 } 24 }
我们主要看第11行list<string> configurations = getcandidateconfigurations(annotationmetadata, attributes);
会给容器中注入众多的自动配置类(xxxautoconfiguration),就是给容器中导入这个场景需要的所有组件,并配置好这些组件。我们跟进去看看
protected list<string> getcandidateconfigurations(annotationmetadata metadata, annotationattributes attributes) { list<string> configurations = springfactoriesloader.loadfactorynames( getspringfactoriesloaderfactoryclass(), getbeanclassloader()); //... return configurations; } protected class<?> getspringfactoriesloaderfactoryclass() { return enableautoconfiguration.class; } public static final string factories_resource_location = "meta-inf/spring.factories"; public static list<string> loadfactorynames(class<?> factoryclass, classloader classloader) { string factoryclassname = factoryclass.getname(); try { //从类路径的meta-inf/spring.factories中加载所有默认的自动配置类 enumeration<url> urls = (classloader != null ? classloader.getresources(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)); //获取enableautoconfiguration指定的所有值,也就是enableautoconfiguration.class的值 string factoryclassnames = properties.getproperty(factoryclassname); result.addall(arrays.aslist(stringutils.commadelimitedlisttostringarray(factoryclassnames))); } return result; } catch (ioexception ex) { throw new illegalargumentexception("unable to load [" + factoryclass.getname() + "] factories from location [" + factories_resource_location + "]", ex); } }
最终有96个自动配置类被加载并注册进spring容器中
j2ee的整体整合解决方案和自动配置都在spring-boot-autoconfigure-xxx.jar中。在这些自动配置类中会通过@conditionalonclass等条件注解判断是否导入了某些依赖包,从而通过@bean注册相应的对象进行自动配置。后面我们会有单独文章讲自动配置的内容
如对本文有疑问, 点击进行留言回复!!
[RK3399][Android7.1.1] Ethernet:异常断电导致ip设置没有保存的问题
Android的handler基本使用以及做一个简单进度条和轮播图以及子线程中用handler
荐 U3D调用AndroidStudio3.5(附测试工程)
网友评论