Spring中的ApplicationListener的使用详解案例


本文链接:https://blog.csdn.net/u010963948/article/details/83507185

1、ApplicationContext Spring的核心,Context我们通常解释为上下文环境。ApplicationContext则是应用的容器。 Spring把Bean(object)放在容器中,需要用就通过get方法取出来。在ApplicationContext接口的众多实现类中,有3个是我们经常用到的(见表1-1),并且使用这3个实现类也基本能满足我们Java EE应用开发中的绝大部分需求。 表1-1 ApplicationContext接口的常用实现类介绍 类 名 称 功 能 描 述 ClassPathXmlApplicationContext 从类路径ClassPath中寻找指定的XML配置文件,找到并装载完成ApplicationContext的实例化工作。例如: //装载单个配置文件实例化ApplicationContext容器 ApplicationContext cxt = new ClassPathXmlApplicationContext("applicationContext.xml"); //装载多个配置文件实例化ApplicationContext容器 String[] configs = {"bean1.xml","bean2.xml","bean3.xml"}; ApplicationContext cxt = new ClassPathXmlApplicationContext(configs); FileSystemXmlApplicationContext 从指定的文件系统路径中寻找指定的XML配置文件,找到并装载完成ApplicationContext的实例化工作。例如://装载单个配置文件实例化ApplicationContext容器 ApplicationContext cxt = new FileSystemXMLApplicationContext("beans.xml"); //装载多个配置文件实例化ApplicationContext容器 String[] configs = {"c:/beans1.xml","c:/beans2.xml"}; ApplicationContext cxt = new FileSystemXmlApplicationContext(configs); XmlWebApplicationContext 从Web应用中寻找指定的XML配置文件,找到并装载完成ApplicationContext的实例化工作。这是为Web工程量身定制的,使用WebApplicationContextUtils类的getRequiredWebApplicationContext方法可在JSP与Servlet中取得IoC容器的引用 2、ApplicationEvent 是个抽象类,里面只有一个构造函数和一个长整型的timestamp。其源码如下: public abstract class ApplicationEvent extends EventObject { /** use serialVersionUID from Spring 1.2 for interoperability */ private static final long serialVersionUID = 7099057708183571937L; /** System time when the event happened */ private final long timestamp; /** * Create a new ApplicationEvent. * @param source the object on which the event initially occurred (never {@code null}) */ public ApplicationEvent(Object source) { super(source); this.timestamp = System.currentTimeMillis(); } /** * Return the system time in milliseconds when the event happened. */ public final long getTimestamp() { return this.timestamp; } } 3、ApplicationListener 是一个接口,里面只有一个onApplicationEvent方法。如果在上下文中部署一个实现了ApplicationListener接口的bean,那么每当在一个ApplicationEvent发布到 ApplicationContext时,调用ApplicationContext.publishEvent()方法,这个bean得到通知。类似于Oberver设计模式。 其源码如下: public interface ApplicationListener<E extends ApplicationEvent> extends EventListener { /** * Handle an application event. * @param event the event to respond to */ void onApplicationEvent(E event); } 好了,这里简单介绍下我的使用方式吧。 首先创建一个自己的回调的类CallBackInfoEvent 去继承ApplicationEvent: public class CallBackInfoEvent extends ApplicationEvent { /** * Create a new ApplicationEvent. * * @param source the object on which the event initially occurred (never {@code null}) */ public CallBackInfoEvent(RiskCallBackInput input) { super(input); } } 然后创建ApplicationListener的一个实现类MyListener : @Component public class MyListener implements ApplicationListener<CallBackInfoEvent> { private static final Logger logger = LoggerFactory.getLogger(HuluReportListener.class); /** * Handle an application event. * * @param event the event to respond to */ @Override public void onApplicationEvent(CallBackInfoEvent event) { RiskCallBackInput input = (RiskCallBackInput) event.getSource(); if (StringUtils.equals(input.getType(), “1”)) { //TODO 处理业务逻辑增删改查 } } } 最后在你的业务service中通过调用以下代码是发布通知事件: @Autowired private ApplicationContext context; //TODO 业务逻辑 context.publishEvent(new CallBackInfoEvent(Object object)); ok了。
springboot以spring的方式初始化servletContext中的值
 
原文链接:https://blog.csdn.net/m0_37202351/article/details/86180998

需求:springboot 启动后自动执行某些代码,初始化数据,并将数据放到 servletContext 中。

首先,不可使用 ServletContextListener 即不能用 @WebListener ,因为 servlet 容器初始化后,spring 并未初始化完毕,不能使用 @Autowired 注入 spring 的对象。

推荐使用 ApplicationListener:启动项目, spring 加载完毕后,才执行该 ApplicationListener,并且该 Listener 中可以使用 spring 的内容。

@Component
public class SettingDataInitListener implements ApplicationListener<ContextRefreshedEvent> {
    @Override
    public void onApplicationEvent(ContextRefreshedEvent contextRefreshedEvent) {
        // 将 ApplicationContext 转化为 WebApplicationContext 
        WebApplicationContext webApplicationContext = 
            (WebApplicationContext)contextRefreshedEvent.getApplicationContext();
        // 从 webApplicationContext 中获取  servletContext 
        ServletContext servletContext = webApplicationContext.getServletContext();
        // servletContext设置值
        servletContext.setAttribute("key", "value");
    }
}
 ————————————————