SpringBoot项目启动执行任务及通过反射获取Service

一、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);
        }
    }
}

猜你喜欢

转载自blog.csdn.net/askuld/article/details/130967302
今日推荐