前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Spring IoC 容器事件

Spring IoC 容器事件

作者头像
李鸿坤
发布于 2020-07-20 01:48:47
发布于 2020-07-20 01:48:47
57200
代码可运行
举报
文章被收录于专栏:泛泛聊后端泛泛聊后端
运行总次数:0
代码可运行

Spring容器除了提供Bean的生命周期扩展点,还需要提供容器的生命周期扩展点。容器不像bean一样是由开发者定义的。框架代码编写的时候并不知道谁会关心。所以Spring采用的方式是将容器的生命周期通过事件机制发布出来,关心事件的开发者自行订阅。这是一个观察者模式的典型应用。

场景

看一个简单的场景。有动态配置A,当它发生变化的时候需要按配置重新组织一个责任链的顺序,如果配置错误则不生效,使用上一次的配置并且告警。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class EhanceFilterChain implements ApplicationContextAware {
  
  private ApplicationContext applicationContext;
  
  public List<IFilter> filterList;
  
  /**
   *  filter顺序的动态配置
   **/
  @DynamicValue(key="ehance_filter_chain_filters")
  public String filterListConfig;
  
  /**
   *  动态配置变化监听函数
   **/
  @DynamicValueListerner(key="ehance_filter_chain_filters")
  public void orderFilterList(){
    // 动态配置变更,组织责任链。如果配置错误则告警
    List<IFilter> filterListNew = new ArrayList<IFilter>();
    try{
      for(...){
               filterListNew.add(applicationContext.getBean("filterBeanName"));
            }
            this.filterList = filterListNew;
    }
    catch(Exception ex){
      ///  monitor alert
    }
    
  }
  
  @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }
  
}

那么问题来了,如果配置错误,还没处理前,应用被重启,处理错误导致责任链为空,容器正常启动,服务正常暴露出去。在关键业务这种情况是不允许的。启动中如果解析错误则需要让服务停止对外暴露。那么应该如何判断容器是否是启动或者bean刷新呢 ?

解决

Spring容器提供了容器的事件机制,能够监听容器的生命周期事件。只需要实现ApplicationListener接口。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class EhanceFilterChain implements ApplicationListener<ContextRefreshedEvent> {
  // 省略其他
  @Override
    public void onApplicationEvent(ContextRefreshedEvent contextRefreshedEvent) {
        ApplicationContext context = contextRefreshedEvent.getApplicationContext();
        if(context.getParent() == null){
           List<IFilter> filterListNew = new ArrayList<IFilter>();
            try{
                for(...){
                   filterListNew.add(applicationContext.getBean("filterBeanName"));
                }
                this.filterList = filterListNew;
            }
            catch(Exception ex){
              // 关闭服务
                context.close();
            }
        }
    }
}
容器事件

Spring容器事件是一个典型的观察者模式,它提供了一种容器的扩展机制。内置的容器事件有ContextRefreshedEvent ContextStartedEvent ContextStoppedEvent ContextClosedEvent

分别对应着容器生命周期的 refresh、start、stop、和close方法。同时它还提供了开发者自定义事件的方法。

首先需要定义一个事件,继承自ApplicationEvent

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class BlackListEvent extends ApplicationEvent {

    private final String address;
    private final String content;

    public BlackListEvent(Object source, String address, String content) {
        super(source);
        this.address = address;
        this.content = content;
    }

    // accessor and other methods...
}

接着定义一个被观察者,它需要有一个ApplicationEventPublisher来发布事件,容器提供了一个接口ApplicationEventPublisherAware来注入ApplicationEventPublisher。而ApplicationEventPublisher使用publishEvent方法发布事件。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class EmailService implements ApplicationEventPublisherAware {

    private List<String> blackList;
    private ApplicationEventPublisher publisher;

    public void setBlackList(List<String> blackList) {
        this.blackList = blackList;
    }

    public void setApplicationEventPublisher(ApplicationEventPublisher publisher) {
        this.publisher = publisher;
    }

    public void sendEmail(String address, String content) {
        if (blackList.contains(address)) {
            publisher.publishEvent(new BlackListEvent(this, address, content));
            return;
        }
        // send email...
    }
}

事件能够发布以后,就需要实现一个或者多个观察者。它们都需要实现ApplicationListener接口,在收到事件后进行对应的处理。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class BlackListNotifier implements ApplicationListener<BlackListEvent> {

    private String notificationAddress;

    public void setNotificationAddress(String notificationAddress) {
        this.notificationAddress = notificationAddress;
    }

    public void onApplicationEvent(BlackListEvent event) {
        // notify appropriate parties via notificationAddress...
    }
}

其他的事情是由Spring容器代劳的,开发者只需要关心事件的发布和订阅。并且两种动作是可以解耦的。发布者并不知道订阅者的存在。

缺点

容器事件可以做到设计的解耦,但是通知范围仅仅存在于容器内部,或者说是单进程内。它只能做代码级别的解耦。在分布式环境中用处并不大。分布式环境下的事件通知还是要使用消息队列中间件

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-06-15,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 泛泛聊后端 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
Ubuntu 18.04+RTX2080Ti+CUDA10.1+CUDNN7.6.5+Pytorch1.3环境部署(详细教程)
修正:Ubuntu 18.04+RTX2080Ti建议安装cuda10.0,cudnn7.5.1,pytorch1.4.0+cu100 / torchvision0.5.0+cu100,tensorflow-gpu1.14.0 修正日期:20200611
全栈程序员站长
2021/04/07
1K0
解决Ubuntu循环登陆问题 + Nvidia驱动、Cuda、Cudnn安装
ubuntu系统显卡驱动偶尔会出现奇怪的问题,造成图形用户界面循环登陆,本文记录相关问题的解决方案。 卸载旧驱动 在登陆界面 ctrl+alt+F2 进入非图形界面控制台,登陆后输入命令: sudo apt-get remove nvidia-* sudo apt-get autoremove sudo apt-get purge nvidia* 安装驱动 加入PPA,然后更新库 sudo add-apt-repository ppa:graphics-drivers sudo apt-get
为为为什么
2022/08/05
1K0
Ubuntu 20.04 CUDA&cuDNN安装方法[通俗易懂]
如果无法查看,则说明尚未安装nvidia驱动,点击附加驱动,选择对应版本的驱动即可自动下载。
全栈程序员站长
2022/07/01
1K0
Ubuntu 20.04 CUDA&cuDNN安装方法[通俗易懂]
手把手教你在 Ubuntu16.04 安装 GPU 驱动 + CUDA9.0 + cuDNN7
如果你的电脑安装了 Ubuntu16.04,而且电脑自带一块 NVIDIA GeForce 的 GPU 显卡,那么不用来跑深度学习模型就太可惜了!关于这方面的网上教程很多,但大都良莠不齐。这篇文章将手把手教你如何安装 GPU 显卡驱动、CUDA9.0 和 cuDNN7。值得一试!
红色石头
2022/01/12
6.9K0
手把手教你在 Ubuntu16.04 安装 GPU 驱动 + CUDA9.0 + cuDNN7
Ubunt16.04 搭建 GPU 显卡驱动 + CUDA9.0 + cuDNN7 详细教程
如果你的电脑安装了 Ubuntu16.04,而且电脑自带一块 NVIDIA GeForce 的 GPU 显卡,那么不用来跑深度学习模型就太可惜了!关于这方面的网上教程很多,但大都良莠不齐。这篇文章将手把手教你如何安装 GPU 显卡驱动、CUDA9.0 和 cuDNN7。值得一试!
红色石头
2022/01/12
7890
Ubunt16.04 搭建 GPU 显卡驱动 + CUDA9.0 + cuDNN7 详细教程
深度学习GPU环境安装教程:Ubuntu16.04+1080(Ti)显卡驱动+CUDA+cuDNN(已n次完美安装)
当前只装了ubuntu16.04单系统,亲测可用,之前ubuntu16.04+win10双系统下也是这种方法装的,只是需要切换视频线的接口,可参考这篇
对角巷法师
2022/05/07
1.5K0
深度学习GPU环境安装教程:Ubuntu16.04+1080(Ti)显卡驱动+CUDA+cuDNN(已n次完美安装)
Ubuntu下安装cuda_Ubuntu下KDE的安装删除
若没有安装,则查看是否有N卡驱动,若无N卡驱动,则到软件与更新 -> 附加驱动中安装驱动
全栈程序员站长
2022/11/09
9420
Ubuntu下安装cuda_Ubuntu下KDE的安装删除
点云深度学习环境配置指南(一)Ubuntu16.04+RTX2080ti
【今日导读】想做点云深度学习?先把环境配置好吧。本期为初学者带来环境配置指南,有需求的同学赶快上手吧。配置为:
点云乐课堂
2020/05/18
1.3K0
Ubuntu 16.04下为TITAN 1080 显卡安装驱动及Gpu版TensorFlow|深度学习
近来入坑了TITAN 1080显卡,在Ubuntu 16.04下为装好驱动以使用Gpu版TensorFlow可不简单,踩了许多坑之后写下此篇为记录。 下载Cuda 按装官方教程,我们可以应该安装Cu
陆勤_数据人网
2018/02/28
1.5K0
Ubuntu 16.04下为TITAN 1080 显卡安装驱动及Gpu版TensorFlow|深度学习
Ubuntu18.04安装 NVIDIA驱动+CUDA10.2+cuDNN+TensorRT
之后,按照提示安装,成功后重启即可。 如果提示安装失败,不要着急重启;可重复上述步骤,多试几次。
全栈程序员站长
2022/08/19
2K0
深度学习GPU环境Ubuntu16.04+GTX1080+CUDA9+cuDNN7+TensorFlow1.6环境配置
本节详细说明一下深度学习环境配置,Ubuntu 16.04 + Nvidia GTX 1080 + Python 3.6 + CUDA 9.0 + cuDNN 7.1 + TensorFlow 1.6。 Python 3.6 首先安装 Python 3.6,这里使用 Anaconda 3 来安装,下载地址:https://www.anaconda.com/download/#linux,点击 Download 按钮下载即可,这里下载的是 Anaconda 3-5.1 版本,如果下载速度过慢可以选择使用清华
崔庆才
2018/04/08
2.1K0
深度学习GPU环境Ubuntu16.04+GTX1080+CUDA9+cuDNN7+TensorFlow1.6环境配置
Ubuntu安装和卸载CUDA和CUDNN
最近在学习PaddlePaddle在各个显卡驱动版本的安装和使用,所以同时也学习如何在Ubuntu安装和卸载CUDA和CUDNN,在学习过程中,顺便记录学习过程。在供大家学习的同时,也在加强自己的记忆。本文章以卸载CUDA 8.0 和 CUDNN 7.05 为例,以安装CUDA 10.0 和 CUDNN 7.4.2 为例。
夜雨飘零
2020/05/06
10.3K0
ubuntu16.04安装cuda9.0(ubuntu18安装nvidia驱动)
Ubuntu 下安装CUDA需要装NVIDIA驱动,首先进入NVIDIA官网,然后查询对应NVIDIA驱动是否支持你电脑的型号。
全栈程序员站长
2022/07/29
7630
ubuntu16.04安装cuda9.0(ubuntu18安装nvidia驱动)
深度学习之CUDA + cudnn
CUDA官网: https://developer.nvidia.com/cuda-downloads
数据科学工厂
2023/02/27
4100
深度学习之CUDA + cudnn
Ubuntu18.04LTS下cuda10.0+cudnn7.5+TensorFlow1.13环境搭建
前言 之前写过cuda环境的搭建文章, 这次干脆补全整个深度学习环境的搭建. ---- 开发环境一览 CPU: Intel core i7 4700MQ GPU: NVIDIA GT 750M
sean_yang
2019/03/15
2K0
Ubuntu18.04LTS下cuda10.0+cudnn7.5+TensorFlow1.13环境搭建
真实机下 ubuntu 18.04 安装GPU +CUDA+cuDNN 以及其版本选择(亲测非常实用)
目前,大多情况下,能搜到的基本上都ubuntu 14.04.或者是ubuntu 16.04的操作系统安装以及GPU 环境搭建过程,博主就目前自身实验室环境进行分析,总结一下安装过程。
全栈程序员站长
2022/08/20
2K0
真实机下 ubuntu 18.04 安装GPU +CUDA+cuDNN 以及其版本选择(亲测非常实用)
纯净Ubuntu16安装CUDA(9.1)和cuDNN
本篇概览 自己有一台2015年的联想笔记本,显卡是GTX950M,已安装ubuntu 16.04 LTS桌面版,为了使用其GPU完成deeplearning4j的训练工作,自己动手安装了CUDA和cuDNN,在此将整个过程记录下来,以备将来参考,整个安装过程分为以下几步: 准备工作 安装Nvidia驱动 安装CUDA 安装cuDNN 特别问题说明 按照一般步骤,在安装完Nvidia显卡驱动后,会提示对应的CUDA版本,接下来按照提示的版本安装CUDA,例如我这里提示的是11.2,正常情况下,我应该安装11.
程序员欣宸
2021/12/07
6750
纯净Ubuntu16安装CUDA(9.1)和cuDNN
Ubuntu 16.04 上 CUDA_10.0及cuDNN的安装
GPU:Geforce GTX1060 驱动版本:418.56 最开始打算装CUDA_10.1( nvidia与cuda需相匹配),但是在运行cuda.run后出现的用户许可证信息有问题,如图
全栈程序员站长
2022/08/14
1.7K0
Ubuntu 16.04 上 CUDA_10.0及cuDNN的安装
Ubuntu20.04安装cuda10.1「建议收藏」
CUDA的主要用途是深度学习,而目前主流的深度学习框架Tensorflow2最高支持CUDA 10.1,因此本文讲解在Ubuntu 20.04系统上安装CUDA 10.1的主要过程。
全栈程序员站长
2022/09/29
1.6K0
Ubuntu20.04安装cuda10.1「建议收藏」
Ubuntu 安装 tensorflow-gpu 1.4 +CUDA 8.0 +cuDNN详细教程
作者 | fendouai 编辑 | 磐石 出品 | 磐创AI技术团队 【磐创AI导读】:本文详细介绍了tensorflow-gpu在Ubuntu下的安装步骤。欢迎大家点击上方蓝字关注我们的公众号:磐创AI。 硬件环境:NVIDIA GTX 980 Ti 系统环境:Ubuntu 16.04 64位 一.安装 NVIDIA驱动 1. 关闭 Secure Boot 具体如何禁用 BIOS 中的 Secure Boot 要根据主板的情况。 以华硕主板的禁用方法为例: 首先进入 BIOS,然后选择 Boot ,
磐创AI
2018/07/03
1.5K0
推荐阅读
相关推荐
Ubuntu 18.04+RTX2080Ti+CUDA10.1+CUDNN7.6.5+Pytorch1.3环境部署(详细教程)
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档