Spring:new() 运算符和 Autowiring 在一起

标签 spring spring-mvc jakarta-ee

如果我使用Spring,这两种方法哪个更正确。
即使我使用双侧注入(inject),我也可以使用 new() 运算符吗?我可以混合使用吗?
我想对这些概念做一些澄清。
谢谢

第一种方法:

@RequestMapping(method=RequestMethod.GET)
public String create(Model model){
 model.addAttribute(new User());
 return "index";
}

第二种方法:
@Autowired
User user;

@RequestMapping(method=RequestMethod.GET)
public String create(Model model){
 model.addAttribute(user);
 return "index";
}

最佳答案

使用依赖注入(inject)并不意味着使用new运算符在整个代码中被自动禁止。只是针对不同的需求采用了不同的方法。

Spring 中的 Web 应用程序由许多由框架实例化的协作 bean 组成,并且(除非覆盖默认范围)是单例的。这意味着它们不能保留任何状态,因为它们在所有请求(线程)之间共享。换句话说,如果您 Autowiring User 对象(或任何其他模型属性),它会在应用程序上下文初始化时创建,并且会为任何用户请求提供相同的实例。这也意味着如果一个请求修改了对象,其他请求也会看到修改。不用说这是多线程应用程序中的错误行为,因为您的 User 对象(或其他模型属性)属于请求,因此它必须具有非常狭窄的方法调用范围,或最多 session 。

您也可以让 spring 为您创建具有不同范围的 bean,但对于模型属性初始化的简单场景,new运营商就足够了。如果对 bean 范围感兴趣,请参阅以下文档:Bean scopes

所以在你的用例中,第二种方法是完全错误的。
但是您也可以将模型属性的创建委托(delegate)给 spring 如果它们被用作命令对象 (即,如果您想将请求参数绑定(bind)到它们)。只需将其添加到方法签名中(带或不带模型属性注释)。

所以你也可以把上面的代码写成

@RequestMapping(method=RequestMethod.GET)
public String create(@ModelAttribute User user){     
 return "index";
}

另见:Supported method argument types

关于Spring:new() 运算符和 Autowiring 在一起,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27024439/

相关文章:

java - 在 Spring 配置中,用 XML 格式编写 Java 代码有什么好处?

mysql - 为什么在 mysql 中键入数据 "long blob"在 Data Explorer MATLAB 中读取为 "int8"?

java - 使用 GAE 任务队列处理持久性操作

web-services - 没有 Web 应用程序服务器的 Java Web 服务

spring - 在spring数据jpa存储库方法查询上附加自定义条件

spring - MongoDb Spring数据GeoNear查询最大和最小距离

Spring MVC 处理程序拦截器,带有 pathparam 的排除路径模式

javax.servlet.http.HttpServlet“找不到

java - Spring - 从 xml 到 Java 配置

JPA 合并只读字段