Spring-Boot-Introduction-2

Spring Boot 入门(二)


使用Maven做构建系统

使用Maven来管理Spring的dependency可以有效减少你的烦恼,你无需自己去下载依赖然后添加到目录下,这些都可以交给Maven来管理。

继承Starter Parent

你可以通过继承 spring-boot-starter-parent 来获得默认的依赖项

1
2
3
4
5
6
<!-- Inherit defaults from Spring Boot -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.4.RELEASE</version>
</parent>

当你想要覆盖某一个依赖项时,你可以通过覆盖属性来实现,例如当你想升级Spring Date时:

1
2
3
<properties>
<spring-data-releasetrain.version>Fowler-SR2</spring-data-releasetrain.version>
</properties>

使用spring-boot-dependencies

当你不想要继承Starter Parent时,你一可以通过添加 spring-boot-dependencies 来添加依赖管理。

1
2
3
4
5
6
7
8
9
10
11
12
<dependencyManagement>
<dependencies>
<dependency>
<!-- Import dependency management from Spring Boot -->
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.1.4.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>

当时当你想要覆盖某个依赖项时,你不能像上面那样通过覆盖属性来实现,而是要在 spring-boot-dependencies 前添加你要覆盖的依赖

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<dependencyManagement>
<dependencies>
<!-- Override Spring Data release train provided by Spring Boot -->
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-releasetrain</artifactId>
<version>Fowler-SR2</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.1.4.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>

Starter

Spring Boot 还提供了很多starter供我们使用,具体到:https://docs.spring.io/spring-boot/docs/current/reference/html/using-boot-build-systems.html查看。

构建你的代码布局

Spring Boot 不需要任何特定的代码布局就可以工作,然而,下面的布局可以让Spring Boot更好的运作。

避免使用默认包

当一个类中没有包声明时,他就会被认为是放在默认包中。而我们应尽量避免使用默认包。它可能会导致你在 Spring Boot 应用中使用@ComponentScan, @EntityScan, or @SpringBootApplication 注释时会让所有jar里的所有class都会被扫描,这可能会导致一些问题。

  • 建议你使用java的包命名规范和方向域名,例如: com.example.project

定位 Main Application 类

通常建议将Main Application类放在root包下,然后用@SpringBootApplication注释这个main类。@SpringBootApplication带注释的类用于搜索@Entity项。使用root包还能允许组件仅扫描应用于您的项目。

  • 如果不想用@SpringBootApplication,可以用@EnableAutoConfiguration@ComponentScan来代替。

建议的包结构:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
com
+- example
+- myapplication
+- Application.java
|
+- customer
| +- Customer.java
| +- CustomerController.java
| +- CustomerService.java
| +- CustomerRepository.java
|
+- order
+- Order.java
+- OrderController.java
+- OrderService.java
+- OrderRepository.java

Application.java中声明main方法(使其变成Main Application类)并添加@SpringBootApplication注释

1
2
3
4
5
6
7
8
9
10
11
12
13
package com.example.myapplication;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Application {

public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}

}

@Configuration Classes

Spring Boot 支持基于 Java 的配置。你可以使用SpringApplication和xml来进行配置,但是Spring建议使用单个 @Configuration 类,通常这个类也是 main 类。

导入其他的Configuration Classes

你不用将所有 @Configuration 放入单个类中,你可以使用 @Import 注释导入其他 Configuration Classes 或 使用 @ComponentScan 自动获取所有Spring组件,包括 @Configuration 类。

导入xml配置

如果你仍然想用xml来配置,建议你还是使用 @Configuration 类, 然后,使用 @ImportResource 来加载xml配置文件。

Auto-configuration

Spring Boot 会自动根据你添加的jar依赖尝试去配置Spring应用。例如,如果你路径上有 HSQLDB ,但你没有手动配置任何数据库连接 bean,Spring Boot 就会自动配置内存数据库。

逐步更换 Auto-configuration

Auto-configuration 是非侵入性的,当你不想要自动配置时,你随时可以定义自己的配置,此时原来的自动配置就会退出。如果你想要知道自己的应用在用哪些自动配置以及原因,你可以使用 --debug 开关来获得详细信息。

禁用特定的Auto-configuration类

如果你想要禁用某个configuration类,你可以像下面那样

1
2
3
4
5
6
7
8
import org.springframework.boot.autoconfigure.*;
import org.springframework.boot.autoconfigure.jdbc.*;
import org.springframework.context.annotation.*;

@Configuration
@EnableAutoConfiguration(exclude={DataSourceAutoConfiguration.class})
public class MyConfiguration {
}

如果class 不再类路径中,可以使用批注的 excludeName 属性和指定完全限定的名称。最后,你可以使用 spring.autoconfigure.exclude

控制要排除的自动配置类列表。

Spring Beans 和依赖注入

你可以使用任何标准的Spring Framework技术来定义bean及其注入的依赖项。建议使用 @ComponentScan 来找到你的bean,并使用 @Autowired 来做构造函数注入。

如果按上述方法构建代码,你可以使用不带任何参数的添加 @Component 。所有的应用程序组件(@Component@Service@Repository@Controller)都会自动注册为Spring Beans。

下面的例子中,一个 @Service Bean使用构造方法来注入获取所需的 RiskAssessor Bean。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
package com.example.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class DatabaseAccountService implements AccountService {

private final RiskAssessor riskAssessor;

@Autowired
public DatabaseAccountService(RiskAssessor riskAssessor) {
this.riskAssessor = riskAssessor;
}

// ...

}

如果bean只有一个构造方法,那么 @Autowired 也可以省略。

1
2
3
4
5
6
7
8
9
10
11
12
@Service
public class DatabaseAccountService implements AccountService {

private final RiskAssessor riskAssessor;

public DatabaseAccountService(RiskAssessor riskAssessor) {
this.riskAssessor = riskAssessor;
}

// ...

}

使用@SpringBootApplication注释

使用 @SpringBootApplication 注释和一起使用 @Configuration@EnableAutoConfiguration@ComponentScan 效果一样。

  • @EnableAutoConfiguration: 允许自动根据添加的jar依赖类配置Spring Boot应用
  • @ComponentScan: 允许在应用所在的包中扫描 @Component
  • @Configuration: 允许在上下文中注册额外的bean或导入其他Configuration classes
1
2
3
4
5
6
7
8
9
10
11
12
13
package com.example.myapplication;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication // same as @Configuration @EnableAutoConfiguration @ComponentScan
public class Application {

public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}

}

实际上,若你在IDE中打开这个注释,会发现它由以下部分组成

  • @SpringBootConfiguration : SpringBoot配置类,表示这是一个SpringBoot的配置类
    • @Configuration:标注配置类
      • @Component:配置类也是组件
  • @EnableAutoConfiguration:开始自动配置功能
    • AutoConfigurationPackage:自动配置包
      • @Import(AutoConfigurationPackages.Registrar.class):Spring的底层注解@Import,给容器导入一个组件,导入的组件有AutoConfigurationPackages.Registrar.class。将主配置类的所在包及下面所有子包里面的所有组件扫描到Spring容器。
    • @Import(AutoConfigurationImportSelector.class):给容器导入:AutoConfigurationImportSelector,即导入组件的选择器,将所有需要导入的组件以全类名的方式返回,这些组件就会被添加到容器中,最终会给容器导入非常多的自动配置类(……AutoConfiguraion)。即给容器导入这个场景所需要的所有组件,并进行配置。免去来我妈手动编写配置和注入功能组件等功能。
      • SpringFactoriesLoader.loadFactoryNames(EnableAutoConfiguration.class,classLoader);在启动的时候从类路径下的META-INF/spring.factories中获取EnableAutoConfiguration指定的值,将这些值作为自动配置类导入到容器中,自动配置类就生效,帮我们进行自动配置工作
  • @ComponentScan(excludeFilters={@Filter(type=CUSTOM, classes {TypeExcludeFilter.class})
  • @Filter(type=CUSTOM, classes={AutoConfigurationExcludeFilter.class})})
  • @Target(value={TYPE})
  • @Retention(value=RUNTIME)
  • @Documented
  • @Inherited

J2EE的整体整合解决方案和自动配置都在spring-boot-autoconfigure.jar;

使用 @SpringBootApplication 注释相当于使用上述3个注释的默认属性。但你也可以自己决定用不用,例如,当你不想用组件扫描的时候你可以使用 @Import 来代替。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package com.example.myapplication;

import org.springframework.boot.SpringApplication;
import org.springframework.context.annotation.ComponentScan
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;

@Configuration
@EnableAutoConfiguration
@Import({ MyConfig.class, MyAnotherConfig.class })
public class Application {

public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}

}

运行Spring Boot 应用

在IDE中

直接按运行即可,要注意的是创建的时候要创建project,可以使Maven project或Spring Boot Project。

作为包应用运行

如果你使用Maven或Gradle的插件来创建一个可执行jar,你可以使用 java -jar 来运行。

1
$ java -jar target/myapplication-0.0.1-SNAPSHOT.jar

如果你需要debug

1
2
$ java -Xdebug -Xrunjdwp:server=y,transport=dt_socket,address=8000,suspend=n \
-jar target/myapplication-0.0.1-SNAPSHOT.jar

使用Maven插件

Maven 的 Spring Boot 插件可以快速编译和运行目标。应用就像在IDE中一样以分解形式运行。

1
$ mvn spring-boot:run

如果你还想用 MAVEN_OPT3 控制系统环境变量

1
$ export MAVEN_OPTS=-Xmx1024m