标签
spring
字数
1110 字
阅读时间
6 分钟
一、接口方式
系统初始化是、声明一个初始化的接口,然后由一个公共抽象类实现该接口,提供一个初始化的抽象方法。由各初始化任务继承该抽象的公共类
再由一个初始化工厂,获取继承该抽象公共类的所有子类。遍历调用其初始化方法。
该初始化工厂在servelet初始化时调用
初始化接口
java
/**
* 定义初始化接口。定义初始化和销毁。
* <i>服务器规范接口</i>
*/
public interface IInit extends IName{
/**
* 定义初始化接口
* @param conf
* @author chenli
* @data 2016-3-13
*/
public void init(ServletConfig conf);
/**
* 定义销毁接口
* @param conf
* @author chenli
* @data 2016-3-13
*/
public void destroy();
}抽象公共类
java
/**
* 出现异常将停止启动
* @author chenli
* @date 2016-3-13
* @version 1.0
*/
public abstract class AbstractInit implements IInit, IPriority, IName {
private Logger logger = LoggerFactory.getLogger(AbstractInit.class);
@Override
public void init(ServletConfig conf) {
try {
doInit(conf);
} catch (Exception e) {
if(exitOnException()){
logger.error("【"+getName()+"】数据初始化异常,应用程序停止...",e);
System.exit(0);
}else{
logger.warn("【"+getName()+"】数据初始化异常,应用程序继续运行...",e);
}
}
}
/**
* 初始化方法
* @param conf
* @throws Exception
* @author chenli
* @data 2018-8-15
*/
public abstract void doInit(ServletConfig conf) throws Exception;
@Override
public void destroy() {
try {
doDestroy();
} catch (Exception e) {
logger.error("【{}】数据销毁异常",getName(),e);
}
}
/**
* 销毁方法
* @param conf
* @throws Exception
* @author chenli
* @data 2018-8-15
*/
public abstract void doDestroy();
/**
* 默认异常将停止启动。
*/
public boolean exitOnException() {
return true;
}
@Override
public int priority() {
return PRIORITY_DEAULT;
}
}初始化工厂
java
/**
* 系统配置总工厂
* @author chenli
* @date 2016-2-24
* @version 1.0
*/
@Service
public class InitConfigFactory implements IInit{
private static final Logger logger = LoggerFactory.getLogger(InitConfigFactory.class);
private List<AbstractInit> factorys = new ArrayList<AbstractInit>();
@Override
public String getName() {
return "系统初始化";
}
/**
* 系统初始化
* @author chenli
* @data 2016-2-25
*/
public void init(ServletConfig conf){
logger.info("----------------------系统初始化----------------------");
logger.info("");
logger.info("#########扫描初始化工厂#########");
List<Class<AbstractInit>> list = ClassUtils.getChilderClass(AbstractInit.class, false);
for (Class<AbstractInit> c : list) {
try {
AbstractInit factory = SpringContext.getBean(c);
factorys.add(factory);
} catch (Exception e) {
logger.error("# 实例化工厂☆☆"+c.getSimpleName()+"☆☆异常,程序运行停止"+c,e);
System.exit(0);
}
}
Collections.sort(factorys, new PriorityComparator());
logger.info("#########扫描完成,开始初始化#########");
logger.info("");
for (AbstractInit f : factorys) {
logger.info("#########开始初始化【"+f.getName()+"】#########");
f.init(conf);
logger.info("#########完成初始化【"+f.getName()+"】#########");
logger.info("");
logger.info("");
}
//初始化权限
AccessDecisionDao accessDecisionManager = SpringContext.getBean("accessDecisionDao");
accessDecisionManager.initMenuOptcodeMap();
logger.info("----------------------系统初始化----------------------");
}
/**
* 系统销毁
* @author chenli
* @data 2016-2-25
*/
public void destroy(){
logger.info("----------------------系统资源回收----------------------");
for (AbstractInit f : factorys) {
logger.info("#########开始销毁系统【"+f.getName()+"】#########");
f.destroy();
logger.info("#########完成销毁系统【"+f.getName()+"】#########");
}
logger.info("----------------------系统资源回收----------------------");
}
}servlet初始化调用
java
/**
* 所有初始化工作
* @author chenli
* @date 2016-1-22
* @version 1.0
*/
public class InitServlet extends HttpServlet {
private static final long serialVersionUID = 3117103275293498582L;
private Logger logger = LoggerFactory.getLogger(InitServlet.class);
private InitConfigFactory configFacroty;
public void init(ServletConfig config) throws ServletException {
logger.info("InitServlet init start");
long start = System.currentTimeMillis();
//初始化SpringContext容器
SpringContext.initContext(config.getServletContext());
//系统初始化
configFacroty = SpringContext.getBean(InitConfigFactory.class);
configFacroty.init(config);
// 系统内存监控
MemoryMonitorUtil.startGcUsageMonitor();
super.init(config);
logger.info("InitServlet init completed in {}ms",(System.currentTimeMillis()-start));
}
public void destroy() {
logger.info("InitServlet destroy.....");
//系统初始化
configFacroty.destroy();
super.destroy();
}
}二、方式二
通过注解方式,参考@PostConstruct与@PreDestroy
@PostConstruct
@PostConstruct该注解被用来修饰一个非静态的void()方法。被@PostConstruct修饰的方法会在服务器加载Servlet的时候运行,并且只会被服务器执行一次。PostConstruct在构造函数之后执行,init()方法之前执行。
在整个Bean初始化中的执行顺序:
Constructor(构造方法) -> @Autowired(依赖注入) -> @PostConstruct(注释的方法)
例子:
java
@Autowired
private SysDictTypeMapper dictTypeMapper;
@Autowired
private SysDictDataMapper dictDataMapper;
/**
* 项目启动时,初始化字典到缓存
*/
@PostConstruct
public void init(){
List<SysDictType> dictTypeList = dictTypeMapper.selectDictTypeAll();
for (SysDictType dictType : dictTypeList){
List<SysDictData> dictDatas = dictDataMapper.selectDictDataByType(dictType.getDictType());
DictUtils.setDictCache(dictType.getDictType(), dictDatas);
}
}@PreDestroy
被@PreDestroy修饰的方法会在服务器卸载Servlet的时候运行,并且只会被服务器调用一次,类似于Servlet的destroy()方法。被@PreDestroy修饰的方法会在destroy()方法之后运行,在Servlet被彻底卸载之前。
java
/**
* 确保应用退出时能关闭后台线程
*
* @author ruoyi
*/
@Component
public class ShutdownManager {
private static final Logger logger = LoggerFactory.getLogger("sys-user");
@PreDestroy
public void destroy() {
shutdownAsyncManager();
}
/**
* 停止异步执行任务
*/
private void shutdownAsyncManager() {
try {
logger.info("====关闭后台任务任务线程池====");
AsyncManager.me().shutdown();
} catch (Exception e) {
logger.error(e.getMessage(), e);
}
}
}