一、SpringBoot项目启动执行任务的几种方式
经过整理后得到以下几种常用方式,供大家参考。
1. 使用过滤器
init() :该方法在tomcat容器启动初始化过滤器时被调用,它在 Filter 的整个生命周期只会被调用一次。可以在这个方法中补充想要执行的内容。
@Component
public class MyFilter implements Filter {
/**
* init() :该方法在tomcat容器启动初始化过滤器时被调用,它在 Filter 的整个生命周期只会被调用一次。
* doFilter() :容器中的每一次请求都会调用该方法, FilterChain(放行) 用来调用下一个过滤器 Filter。
* destroy(): 当容器销毁过滤器实例时调用该方法,在方法中销毁或关闭资源,在过滤器 Filter 的整个生命周期也只会被调用一次。
*/
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("Filter 前置");
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
System.out.println("Filter 处理中");
filterChain.doFilter(servletRequest, servletResponse);
}
@Override
public void destroy() {
System.out.println("Filter 后置");
}
}
2.实现InitializingBean接口,代码如下:
@Component
public class SpringContext implements InitializingBean {
@Override
public void afterPropertiesSet() throws Exception {
System.out.println(" ======================implements InitializingBean 方法开始执行==================");
}
}
3.实现ApplicationListener接口,代码如下:
@Component
public class SpringContext implements ApplicationListener<ApplicationStartedEvent> {
@Override
public void onApplicationEvent(ApplicationStartedEvent event) {
System.out.println(" ======================implements ApplicationListener方法开始执行==================");
}
}
4.实现ApplicationRunner接口,代码如下:
@Component
public class SpringContext implements ApplicationRunner {
@Override
public void run(ApplicationArguments args) throws Exception {
System.out.println(" ======================implements ApplicationRunner==================");
}
}
5.实现CommandLineRunner接口,代码如下:
@Component
public class SpringContext implements CommandLineRunner {
@Override
public void run(String... args) throws Exception {
System.out.println(" ======================implements CommandLineRunner==================");
}
}
6.使用@PostConstruct注解,代码如下:
@Component
public class SpringContext {
@PostConstruct
public void run() {
System.out.println(" ======================@PostConstruc方法开始执行==================");
}
}
二、SpringBoot 通过反射获取Service
使用场景
AService 中调用 BUtil工具类中的方法,BUtil工具类中的方法此时需要查询数据库操作,查询数据库操作需要使用BService 中的 select() 接口,此时我们在BUtil 中使用 @Autowird BService bService 是不能成功注入的。
解决办法
通过实现 ApplicationContextAware 接口从容器中获取对象
反射工具类
package com.mes.material.utils;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
@Component
public class SpringBeanUtils implements ApplicationContextAware {
private static ApplicationContext context;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
context = applicationContext;
}
public static <T> T getBean(Class<T> requiredType) {
if (context == null) {
throw new IllegalStateException("spring 环境没有启动!");
}
return context.getBean(requiredType);
}
public static <T> T getBean(String beanName, Class<T> requiredType) {
if (context == null) {
throw new IllegalStateException("spring 环境没有启动!");
}
return context.getBean(beanName, requiredType);
}
public static ApplicationContext getContext() {
if (context == null) {
throw new IllegalStateException("spring 环境没有启动!");
}
return context;
}
}
使用方法
package com.mes.material;
import com.mes.material.domain.vo.MaterialStatisticsVo;
import com.mes.material.quartz.service.impl.IMaterialEanConfigImpl;
import com.mes.material.service.impl.IMaterialStatisticsServicesImpl;
import com.mes.material.service.impl.IMaterialInventoryPlanServiceImpl;
import com.mes.material.utils.SpringBeanUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
/**
* @author best_liu
* @version 1.0
* @date 2021/9/29
*/
@Component
@Order(value = 1)
@Slf4j
public class MaterialStatisticsStartUp implements ApplicationRunner {
private IMaterialStatisticsServicesImpl materialStatisticsServicesImpl;
@Override
public void run(ApplicationArguments args) throws Exception {
try {
materialStatisticsServicesImpl = SpringBeanUtils.getBean("IMaterialStatisticsServicesImpl", IMaterialStatisticsServicesImpl.class);
MaterialStatisticsVo materialStatisticsVo = new MaterialStatisticsVo();
materialStatisticsServicesImpl.materialStatistics(materialStatisticsVo);
} catch (Exception e) {
log.error("线程错误!", e);
}
}
}