使用maven创建Springboot项目:
导入依赖jar包
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.6.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
编写代码
- 编写一个主程序类
- 主程序类需要使用@SpringBootApplication来进行标注
package com.yu;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* @Description: TODO
* @Author : yu
* Date : 4/3/2020 12:40 AM
*/
@SpringBootApplication
public class HelloWorldMainApplication {
public static void main(String[] args) {
//启动spring应用的入口
SpringApplication.run(HelloWorldMainApplication.class, args);
}
}
3、编写业务逻辑代码(需要在与springboot主程序类的同级及子包下)
package com.yu.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @Description: TODO
* @Author : yu
* Date : 4/3/2020 12:45 AM
*/
@RestController
public class HelloController {
@RequestMapping("/hello")
public String hello(){
return "hello,springboot!";
}
}
4、直接执行应用主程序
我们不需要配置tomcat等等配置,因为tomcat是内嵌在里面的,也不需要做Springmvc里面的视图解析器等等都不需要我们配置,所以说springboot简化了我们的开发。
5、添加一个可以打包springboot的插件
可以打包成一个可运行的jar包
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
6、打jar包
使用maven中的package
然后会在target目录下生成一个jar包
HelloWorld深究
1、父项目
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.6.RELEASE</version>
</parent>
<!--点进去会发现这个父项目还依赖一个父项目-->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.2.6.RELEASE</version>
<relativePath>../../spring-boot-dependencies</relativePath>
</parent>
<!--这个是真正管理springboot应用的所有依赖版本的-->
在dependencies项目是springboot版本仲裁中心;
在这个dependencies里面设置了大部分我们常用的包的版本,所以我们后续一些常用的包导进来就不需要选择版本了,springboot会自动给我们选择版本。但是一些没有在dependencies声明的包的版本仍然还是需要我们进行配置。
2、导入的依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
spring-boot-starter-web:
spring-boot-starter-web:Springboot场景启动器,帮我们导入了相关的所有依赖
3、拓展
springboot中不止这一个启动器,还有很多启动器,在官方文档中有声明https://docs.spring.io/spring-boot/docs/2.2.6.RELEASE/reference/html/using-spring-boot.html#using-boot-starter
Springboot将所有的功能场景都抽取出来,做成一个个启动器,可以看成一个场景所需要的所有依赖全部都会导入进来,而且在springboot中还对版本进行了选择。
HelloWorld主程序探究
为什么我们不需要去配置tomcat,还有各种配置文件?而这个主程序比普通的java类多的仅仅是一个注解类,为什么可以实现这么多功能呢?
那么这个注解有什么特别的?
我们通过阅读源码可以得到解答。
package com.yu;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* @Description: TODO
* @Author : yu
* Date : 4/3/2020 12:40 AM
*/
@SpringBootApplication
public class HelloWorldMainApplication {
public static void main(String[] args) {
//启动spring应用的入口
SpringApplication.run(HelloWorldMainApplication.class, args);
}
}
@SpringBootApplication:springboot用用标注在某个类上说明这个类是springboot的配置类,springboot就应该运行这个类来运行springboot程序
@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) })
@SpringBootConfiguration:springboot的配置类:
标注在某个类上,表示这个是springboot的配置类,我们进入到SpringBootConfiguration就可以看到下面的内容:
@Target(ElementType.TYPE) //注解作用在类上
@Retention(RetentionPolicy.RUNTIME)// 注解不仅被保存到class文件中,jvm加载class文件之后,仍然存在
@Documented //Java的元注解,表示这个类被javadoc工具记录
@Configuration //配置类
可以看到@Configuration这个注解,之前在Spring中则是用这个注解来标注一个配置类,是一个组件,交给spring托管
@SpringBootApplication的另一个重要的注解:@EnableAutoConfiguration
作用:开启自动配置功能:
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited //表示该注解会被子类继承
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
告诉springboot开启自动配置功能,我们就无须进行繁琐的配置编写了,这个也就是springboot之所以能够简化我们的开发的主要原因,替我们进行的配置。
@EnableAutoConfiguration里面的另一个注解:@AutoConfigurationPackage
作用:自动配置包
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Import(AutoConfigurationPackages.Registrar.class) //将对应的类注册到容器中,名字是全类名
Spring的底层注解@Import给容器导入组件,导入的组件由AutoConfigurationPackages.Registrar.class,这个也是和xml版对应的,我们在配置文件中使用import将所有配置文件整合到一起
我们打到这个自动导入包的源文件中,给这个登录方法打上断点,进行计算
我们可以看到这个metadata源信息是在springboot主程序类
new PackageImport(metadata).getPackageName()
//这个是将入口所在的所有包及其子包都扫进来
这个可以看到结果
这也是为什么我们的包只有和主程序类在同一目录下才能被扫描的到的原因。
所以@AutoConfigurationPackage作用是将主入口所在的包及子包的所有组件扫描到Spring容器中。
@Import(AutoConfigurationImportSelector.class)
给容器中导入组件
AutoConfigurationImportSelector:导入哪些组件的选择器
将所有的组件以全类名的方式返回,这个组件会添加到容器中,我们可以看到这个类里面有一个
public String[] selectImports(AnnotationMetadata annotationMetadata) {
if (!isEnabled(annotationMetadata)) {
return NO_IMPORTS;
}
AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader
.loadMetadata(this.beanClassLoader);
AutoConfigurationEntry autoConfigurationEntry = getAutoConfigurationEntry(autoConfigurationMetadata,
annotationMetadata);
return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
}
这里返回的就是我们选择注入的类的全类名的集合。
会给容器导入非常多的自动配置类(xxxAutoConfiguration);就是给容器导入这个场景所需要的所有组件,并配置好这个组件。
我们在这个方法这里打上断点,就可以看到我们会选择自动导入的组件。
有了自动配置类,减免了我们手动编写注入功能组件等功能
对应的配置文件在这里:
将这些值作为自动配置类导入到容器中,自动配置类就生效了。然后就可以帮我们进行自动配置工作了。以前我们需要自己配置的东西,仍然需要配置,只是springboot帮我们配置了
另一种创建springboot的项目
可以使用idea直接创建项目,或者到https://start.spring.io/创建项目然后使用idea打开。