我想尝试各种类型的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);
}
}
Beans类:
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();
}
}
Scoper类:
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并将其传递给作用域构造函数。 稍后,在控制器中,rand属性为null。
我在做什么错了?
答案 0 :(得分:4)
您正在尝试将@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
更好。