3

spring boot入门程序搭建,可以分一下几个步骤:

  • 创建maven项目
  • 引入spring boot starter
  • 创建程序启动入口
  • 启动程序

pom.xml文件

<?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>com.sff.springboot.example</groupId>
    <artifactId>springboot</artifactId>
    <packaging>pom</packaging>
    <version>1.0-SNAPSHOT</version>
    <modules>
        <module>spring-boot-helloword</module>
    </modules>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.0.RELEASE</version>
    </parent>

    <!--web项目需要引入web starter-->
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>

    <!--可以将应用打包成一个可执行的jar包-->
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
    
</project>

启动程序入口

@SpringBootApplication
public class SpringBootMainHelloWorld {

    /**
     * spring boot启动程序入口
     *
     * @param args
     */
    public static void main(String[] args) {
        SpringApplication.run(SpringBootMainHelloWorld.class, args);
    }
}

@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 {
}

@SpringBootApplication 注解被 @SpringBootConfiguration ,@EnableAutoConfiguration 所标注。

  • @SpringBootConfiguration :表示是一个spring boot的配置类。
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Configuration
public @interface SpringBootConfiguration {
}

可以发现它是由 @Configuration 标注,所以是一个配置类。

  • @EnableAutoConfiguration: 告诉spring boot开启自动配置功能,怎么理解?以前进行spring web项目开发时我们需要配置 spring mvc等相关配置,但在spring boot中这些都可以让该注解实现。
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {
    String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";
}

(1)我们发现 @EnableAutoConfiguration 注解是由 @AutoConfigurationPackage 注解标注,那它的作用是什么呢?
@AutoConfigurationPackage : 自动配置包

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Import(AutoConfigurationPackages.Registrar.class)
public @interface AutoConfigurationPackage {
}

@AutoConfigurationPackage 注解的实现是由 @Import(AutoConfigurationPackages.Registrar.class) 标注的,意思是:给容器中导入一个 AutoConfigurationPackages.Registrar 的组件。

看下 AutoConfigurationPackages.Registrar 是个什么东西呢?

clipboard.png

在该类的 registerBeanDefinitions 内部打个断点我们发现:

/**
 * metadata : 表示我们的注解信息,就 @SpringBootApplication 注解,标注的类是 
 * SpringBootMainHelloWorld;
 * new PackageImport(metadata).getPackageName() : 它得到的包路劲就是 
 * @SpringBootApplication 标注的主程序所在包路劲。
 */
public void registerBeanDefinitions(AnnotationMetadata metadata,
               BeanDefinitionRegistry registry) {
           register(registry, new PackageImport(metadata).getPackageName());
}

clipboard.png

故@AutoConfigurationPackage的作用是:将spring boot主配置类所在的包及其子包下的所有的组件扫描到spring容器中去。

(2)我们发现 @EnableAutoConfiguration 注解中还被 @Import(AutoConfigurationImportSelector.class) 注解标注,那它的作用是什么呢?
通过 AutoConfigurationImportSelector 返回要导入的组件的全类目,然后导入容器中。关于spring boot是如何装配的可以参考博客:spring boot自动装配原理

所以我们可以理解 @SpringBootApplication 功能等同于 @SpringBootConfiguration ,@EnableAutoConfiguration ,@ComponentScan 三个注解的总和。

实现HelloController

@Controller
public class HelloController {

    @ResponseBody
    @RequestMapping("/hello")
    public String hello() {
        return "hello spring boot";
    }
}

运行main程序,执行结果

clipboard.png

遇到的问题

启动时报错

Your ApplicationContext is unlikely to start due to a @ComponentScan of the default package

导致问题的原因:
是因为 SpringBootMainHelloWorld.java 文件不能直接放在main/java文件夹下,必须要建一个包把他放进去,stack overflow

spring boot的Hello World程序研究

pom文件

我们发现在pom文件中有个 <parent>...</parent>元素,它管理着父项目的配置:

 <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.0.RELEASE</version>
 </parent>

在IDEA中点击<artifactId>spring-boot-starter-parent</artifactId> 进去发现有一个spring boot的父项目管理配置:

clipboard.png

这个才是spring boot 版本管理中心。

依赖jar由谁控制

<dependency>
       <groupId>org.springframework.boot</groupId>
       <artifactId>spring-boot-starter-web</artifactId>
</dependency>

spring-boot-starter-web 有何作用?
它帮我导入了spring web应用正常启动所需要的jar包。我们称 spring-boot-starter 场景启动器。spring boot提供了大量的启动器,只要引入启动器就会导入相应的开发jar引入到项目中。


一只小小鸟
144 声望25 粉丝

如何做一个深层次的思考者,从简单开始、从记录开始。