1. Thread safety?
Whether there is a critical section and shared variables will be written by different threads
Then the member variables or methods of the base class in the template method will have thread safety issues.
2、excel
AbstractExcelSheet
Decoupling business data and excel logic
Allow data to be set between service layers
In this way, excel-related classes do not need to be added to the spring container.
public abstract class AbstractExcelSheet<T> { private XSSFWorkbook workbook; private XSSFSheet sheet; /** * Write data */ private List<T> data; public void setData(List<T> data) { this.data = data; } /** * Get the sheet object of the current class * * @return sheet object */ public XSSFSheet getSheet() { return sheet; } /** * Set the sheet object * * @param sheet sheet object */ public void setSheet(XSSFSheet sheet ) { this.sheet = sheet; } /** * Get the excel object it belongs to * * @return excel object */ public XSSFWorkbook getWorkbook() { return workbook; } /** * Set excel object * * @param workbook excel object */ public void setWorkbook(XSSFWorkbook workbook) { this.workbook = workbook; } /** * Create basic information of the sheet */ public abstract void createSheet(); /** * Rewrite in subclasses * * @return title column */ public abstract List<String> getTitles (); /** * Generate sheet title column, this method does not need to be rewritten */ public void createTitleRow() { List<String> titles = getTitles(); // Get the row XSSFRow titleRow = getSheet().createRow(0); for (int i = 0; i < titles.size(); i++ ) { _ _ _ _ _ ) 460); } /** * Add the content to be exported to excel * * @param data Export data */ public abstract void createDataRow(List<T> data); /** * writeSheetData */ public void writeSheetData() { // Create a form sheet createSheet(); // sheet sets the header content (the first row of content) createTitleRow(); // Get the number from the database and write it to the file createDataRow(data); } /** *Write a row of sheet data * * @param rowIndex sheet write row index * @param data sheet entity data * @param enumValues sheet header title * @param <S> generic */ protected <S> void writeRowData(int rowIndex, S data, SheetTitleEnum[] enumValues) { XSSFRow row = getSheet().createRow(rowIndex); int colIndex = 0; XSSFCell cell = row.createCell(colIndex); for (SheetTitleEnum enumValue : enumValues) { String cellValue = ExportExcelUtil.getCellValue(data, enumValue); cell.setCellValue(cellValue); cell = row.createCell(++colIndex); } } }
BusiPackageResultExcelSheet
Business knowledge package inspection results.xlsx Business knowledge package inspection results sheet
public class BusiPackageResultExcelSheet<T> extends AbstractExcelSheet<T> { private final static String SHEET_NAME = "Business knowledge package check result"; @Override public void createSheet() { this.setSheet(this.getWorkbook().createSheet(SHEET_NAME)); } @Override public List<String> getTitles() { return BusiPackageResultSheetTitleEnum.titles; } @Override public void createDataRow(List<T> data) { // Header rowIndex = 0, so rowIndex = 1 int rowIndex = 1; SheetTitleEnum[ ] enumValues = BusiPackageResultSheetTitleEnum.values(); for (T dataEntry : data) { // Write row data writeRowData(rowIndex++, dataEntry, enumValues); } } }
BusiPkgRuleResultExcelSheet
Business knowledge package inspection results.xlsx rule inspection results sheet
public class BusiPkgRuleResultExcelSheet<T> extends RuleResultExcelSheet<T> { @Override public void createDataRow(List<T> data) { // Header rowIndex = 0, so rowIndex = 1 int rowIndex = 1; for (T dataEntry : data) { //Write row data writeRowData(rowIndex++, dataEntry, RuleResultSheetTitleEnum.values()); } } }
RuleResultExcelSheet
Rule check results.xlsx Rule check results sheet
public class RuleResultExcelSheet<T> extends AbstractExcelSheet<T> { private final static String SHEET_NAME = "Rule check result"; @Override public void createSheet() { this.setSheet(this.getWorkbook().createSheet(SHEET_NAME)); } / ** * Header content * * @return Header content */ @Override public List<String> getTitles() { return RuleResultSheetTitleEnum.titles; } @Override public void createDataRow(List<T> data) { // Header rowIndex = 0, so rowIndex = 1 int rowIndex = 1; SheetTitleEnum[] enumValues = RuleResultSheetTitleEnum.values(); for (T dataEntry : data) { // Write row data writeRowData(rowIndex++, dataEntry, enumValues); } } }
Most of the methods in the above design are implemented in the base class
When the headers of excel are different, they are implemented in subclasses.
3. Thread safety issues
All member variables may be competed by other threads.
For example, thread 1 setData data1
But at this time, if thread 1 excel has not been exported successfully,
Thread 2 comes in setData data2
Overwritten the data of thread 1
In fact, there are still many threading issues, because multi-threading is uncontrollable.
4. Solve
When service calls the excel implementation class, it becomes a local variable.
Properly use synchronized, ReentrantLock, and ThreadLocal atomic applications in a single application
Proper distributed use of redis locks
Two applications, pay attention to deadlock issues