Java Spring原型作用域bean。我是否需要将其中的字段设置为threadLocal?
Spring框架中有一条经验法则——将无状态bean声明为单例,将有状态bean声明为原型。然而,并没有关于原型作用域bean中有状态字段的信息,也并没有关于是否应该同步查找方法以避免竞争条件的信息 假设我有一个包含多个字段的有状态beanJava Spring原型作用域bean。我是否需要将其中的字段设置为threadLocal?,java,spring,spring-mvc,prototype,synchronized,Java,Spring,Spring Mvc,Prototype,Synchronized,Spring框架中有一条经验法则——将无状态bean声明为单例,将有状态bean声明为原型。然而,并没有关于原型作用域bean中有状态字段的信息,也并没有关于是否应该同步查找方法以避免竞争条件的信息 假设我有一个包含多个字段的有状态bean @Service @Scope("prototype") class PostOperator { @Autowired private MailSender mailSender; private String las
@Service
@Scope("prototype")
class PostOperator {
@Autowired
private MailSender mailSender;
private String lastName;
private String streetAddress;
private Long operatorId;
private Map <String, String> subjectArticle map;
public PostOperator(String lastName, String streetAddress, Long operatorId,
Map <String, String> subjectArticle map){
......
}
public void submitEmail(){
mailSender.send(lastName, streetAddress, operatorId);
}
}
@服务
@范围(“原型”)
类后置运算符{
@自动连线
私人邮件发送者;
私有字符串lastName;
私有字符串streetAddress;
私人长运营商;
私有地图主题文章地图;
公共PostOperator(字符串lastName、字符串streetAddress、长运算符ID、,
地图主题(文章地图){
......
}
公共无效提交邮件(){
mailSender.send(姓氏、街道地址、操作员ID);
}
}
我有一个带有查找方法的Rest控制器
@RestController
class AppointmentController {
@GetMapping("/submit")
public ResponseEntity submit() {
PostOperator operator = getOperator("Smith", "Fleet Str.", 7L,
new ConcurrentHashMap<>());
operator.submitEmail();
return ResponseEntity.ok();
}
@Lookup
public PostOperator getOperator(String lastName, String streetAddress, Long operatorId,
Map <String, String> subjectArticle map) {
return null;
}
@RestController
班主任{
@GetMapping(“/submit”)
公共响应提交(){
PostOperator=getOperator(“史密斯”,“舰队街”,7L,
新的ConcurrentHashMap());
运算符。submitEmail();
返回ResponseEntity.ok();
}
@查找
公共PostOperator getOperator(字符串lastName、字符串streetAddress、长运算符ID、,
地图主题(文章地图){
返回null;
}
- 我是否需要将字段声明为ThreadLocal
- 由于AFAIK Singleton不是线程安全的,我需要同步查找方法吗
- 是否需要在PostOperator中同步submitEmail()方法
非常感谢各位的澄清。在我看来,只要依赖实例不包含任何影响的状态 在上面的示例中,您的服务
PostOperator
依赖于MailSender
,它的唯一职责是根据给定的参数发送电子邮件,其中所有行为都绑定到send
方法。唯一的例外是电子邮件配置。因此,在这种情况下,基于使用的电子邮件凭据send
方法不依赖于任何其他状态来发送方法,它也没有任何副作用,您不必担心线程安全
无状态服务在大多数情况下都具有线程安全性。同意无状态服务,但我担心的是AppointmentController依赖于有状态的PostOperator。在这种情况下,同步@Lookup方法有意义吗?因为Lookup方法接收参数并传递给PostOperator的构造函数?在这种情况下,传入的请求是否可能导致竞争条件?因为您已将
PostOperator
服务注释为prototype
,所以应该在每个请求中初始化此服务,这意味着每个请求都有新的实例,我也看不到此服务注入到您的控制器中服务的ate不会在请求之间共享,那么我们不需要担心,另一件事是它不会有副作用,比如更新状态或修改,那么我们不需要担心其他更好的方法是将syncronized
Hi@msucil,PostOperator确实没有注入控制器,但它是从查找方法获得的od getOperator,因此它是一个本地字段。请查看控制器-有一行代码:PostOperator=getOperator(“Smith”,“Fleet Str.”,7L,new ConcurrentHashMap())就在submit方法中。首先,我在方法中获取PostOperator实例,然后我提交电子邮件。在这种情况下,每当调用getOperator
时,它都会返回PostOperator
的新实例。在这种情况下,无需担心线程安全,因为执行上下文绑定到getOperator
方法D