我的课程“RequestContext
”,其范围为request
。此类具有属性listOfItem
。
现在我有了MyMapper
课,我需要使用这个列表。现在,当我想listOfItems
时,我总是打电话给context.getListOfItem()
,但问题是我有很多私人方法,我需要多次重复这个。在构造函数中定义此属性时可以吗?它是线程安全的吗?:
public abstract class MyMapper{
@Autowired
protected RequestContext context;
private final List<String> listOfItem;
public MyMapper() {
this.listOfItem = context.getListOfItem(); // is this thread safe and ok ?
}
public Object map(Object entity){
}
}
答案 0 :(得分:1)
是的,这是线程安全的,只要它被声明为原型范围bean ,并且您需要创建一个由Spring调用的init()
方法:
@PostConstruct
public void init() {
listOfItem = context.getListOfItem();
}
RequestContext只能从单个线程(分配用于处理请求的线程)访问,构造函数在其调用之前就不能重新创建对象。
请注意不要将此与listOfItem
混淆以防止重入问题,只是因为它被锁定在MyMapper
对象中并不会阻止它被getter共享,如果一个可用(在你的情况下没有)。我也看到它是一个抽象类,但因为listOfItem
是私有的,所以子类不能访问它。该列表的任何泄漏引用都可以由并发线程操纵,因为它是由引用构成的任何副本(因为List
在Java中是可变的。)
由于此安全性是您的意图,因此创建一个单元测试来检查字段的可见性,如果通过反射访问字段则不会引发相应的异常。您可能还希望使用自己的内部标记注释对该字段进行注释,以指示该字段是线程安全的。这有助于文档和注释,潜在的未来自动化(例如可以查找所有此类注释并自动运行反射测试的测试基础)。
看起来很干净!保持良好的工作。