(一).今天看到这样的代码,一开始好奇为什么不直接把注解 @Value放到dataUrl上面,这样多此一举是干什么。
原因:
@Value注解用于将外部配置文件的属性值注入到 Spring 管理的 Bean 中,Bean容器管理的都是实例对象。而静态属性是属于类的,不是一个对象,并不在Bean容器中,所以@Value没法把值注入到静态属性中。
如果想要将外部配置文件的属性注入到静态属性中:
可以采用上图中的方法。需要注意的是,由于@Value注解是通过 Setter 方法来注入属性值的,因此该方法的访问修饰符必须是公共的(public),否则 Spring 无法调用该方法进行属性值的注入。此外,由于该方法是 Setter 方法,因此不能有返回值。
补充:@Value是如何将值注入到bean实例中的
@Value注解是将外部配置文件中的属性值注入到 Spring 管理的 Bean 实例中的一种方式,其具体实现是通过 Spring的属性编辑器(PropertyEditor)完成的。 在 Spring容器启动时,会读取配置文件中的属性值,并将其转换为对应的数据类型。此时,如果发现某个 Bean 的属性上使用了@Value注解,Spring会先创建该 Bean 的实例,然后在实例的属性上执行属性编辑器,将配置文件中的属性值转换为对应的数据类型,并注入到该属性中。
具体实现过程如下:
1.Spring 首先读取配置文件中的属性值,例如application.properties文件中的common.dataUrl属性。
2.如果某个 Bean 的属性上使用了@Value注解,Spring 会先创建该 Bean 的实例。
3.在实例的属性上执行属性编辑器,将配置文件中的属性值转换为对应的数据类型,并注入到该属性中。
(二).看到一个大哥写的码,果然没点基础还真看不懂。当时一直在纠结SmsType这个枚举类还没有创建,怎么能先拿它用来给type定义呢?
原因:
在这个例子中,虽然 SmsType 枚举类型的定义出现在 type 成员变量的定义之后,但编译器会先把 SmsType 枚举类型编译成字节码文件,然后再编译 type 成员变量的定义,因此不会出现编译错误。
补充:
Java 中的内部类是定义在另一个类内部的类,它可以访问外部类的成员变量和方法。内部类可以分为成员内部类、局部内部类、匿名内部类和静态内部类,每种类型的内部类在编译时的处理方式略有不同。
对于成员内部类而言,它的成员变量是在创建内部类对象时进行初始化的。具体来说,当创建一个成员内部类的对象时,会先创建外部类对象,再创建内部类对象。因此,在编译时,成员内部类的成员变量的定义和初始化代码会被编译成字节码文件中的常规成员变量和构造方法代码,和外部类的其他成员变量和方法一起被编译。
需要注意的是,成员内部类的成员变量和外部类的成员变量是相互独立的,它们在内存中分别占用不同的空间。成员内部类只能访问外部类的成员变量和方法,而不能直接访问外部类的局部变量和方法参数。
(三):使用@RequestBody注解将json数据转换为java对象时,我下面这个属性为null,没有获取到json数据中的数据
原因:访问权限不足:Java属性的访问权限为private,无法从外部访问,导致无法正确赋值。
解决方案:
1.将属性的权限设置为public
2.添加@JsonProperty(“json属性名”),在属性值上
如果JSON数据名和Java属性名一致,但是仍然不能获取值,可能有以下几个原因:
1.数据类型不匹配:JSON数据中的值的数据类型与Java属性的数据类型不匹配,导致无法正确赋值。例如,JSON数据中的值为字符串类型,但是Java属性的数据类型为整数类型。
2.访问权限不足:Java属性的访问权限为private,无法从外部访问,导致无法正确赋值。
3.缺少setter方法:Java属性缺少setter方法,导致无法正确赋值。
4.缺少无参构造方法:Java类缺少无参构造方法,导致无法正确反序列化JSON数据
补充:
@RequestBody:是Spring框架中的一个注解,用于指示框架将HTTP请求的body部分转换为指定的Java对象。在处理RESTful API时,通常使用@RequestBody将HTTP请求的JSON或XML数据转换为Java对象。Spring框架默认使用Jackson库来解析JSON数据。如果要使用其他库或自定义解析器,则需要进行相应的配置。
@JsonProperty是Jackson库中的注解,用于指定JSON对象属性名与Java对象属性名之间的对应关系。在Spring MVC中,使用@JsonProperty注解来解决JSON字符串属性名与Java对象属性名不一致的问题。
@JsonProperty注解有以下几个属性:
1.value:指定JSON对象属性名与Java对象属性名之间的对应关系。例如,@JsonProperty(“name”)指定JSON对象中的"name"属性对应Java对象中的"name"属性。
2.access:指定Java对象属性的访问权限。可选值包括Access.READ_ONLY和Access.WRITE_ONLY。默认值为Access.AUTO,表示根据Java对象属性的访问权限自动选择读写权限。
3.required:指定JSON对象属性是否为必需属性。默认值为false,表示JSON对象属性可以为空。
4.defaultValue:指定JSON对象属性的默认值。如果JSON对象中没有该属性,就使用指定的默认值。
@Validated补充
@Validated是Spring框架中的注解,用于验证Java对象中的字段是否符合约束条件。
@Validated注解常用于处理表单数据、HTTP请求参数等场景,可以确保数据的正确性和完整性。
@Validated注解需要与javax.validation中的注解结合使用,例如@NotNull、@Size、@Pattern等。这些注解用于约束Java对象中的字段,指定其取值范围、长度、格式等条件。当使用@Validated注解验证Java对象时,会自动根据约束条件进行验证,如果验证失败,会抛出MethodArgumentNotValidException异常。
@Validated注解还可以用于Spring中的AOP校验,例如在Controller层对参数进行校验,可以使用@Validated注解来标注方法或类,然后在方法或类中使用@Valid注解来校验参数。这样可以在请求到来时自动验证参数,减少重复的校验代码。
例如,以下代码定义了一个Java对象User,使用@NotNull注解约束了name字段,使用@Size注解约束了password字段的长度:
public class User {
@NotNull(message = "用户名不能为空")
private String name;
@Size(min = 6, max = 20, message = "密码长度必须在6-20个字符之间")
private String password;
// 省略Getter和Setter
}
在Controller层中,使用@Validated注解对User对象进行校验:
@RestController
@Validated
public class UserController {
@PostMapping("/user")
public ResponseEntity<User> createUser(@Valid @RequestBody User user) {
// 处理创建用户的操作
}
}
在上面的代码中,@Validated注解标记了Controller类,在处理请求方法时会对数据进行校验。@Valid注解标记了方法参数User,表示对User对象进行校验。当客户端发送POST请求时,服务器会自动对请求体中的JSON字符串转换为Java对象,并校验其字段是否符合约束条件。如果校验失败,会抛出MethodArgumentNotValidException异常,可以在异常处理器中进行处理。