1. @SpringBootApplication
1
2
3
4
5
6
@SpringBootApplication
class WebApplication
fun main(args: Array<String>) {
runApplication<WebApplication>(*args)
}
我们可以把 @SpringBootApplication看作是 @Configuration、@EnableAutoConfiguration、@ComponentScan 注解的集合。
-
@EnableAutoConfiguration:启用 SpringBoot 的自动配置机制 -
@ComponentScan: 扫描被@Component(@Service,@Controller)注解的 bean,注解默认会扫描该类所在的包下所有的类。 -
@Configuration:允许在 Spring 上下文中注册额外的 bean 或导入其他配置类
2. @Autowired
自动导入对象到类中,被注入进的类同样要被 Spring 容器管理比如:Service 类注入到 Controller 类中。
1
2
3
4
5
6
7
8
9
@Service
class UserServiceImpl : UserService
@RestController
@RequestMapping("/user")
class UserController {
@Autowired
lateinit var userService: UserService
}
3. @Component,@Repository,@Service, @Controller
我们一般使用 @Autowired 注解让 Spring 容器帮我们自动装配 bean。要想把类标识成可用于 @Autowired 注解自动装配的 bean 的类,可以采用以下注解实现:
-
@Component:通用的注解,可标注任意类为Spring组件。如果一个 Bean 不知道属于哪个层,可以使用@Component注解标注。 -
@Repository: 对应持久层即 Dao 层,主要用于数据库相关操作。 -
@Service: 对应服务层,主要涉及一些复杂的逻辑,需要用到 Dao 层。 -
@Controller: 对应 Spring MVC 控制层,主要用于接受用户请求并调用 Service 层返回数据给前端页面。
4. @RestController
@RestController注解是@Controller和@ResponseBody的合集,表示这是个控制器 bean,并且是将函数的返回值直接填入 HTTP 响应体中,是 REST 风格的控制器。
单独使用 @Controller 不加 @ResponseBody的话一般是用在要返回一个视图的情况,这种情况属于比较传统的 Spring MVC 的应用,对应于前后端不分离的情况。@Controller +@ResponseBody 返回 JSON 或 XML 形式数据
5. @Scope
声明 Spring Bean 的作用域,使用方法:
1
2
3
import org.springframework.beans.factory.config.BeanDefinition
@Scope(value = BeanDefinition.SCOPE_PROTOTYPE)
四种常见的 Spring Bean 的作用域:
- ConfigurableBeanFactory.SCOPE_SINGLETON : 唯一 bean 实例,Spring 中的 bean 默认都是单例的。
- ConfigurableBeanFactory.SCOPE_PROTOTYPE : 每次请求都会创建一个新的 bean 实例。
- org.springframework.web.context.WebApplicationContext.SCOPE_REQUEST : 每一次 HTTP 请求都会产生一个新的 bean,该 bean 仅在当前 HTTP request 内有效。
- org.springframework.web.context.WebApplicationContext.SCOPE_SESSION : 每一个 HTTP Session 会产生一个新的 bean,该 bean 仅在当前 HTTP session 内有效。
6. @Configuration
一般用来声明配置类,可以使用 @Component注解替代,不过使用@Configuration注解声明配置类更加语义化。
1
2
3
4
5
@Configuration
class AppConfig {
@Bean
fun transferService() = TransferServiceImpl()
}
7. 常见的 HTTP 请求类型
-
@GetMapping("/users")等价于@RequestMapping(value="/users",method=RequestMethod.GET), 请求获取数据。 -
@PostMapping("/users")等价于@RequestMapping(value="/users",method=RequestMethod.POST), 提交创建新数据。 -
@PutMapping("/users/{userId}")等价于@RequestMapping(value="/users/{userId}",method=RequestMethod.PUT), 更新数据 -
@DeleteMapping("/users/{userId}")等价于@RequestMapping(value="/users/{userId}",method=RequestMethod.DELETE),删除数据
8. 接口接收数据参数-
@PathVariable 路径参数
@RequestParam 查询参数
1
2
3
4
// /hello?name=jiang
fun hello(@RequestParam(name = "name") name: String): String {
return "Hello $name"
}
@RequestParam中有四个参数
- name 和 value是相同意思,因为默认从key是这里的命名,但如果名称和前端定义不一致就可以使用这个进行映射,添加后就不能按默认参数传参了,但是不可以同时添加。否则这个请求会报错,不能正常响应。
- required 表示这个参数是否必传,必传参数如果没有传就会报错,传空字符串也会报错,默认是必传的,但如果没有写@RequestParam则可以不用传,则会为null或者默认值(0)
- defaultValue 表示默认参数,如果没有传则为默认参数。当有默认值时,required就无效了,因为都会有值了。
注意,如果使用kotlin的默认参数,也是无效的,不能作为默认参数
1
2
3
4
// /hello?name=jiang
fun hello(@RequestParam(name = "name") name: String = "jiang"): String {
return "Hello $name"
}
接收对象参数
当有多个参数时,可以直接用参数接收,但是不能再写@RequestParam了,其中参数也都是可以不用传的了。
但必须要有无参构造函数,这样才能生效。
1
2
3
4
data class User(
var name: String?,
var age: Int?
)
或者
1
2
3
4
data class User(
var name: String = "jiang",
var age: Int = 18
)
不可以
1
2
3
4
data class User(
var name: String = "jiang",
var age: Int
)
会报错
1
java.lang.IllegalStateException: No primary or single unique constructor found for class xxx.demos.web.User
因为反编译可以看到有两个构造函数了
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public User(@NotNull String name, int age) {
Intrinsics.checkNotNullParameter(name, "name");
super();
this.name = name;
this.age = age;
}
// $FF: synthetic method
public User(String var1, int var2, int var3, DefaultConstructorMarker var4) {
if ((var3 & 1) != 0) {
var1 = "";
}
this(var1, var2);
}
-
@RequestBody用于读取 Request 请求(可能是 POST,PUT,DELETE,GET 请求)的 body 部分并且Content-Type 为 application/json 格式的数据,接收到数据之后会自动将数据绑定到 Java 对象上去。系统会使用HttpMessageConverter或者自定义的HttpMessageConverter将请求的 body 中的 json 字符串转换为 java 对象。
9. 读取配置信息
数据源内容如下:
application.yml
1
2
3
spring:
profiles:
active: prod
profiles-active设置环境,选择对应的文件
application-dev.yml
1
2
3
4
5
application:
name: dev环境
version: versionID
developer:
name: dev环境
application-prod.yml
1
2
3
4
5
application:
name: prod环境
version: prod环境
developer:
name: prod环境
** 使用 @Value("${property}") 读取比较简单的配置信息: **
1
2
3
4
@Value("${application.name}")
private String name;
@Value("${application.version}")
private String version;
** 通过@ConfigurationProperties读取配置信息并与 bean 绑定。 **
1
2
3
4
5
@ConfigurationProperties(prefix = "developer")
@Component
data class DeveloperProperty(
name: String,
)