一个领导看了就能涨薪的解耦编程新技能

简介: 今天要给大家介绍一个新的编程技能,基于事件驱动来编程。 在spring容器中,提供了一种事件机制,帮助springbean之间进行通信。他提供了一系列基础类,简化了程序员的事件功能开发,通过事件机制可以将我们的程序代码进行解耦,下面我们就让我们开始了解下Spring的事件机制吧。

hello大家好,今天要给大家介绍一个新的编程技能,基于事件驱动来编程。 在spring容器中,提供了一种事件机制,帮助springbean之间进行通信。他提供了一系列基础类,简化了程序员的事件功能开发,通过事件机制可以将我们的程序代码进行解耦,下面我们就让我们开始了解下Spring的事件机制吧。

1、事件源:ApplicationEvent

java复制代码public abstract class ApplicationEvent extends EventObject {  
//记录事件发生时间  
private final long timestamp;  
public ApplicationEvent(Object source) {       
    this.timestamp = System.currentTimeMillis();  
}    
public final long getTimestamp() {
    return this.timestamp;  
}
}

2、事件监听器:ApplicationListener

java复制代码public interface ApplicationListener<E extends ApplicationEvent> extends EventListener 
{  
// 事件处理方法  
void onApplicationEvent(E event);
}

3、事件发布器:ApplicationEventPublisher

java复制代码public interface ApplicationEventPublisher 
{
default void publishEvent(ApplicationEvent event) {
publishEvent((Object) event);  
}
void publishEvent(Object event);
}

先做个总结:通过上面3个基础抽象类和接口,就可以实现在spring容器内发布事件了

例子:

1、自定义黑名单处理事件

java复制代码public class BlackListEvent extends ApplicationEvent {
     private final String address;    
     private final String content;  
     public BlackListEvent(Object source, String address, String content) {   
     this.address = address;
     this.content = content;    
}
}

2、邮件发布者

java复制代码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;
        }
        // do send email...
    }
}

3、黑名单监听器处理

java复制代码public class BlackListNotifier implements ApplicationListener<BlackListEvent> {
    private String notificationAddress;
    public void setNotificationAddress(String notificationAddress) {
        this.notificationAddress = notificationAddress;
    }
    //该方法接受参数化类型BlackListEvent,避免了向下转型,保证类型安全
    public void onApplicationEvent(BlackListEvent event) {
        // 黑名单处理逻辑
    }
}

通过上面三步,就可以完成事件发布监听了,是不是很简单。不过需要注意的是,这里的事件监听器是同步的,也就是会阻塞事件发布者,直到事件监听器处理完毕。

Spring内置事件列表

上面是自自定义的事件,其实在spring 中内置了几种事件:

contextRefreshedEvent

该事件是在spring容器初始化后触发的,比如
ConfigurableApplicationContext容器的refresh()方法调用

ContextStartedEvent

该事件是在spring容器开始启动后触发的,比如
ConfigurableApplicationContext容器的start()方法调用

ContextStoppedEvent

该事件是在spring容器停止后触发的,比如
ConfigurableApplicationContext容器的stop()方法调用

ContextClosedEvent

该事件是在spring容器停止后触发的,比如
ConfigurableApplicationContext容器的close()方法调用,spring容器close后,是不能恢复的

RequestHandledEvent

该事件是spring web应用中,对于web请求完成后触发的事件

ServletRequestHandledEvent

他是RequestHandledEvent的子类触发时机是一样的

### 基于注解实现事件


上面我们是通过实现spring接口来实现事件监听功能的,在Spring 4.2之后,spring提供了基于注解的方式来定义和实现事件监听功能,我们只需要将监听器类重新成如下,一样可以实现监听器的效果:

java复制代码public class BlackListNotifier {    
    private String notificationAddress;
    public void setNotificationAddress(String notificationAddress) {                    this.notificationAddress = notificationAddress;
    }    
    @EventListener
    public void processBlackListEvent(BlackListEvent event) {
         //黑名单事件处理
    }
}

没错,就是通过@EventListener注解来完成监听器的注册,同时该注解还支持监听指定多个事件类型监听需要的事件:

java复制代码@EventListener({ContextStartedEvent.class, ContextRefreshedEvent.class})
public void handleContextStart() {

或者el表达式参数来过滤需要监听的事件:

java复制代码@EventListener(condition = "#blEvent.content == 'my-event'")
public void processBlackListEvent(BlackListEvent blEvent) {
    // notify appropriate parties via notificationAddress...
}

如果监听事件之后,需要再次发布事件,只要将监听器方法返回对应的事件对象,spring容器将自动对该事件进行发布,例如:

java复制代码@EventListener
public ListUpdateEvent handleBlackListEvent(BlackListEvent event) {
    // notify appropriate parties via notificationAddress and
    // then publish a ListUpdateEvent...
}
像上面一样,ListUpdateEvent事件将在handleBlackListEvent事件处理完成后自动发布,如果需要发布多个事件还可以将返回的对象变成集合类型。
spring还支持事件顺序,只需要在监听器方法上加上@Order注解即可,例如:
```java
@EventListener
@Order(42)
public void processBlackListEvent(BlackListEvent event) {
    // notify appropriate parties via notificationAddress...
}

异步事件支持

上文介绍到spring事件默认是同步的,其实spring也支持异步的处理事件,只需要添加异步支持(开启Spring TaskExecutor)并且添加@Async注解即可开启异步的处理事件

java复制代码@Async
public void processBlackListEvent(BlackListEvent event) {
    // BlackListEvent is processed in a separate thread
}

总结

Spring提供了比较简单事件基础类让Spring bean之间可以通信,让程序员很容易实现事件的发布,监听,支持顺序监听,异步监听,通过事件监听也可以使我们的程序进行解耦。 这种编码方式是你喜欢的吗,可以在合适的场景试一试。

好了,Spring的事件机制就介绍到这里了,大家有没有问题啊,欢迎留言探讨!!

相关文章
|
程序员 项目管理
程序员如何做好个人职业规划彻底摆脱焦虑?
程序员如何做好个人职业规划彻底摆脱焦虑?
151 0
|
4月前
|
设计模式 安全 C语言
软件工程师,全面思考问题很重要
软件工程师,全面思考问题很重要
58 9
|
5月前
|
Java 程序员 Spring
一个领导看了就能涨薪的解耦编程新技能
该文章主要介绍了Spring框架中的事件驱动编程技巧,这是一种低耦合的编程方式,能够帮助提高代码的质量和维护性。
代码之美:从混乱到秩序的编程旅程
在编程的世界里,代码不仅仅是冷冰冰的文字和符号的组合。它们是思想的载体,是解决问题的工具,更是艺术与科学的结晶。本文将带你领略编程过程中的美学,从最初的混乱无序到最终的清晰有序,探索如何通过良好的设计原则、清晰的逻辑结构以及持续的重构来提升代码质量,从而使得代码不仅能够高效运行,还能成为令人赏心悦目的艺术品。
|
文字识别 算法 NoSQL
读书分享:《程序员修炼之道:通向务实的最高境界》的思想经验
相较于全书众多的干货笔记,这篇文章是个别思想经验的总结,希望和大家交流。 ETC;DRY不仅限于编码;维护一个项目概念列表;帮助业务方理解他想要什么;防御性编程;继承税;学会沟通;小实验
读书分享:《程序员修炼之道:通向务实的最高境界》的思想经验
|
程序员 容器
程序员基本素养和特质
程序员基本素养和特质
|
存储 程序员 项目管理
六年团队Leader实战秘诀|程序员最重要的八种软技能
笔者在带团队的六年中发现,程序员们在职场都有一个共同的困扰:“好像写代码都没什么问题了,日常工作基本上都是应付业务需求的开发,好像找不到其他的更大的附加价值了,我应该找一些什么样的发力点才能让我的价值更突出呢?” 。本文将和大家聊聊程序员的软技能。
六年团队Leader实战秘诀|程序员最重要的八种软技能
|
NoSQL 前端开发 Java
学习者的窘境:程序员如何有效学习才能有成就感
学习者的窘境:程序员如何有效学习才能有成就感
159 0
学习者的窘境:程序员如何有效学习才能有成就感
|
程序员
程序员转管理岗你需要了解的管理学常识
  既然我们要探讨“技术人如何做管理”这个话题,那么对“什么是管理”以及“管理是干什么的”这个问题就无法回避。虽然“管理”这个概念很模糊,但是我们依然可以通过界定管理者的核心职责,来刻画出管理的含义。   在管理学的发展史上,有很多彪炳史册的管理大师,我们不妨看看,管理界这几位泰斗级人物是怎么说的。   古典管理理论的代表亨利·法约尔认为,“管理是由五个要素组成的一种普遍的人类活动,这五个要素是:计划、组织、指挥、协调和控制”。不难看出,他特别关注管理的过程性,强调“做事”的可控性,不愧为“管理过程学派”的创始人。“科学管理之父”弗雷德里克·泰勒认为,“管理就是确切地知道你要别人干什么,
180 0