不小心弄出一个线程不安全的Service class ExcelImpService extends AbstractExcelImporter { ExcelImportService excelImportService List<Map> imp(FileStore excelFileStore, Map config) { String excelPath = excelFileStore.path assert new File(excelPath).exists() this. read(excelPath) println workbook.getSheetName(0) println workbook.getSheetName(0) //停一下 excelImportService.columns(workbook, config) } } 因为默认依赖注入的service是单实例的,所以会出现下面的结果 ---sout--- 浏览器1:company 浏览器2:expenseGroup 浏览器2:expenseGroup 浏览器1:expenseGroup (属性对象被别的线程修改了,应该还是company才对) 这个问题还是很隐晦的,而且线程安全问题一般不容易测试,所以要尽量从理论上消灭在萌芽状态 public abstract class AbstractExcelImporter extends imexporter.AbstractImexporter { Workbook workbook= null // 这个继承过来的属性就是隐患,每次调用read方法,都会修改之 ...略... } 经验:service如果有属性,要么搞成final的,否则就要格外留意方法中对其修改的操作。 解决办法: 开始想把ExcelImpService改成一个普通类,但是不利于获得其它service的支持(excelImportService)。。。 把service声明为session或request级别的,体验一下基于使用条件的线程安全。 /** * default(singleton) is NOT thread safe, since extends workbook prototype from AbstractExcelImporter * request -- 同一浏览器的同一tab是线程安全的 * session -- 不同(厂商)浏览器间是线程安全的,同一浏览器的不同tab是不安全的(但一般没人那么无聊吧,所以这就够了) */ static scope = 'session'