spring中实现容器加载完成后再执行自己的方法

 更新时间:2023年02月16日 08:58:33   作者:阿文_ing  
这篇文章主要介绍了spring中实现容器加载完成后再执行自己的方法,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

spring容器加载完成后再执行自己的方法

在开发过程中遇到了要在项目启动后自动开启某个服务,由于使用了spring,我在使用了spring的 listener ,它有 onApplicationEvent ()方法, 在Spring容器将所有的Bean都初始化完成之后,就会执行该方法 。

应用场景

很多时候我们想要在某个类加载完毕时干某件事情,但是使用了spring管理对象,我们这个类引用了其他类(可能是更复杂的关联),所以当我们去使用这个类做事情时发现包空指针错误,这是因为我们这个类有可能已经初始化完成,但是引用的其他类不一定初始化完成,所以发生了空指针错误

解决方案如下    

1.写一个类继承spring的ApplicationListener监听,并监控ContextRefreshedEvent事件(容易初始化完成事件)    

2.定义简单的bean:<bean id="startListener" class="com.itsm.core.service.table.StartListener"></bean> 或者直接使用@Service注解方式

@Service
public class StartListener implements ApplicationListener<ContextRefreshedEvent> {
    public static final Map<Integer, TableMapper> mappers = new HashMap<>();
    @Resource
    A_Mapper a_mapper;
    @Override
    public void onApplicationEvent(ContextRefreshedEvent event)
    {
        if(event.getApplicationContext().getParent() == null)//root application context 没有parent,他就是老大.
        {
            //需要执行的逻辑代码,当spring容器初始化完成后就会执行该方法。
            System.out.println("\n\n\n\n\n______________\n\n\n加载了\n\n_________\n\n");
        }
        //或者下面这种方式
        if(event.getApplicationContext().getDisplayName().equals("Root WebApplicationContext"))
        {
            System.out.println("\n\n\n_________\n\n加载一次的 \n\n ________\n\n\n\n");
        }
        mappers.put(1,a_mapper);
    }
}

spring容器加载完成之后进行开启一个线程进行数据更新操作

需求:最近做项目遇到了一个需求,数据表中有些数据需要定时更新,这样就需要启动一个线程完成,不想再新建一个项目来完成这些事,就想在spring启动之后来开启一个线程定时来完成这件事 ,直接上代码

package com.irisian.picturelabel.listener;

import com.irisian.picturelabel.service.PictureService;
import com.irisian.picturelabel.service.TaskService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

/**
 * Author:吴满心
 * Date:2018/5/18
 * Function:负责在spring容器加载完成之后进行图片和任务数据表的更新
 */
@Component
public class SpringFinishedListener implements InitializingBean {
    private static final Logger logger = LoggerFactory.getLogger(SpringFinishedListener.class);

    @Autowired
    private PictureService pictureService;

    @Autowired
    private TaskService taskService;

    @Override
    public void afterPropertiesSet() throws Exception {
        new Thread(() -> {
            while (true) {
                logger.info("开始执行图片和任务的更新操作!");
                try {
                    pictureService.updatePictureStatus();
                    //更新任务的完成状态信息
                    taskService.updateFinishStatus();
                } catch (Exception e) {
                    e.printStackTrace();
                    logger.error(e.getMessage());
                }
                try {
                    Thread.sleep(1800000);      //30分钟执行一次进行数据更新
                } catch (InterruptedException e) {
                    e.printStackTrace();
                    logger.error(e.getMessage());
                }
            }
        }).start();


    }
}

开始还尝试过servlet的方法,如

package com.irisian.picturelabel.servlet;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;

/**
 * Author:吴满心
 * Date:2018/5/18
 * Function:
 */
@WebServlet(name = "backServlet", urlPatterns = {"/backServlet"})
public class BackServlet extends HttpServlet {
    private static final Logger logger= LoggerFactory.getLogger(BackServlet.class);

    @Override
    public void init() throws ServletException {
        new Thread(()->{
            while(true){
                logger.info("我5秒钟执行一次");
                try {
                    Thread.sleep(5000);
                } catch (InterruptedException e) {
                    logger.error(e.getMessage());
                }
            }
        }).start();
    }


    @Override
    public void destroy() {
        logger.info("服务器关闭了");
    }
}

配置Configuration

package com.irisian.picturelabel.configuration;
import com.irisian.picturelabel.exception.MyExceptionResolver;
import com.irisian.picturelabel.servlet.BackServlet;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.HandlerExceptionResolver;

/**
 * Author:吴满心
 * Date:2018/5/15
 * Function:
 */
@Configuration
public class SpringConfiguration {
    @Bean
    public HandlerExceptionResolver getHandlerExceptionResolver() {
        return new MyExceptionResolver();
    }

    /**
     * 配置一个后台运行的servlet
     * @return
     */
    @Bean
    public ServletRegistrationBean servletRegistrationBean() {
        ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean(new BackServlet(), "/backServlet");
        servletRegistrationBean.setLoadOnStartup(1);        //数字越小,启动优先级越高,但是必须大于0
        return servletRegistrationBean;
    }

}

但是不满足spring启动之后,spring不启动完成,就无法使用bean了,所以就按照前面的一种方法了

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • Java使用DateTimeFormatter格式化输入的日期时间

    Java使用DateTimeFormatter格式化输入的日期时间

    这篇文章主要介绍了Java使用DateTimeFormatter格式化输入的日期时间,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-01-01
  • 不调用方法实现hutool导出excel图片示例详解

    不调用方法实现hutool导出excel图片示例详解

    这篇文章主要为大家介绍了不调用方法实现hutool导出excel图片示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-08-08
  • Java文件操作之按行读取文件和遍历目录的方法

    Java文件操作之按行读取文件和遍历目录的方法

    这篇文章主要介绍了Java文件操作之按行读取文件和递归遍历目录的方法,遍历目录文中分别举了递归和非递归的例子,需要的朋友可以参考下
    2016-03-03
  • Java语言ReadWriteLock特性实例测试

    Java语言ReadWriteLock特性实例测试

    这篇文章主要介绍了Java语言ReadWriteLock特性实例测试,分享了相关代码示例,小编觉得还是挺不错的,具有一定借鉴价值,需要的朋友可以参考下
    2018-02-02
  • java切分字符串的2种方法实例

    java切分字符串的2种方法实例

    在我们日常工作中经常遇到截取字符串的需求,下面这篇文章主要给大家介绍了关于java切分字符串的2种方法,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2022-06-06
  • nacos客户端一致性hash负载需求实现

    nacos客户端一致性hash负载需求实现

    这篇文章主要介绍了nacos客户端一致性hash负载的需求实现过程及步骤详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步
    2022-02-02
  • 深度剖析java中JDK动态代理机制

    深度剖析java中JDK动态代理机制

    本篇文章主要介绍了深度剖析java中JDK动态代理机制 ,动态代理避免了开发人员编写各个繁锁的静态代理类,只需简单地指定一组接口及目标类对象就能动态的获得代理对象。
    2017-04-04
  • SpringBoot整合MyBatis实现乐观锁和悲观锁的示例

    SpringBoot整合MyBatis实现乐观锁和悲观锁的示例

    这篇文章主要介绍了SpringBoot整合MyBatis实现乐观锁和悲观锁的示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-09-09
  • Mac下安装配置Maven并在IDEA中配置的详细教程

    Mac下安装配置Maven并在IDEA中配置的详细教程

    这篇文章主要介绍了Mac下安装配置Maven并在IDEA中配置,本文通过图文并茂的形式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-07-07
  • SpringBoot web开发源码深入分析

    SpringBoot web开发源码深入分析

    Web开发的核心内容主要包括内嵌的Servlet容器和SpringMVCSpringBoot使用起来非常简洁,大部分配置都有SpringBoot自动装配,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习吧
    2022-10-10

最新评论