自己使用springboot也已经写过一段时间的代码,但是对springboot真正运行的流程还是有点模糊,今天写出自己对springboot的认识,如有不对,还请各位大佬不吝赐教,话不多说,直接上代码
工程的目录结构如下
pom文件如下:
<?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"> <groupId>com.rookie.bigdata</groupId> <version>1.0-SNAPSHOT</version> <modelVersion>4.0.0</modelVersion> <artifactId>springboot-helloworld</artifactId> <name>springboot-helloworld</name> <!-- FIXME change it to the project's website --> <url>http://www.example.com</url> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.0.5.RELEASE</version> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.target>1.8</maven.compiler.target> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> </dependencies> <build> </build> </project>
代码如下:
Application.java
package com.rookie.bigdata; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; /** * Created by on 2018/9/20. */ @SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } }
HelloController.java
package com.rookie.bigdata.web; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; /** * Created by on 2018/9/20. */ @RestController public class HelloController { @RequestMapping("/hello") public String home() { return "hello world"; } }
运行Application.java中的主类,访问localhost:8080/hello,出现如下界面表示成功
@SpringBootApplication注解是一个spring boot的一个重要注解,用来进行快速的启动,源码如下
@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 {
@SpringBootConfiguration标注在某个类上,表示这是一个Spring Boot的配置类。源码如下:
@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Configuration public @interface SpringBootConfiguration {
@EnableAutoConfiguratio 通知SpringBoot开启自动配置功能,这样自动配置才能生效。源码如下:
@Target(ElementType.TYPE)@Retention(RetentionPolicy.RUNTIME)@Documented@Inherited@AutoConfigurationPackage//根据条件来注册我们需要的bean实例,@Import注解支持导入普通的java类,并将其声明成一个bean.给容器中导入组件@Import(AutoConfigurationImportSelector.class)public @interface EnableAutoConfiguration {
@AutoConfigurationPackage 自动配置包注解,源码如下:
@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited //@Import(AutoConfigurationPackages.Registrar.class):默认将主配置类(@SpringBootApplication)所在的包及其子包里面的所有组件扫描到Spring容器中。 @Import(AutoConfigurationPackages.Registrar.class) public @interface AutoConfigurationPackage {
@Import(AutoConfigurationPackages.Registrar.class)注解源码如下:
/** * {@link ImportBeanDefinitionRegistrar} to store the base package from the importing * configuration. */ 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.singleton(new PackageImport(metadata)); } }
这样就明白了为什么Application这个类要在最外面的一层,是为了扫描@SpringBootApplication标注的主配置类所在的包及其子包下所有组件,并根据每个类上面的注解实例化为一个bean对象