简介
@PostConstruct和@PreDestroy这两个注解被用来修饰一个非静态的void()方法,而且这个方法不能有抛出异常声明。
@PostConstruct注解在方法上,表示此方法是在Spring实例化该Bean之后马上执行此方法,之后才会去实例化其他Bean,并且一个Bean中@PostConstruct注解的方法可以有多个。
说明
@PostConstruct说明:被@PostConstruct修饰的方法会在服务器加载Servlet(bean)的时候运行,并且只会被服务器调用一次,类似于Serclet的inti()方法。被@PostConstruct修饰的方法会在构造函数之后,init()方法之前运行。
用处:@PostConstruct注解的方法在项目启动的时候执行这个方法,也可以理解为在spring容器启动的时候执行,可作为一些数据的常规化加载,比如数据字典之类的。
@PreDestroy说明:被@PreDestroy修饰的方法会在服务器卸载Servlet(bean)的时候运行,并且只会被服务器调用一次,类似于Servlet的destroy()方法。被@PreDestroy修饰的方法会在destroy()方法之后运行,在Servlet被彻底卸载之前。
加载过程
示例
@Component
@EnableScheduling
@Slf4j
public class VehicleLocationSchedule {
@Autowired
SysAreasMapper sysAreasMapper;
@Autowired
VehicleLocationMapper vehicleLocationMapper;
@Autowired
VehicleStatusMapper vehicleStatusMapper;
@Autowired
VehicleLocationService vehicleLocationService;
//运行次数
private int count = 0;
/**
* 定时更新车辆所在省份的信息(每隔6小时执行一次)
*/
@PostConstruct
@Scheduled(fixedDelay = 1000 * 60 * 60 * 6)
private void updateVehicleLocation() {
//查询省份边际坐标
List<ProvinceAreasVO> allProvince = sysAreasMapper.findAllProvince();
//需要更新的数据
List<VehicleLocationDO> list = new LinkedList<>();
//需要新增的数据
List<VehicleLocationDO> list2 = new LinkedList<>();
//更新过坐标位置数据的车辆
List<VehicleLocationVO> vehicleLocationAll;
//判断是否是第一次启动
//获取所有有坐标且报文时间大于位置的更新时间的车辆的数据(count=0)
//查询6小时之间更新过实时数据且报文时间大于位置的更新时间的有坐标的车辆(count>0)
vehicleLocationAll = vehicleStatusMapper.getVehicleLocationAll(count);
//遍历车辆
for (VehicleLocationVO vehicleLocationVO : vehicleLocationAll) {
//车辆坐标点
PointDTO pointDTO = new PointDTO();
try {
pointDTO = FenceUtils.mct84Bl2xy(
GpsPointDTO.builder().longitude(vehicleLocationVO.getLongitude())
.latitude(vehicleLocationVO.getLatitude()).build());
} catch (Exception e) {
log.error("GPS坐标转换xy坐标错误:", e);
}
//对所有省份进行遍历,查看在哪个省份里(优先遍历车辆上一次所在省份)
VehicleLocationDO locationDO = vehicleLocationMapper.selectById(vehicleLocationVO.getVin());
//表里有该车辆的数据且省份集合的第一个省份不是该车辆上一次所在的省
if (locationDO != null && !locationDO.getIdAreas().equals(allProvince.get(0).getId())) {
Integer idAreas = locationDO.getIdAreas();
for (int i = 0; i < allProvince.size(); i++) {
if (allProvince.get(i).getId().equals(idAreas)) {
//将车辆上一次所在省份放在集合最前面
Collections.swap(allProvince, i, 0);
}
}
}
for (ProvinceAreasVO provinceAreasVO : allProvince) {
try {
//判断车辆是否在该省内
FenceResult result = FenceUtils.isPointInPolyFences(pointDTO,
FenceUtils.parsePolylineFromStr(provinceAreasVO.getPoint()));
if (result.getIsInline()) {
//在该省内
VehicleLocationDO vehicleLocationDO = VehicleLocationDO.builder().vin(vehicleLocationVO.getVin())
.idAreas(provinceAreasVO.getId()).updateAt(LocalDateTime.now()).build();
//判断表里是否有该车的数据
if (vehicleLocationMapper.selectById(vehicleLocationVO.getVin()) == null) {
//需要新增的数据
list2.add(vehicleLocationDO);
}
//需要更新的数据
list.add(vehicleLocationDO);
break;
}
} catch (Exception e) {
log.error("省份坐标字符串转换PointDTO集合错误:", e);
}
}
}
//新增数据
vehicleLocationService.saveBatch(list2);
//更新数据
vehicleLocationService.updateBatchById(list);
//运行次数更新
count++;
}
}