请看下面的代码:
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/test")
@Slf4j
class BeanScopeTestController {
private final SingletonBean singletonBean1;
@Autowired
BeanScopeTestController(SingletonBean singletonBean) {
this.singletonBean1 = singletonBean;
}
@GetMapping
String checkTheSameInstance(@Autowired SingletonBean singletonBean2) {
log.info(singletonBean1.toString());
log.info(singletonBean2.toString());
boolean methodEquals = singletonBean1.equals(singletonBean2);
boolean instanceEquals = singletonBean1 == singletonBean2;
return String.format("method equals: %s; instance equals: %s", methodEquals, instanceEquals);
}
}
import lombok.EqualsAndHashCode;
import lombok.ToString;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
@Slf4j
@Component
@ToString
@EqualsAndHashCode
class SingletonBean {
private static int idProvider = 0;
private final int id;
public SingletonBean() {
this.id = idProvider++;
}
}
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class SpringDemoApplication {
public static void main(String[] args) {
SpringApplication.run(SpringDemoApplication.class, args);
}
}
GET
/test
端点(方法BeanScopeTestController#checkTheSameInstance
)的输出怎么可能是method equals: false; instance equals: false
?
spring @Bean
的默认范围是 Singleton
,我希望类字段 singletonBean1
和方法参数 singletonBean2
将从 Spring 容器中获得相同的实例,但这些引用会使用不同的 SingletonBean
实例自动装配。 Spring MVC 中方法参数上的 @Autowire
的工作方式是否有所不同,因此可能 bean 作用域以某种方式被覆盖?还是原因不一样?
我希望通过类字段和方法参数自动装配相同的
SingletonBean
实例。
好吧,我想我知道答案了。根据 Spring MVC 文档:
使用
@ModelAttribute
是可选的。默认情况下,任何不是由 BeanUtils#isSimpleProperty
确定的简单值类型并且未由任何其他参数解析器解析的参数都被视为隐式 @ModelAttribute.
所以我注入到方法中的
SingletonBean
被视为@ModelAttribute
。有关此内容的文档是表格最底部的 Method Arguments 和页面底部的 @ModelAttribute Tip
。
接下来,
@ModelAttribute
有一个请求范围,可以从下面的语句中扣除:
您可以使用@ModelAttribute注释: 在
@RequestMapping
方法中的方法参数上,从模型创建或访问 Object
并通过 WebDataBinder
将其绑定到请求。
可以在模型文档中找到。