java - Spring自动装配“忘记”了依赖
问题描述
我想玩弄不同类型的 bean 范围。所以我写了一个测试环境,它应该生成一个随机数,这样我就可以看到一个 bean 是否发生了变化。我的测试设置不起作用,我无法解释我发现了什么。
我将 Spring Boot 2.13 与 Spring Framework 5.15 一起使用。
以下设置:
主类:
package domain.webcreator;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class WebcreatorApplication {
public static void main(String[] args) {
SpringApplication.run(WebcreatorApplication.class, args);
}
}
豆类:
package domain.webcreator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.Random;
@Configuration
public class Beans {
@Bean
public Random randomGenerator() {
return new Random();
}
}
范围类:
package domain.webcreator;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;
import java.util.Random;
@Service
@Scope("singleton")
public class Scoper {
private Random rand;
public Scoper(Random rand) {
this.rand = rand;
}
public int getNumber(int max) {
return rand.nextInt(max);
}
}
索引控制器
package domain.webcreator.controller;
import domain.webcreator.Scoper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class IndexController {
@GetMapping("/")
@ResponseBody
@Autowired
public String indexAction(Scoper scoper) {
return String.valueOf(scoper.getNumber(50));
}
}
我的问题是,我在调用scoper.getNumber(50)时得到了 NPE 。这很奇怪,因为在调试时,会生成一个 Random bean 并将其传递给 scoper 构造函数。稍后,在控制器中,rand 属性为空。
我究竟做错了什么?
解决方案
您正在尝试应用@Autowired
随机方法,这不是 Spring 的工作方式。控制器方法参数用于特定于该 HTTP 请求的信息,而不是一般依赖项,因此 Spring 正在尝试创建一个Scoper
与请求关联的新参数——但它在请求中没有任何传入值要填写。(我真的很惊讶你没有收到关于没有默认构造函数的错误。)
相反,将你Scoper
的传入构造函数。
@RestController
public class IndexController {
private final Scoper scoper;
public IndexController(Scoper scoper) {
this.scoper = scoper;
}
@GetMapping("/")
public String indexAction(Scoper scoper) {
return String.valueOf(scoper.getNumber(50));
}
}
几点注意事项:
- 单例范围是默认的,无需指定。
@RestController
@ResponseBody
除非你有一个混合控制器类,否则最好重复。
推荐阅读
- sql-server-2008 - 如何避免“无法对包含聚合或子查询的表达式执行聚合函数”错误
- python - 使用另一个数据层的数据操作 pyplot 的 imshow 的单元格样式
- c# - Azure 函数 - function.json 它位于何处?
- python - 增强人工图像,使其看起来像真实图像以用于 TF 对象检测
- java - replaceAll 方法对我不起作用我做错了什么?
- excel - 在新工作簿上运行复制的宏时创建的运行时错误
- html - CSS字体样式未显示在网站中
- r - 回归,数据集中所有变量的列表
- vba - 在我的表单上的 firstFollowUp 字段中生成 dateReceived 字段后八个工作日的日期
- c# - EF Core:当 DB-first FK 是错误的方式时,如何级联删除?