类字段和方法参数中的单例 bean 上的@Autowire 给出了不同的实例

问题描述 投票:0回答:1

请看下面的代码:

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 spring-boot singleton instance autowired
1个回答
0
投票

好吧,我想我知道答案了。根据 Spring MVC 文档:

使用

@ModelAttribute
是可选的。默认情况下,任何不是由
BeanUtils#isSimpleProperty
确定的简单值类型并且未由任何其他参数解析器解析的参数都被视为隐式
@ModelAttribute.

所以我注入到方法中的

SingletonBean
被视为
@ModelAttribute
。有关此内容的文档是表格最底部的 Method Arguments 和页面底部的 @ModelAttribute
Tip

接下来,

@ModelAttribute
有一个请求范围,可以从下面的语句中扣除:

您可以使用@ModelAttribute注释: 在

@RequestMapping
方法中的方法参数上,从模型创建或访问
Object
并通过
WebDataBinder
将其绑定到请求。

可以在模型文档中找到。

© www.soinside.com 2019 - 2024. All rights reserved.