在Spring中发布自定义事件

本文内容纲要:在Spring中发布自定义事件

在Java中,事件机制的实现包括三个基本组件,事件、事件发布者和事件监听者。在Spring中,事件机制的实现也同样包括这三个基本组件,但 Spring框架对这些组件实现了高层封装和抽象,使得事件的发布过程非常的简单,而且降低了组件之间的耦合性。但事情总没有完美的,事件组件和 Spring框架之间的耦合则不可避免。不管怎样,Spring还是帮助我们简单而优雅的实现了事件机制。下面就来看看如何在Spring中实现自定义事 件的发布和监听。

假设这样一个场景:新学期开了一门新课,学生要通过注册取得上课的资格,课程不可能接受太多的学生,当注册人数达到一定数量后,就不再允许注册这门课程了(我们这门新课只接受7个学生,先到先得哦在Spring中发布自定义事件)。

先实现和事件没关系的组件——课程,代码如下:

public class Course {

public static final int MAX_CAPACITY = 7;

private int capacity = 0;

public Course() {}

public int getCapacity() {

return capacity;

}

public void addNewStudent() {

this.capacity++;

}

}

接着实现事件的三个基本组件,首先事件是事件机制的核心,先实现它。这里实现了两个事件RegisteredEvent和 CourseFullEvent,分别表示注册成功事件和课程已满事件。在Spring中,所有事件都继承自抽象类ApplicationEvent。我 们不需要这两个事件做什么,所以它们的代码很简单。

public class RegisteredEvent extends ApplicationEvent {

public RegisteredEvent(Object arg0) {

super(arg0);

}

}

public class CourseFullEvent extends ApplicationEvent {

public CourseFullEvent(Object arg0) {

super(arg0);

}

}

第二个组件是事件发布者,也就是课程注册服务。在Spring中发布事件当然要通过容器来发布,这样容器内的监听器组件才会知道事件发生了。 BeanFactory容器没有发布事件的功能,所以就要用特性更为丰富的ApplicationContext。而容器中的Java对象要想知道它所在 的容器,就一定要实现ApplicationContextAware接口,因此这个对象就难免要和Spring框架建立联系了,为了实现发布事件的功 能,与框架的耦合在所难免。

public interface StudentService {

void register(Course course, Student student);

}

public class StudentServiceImpl implements StudentService,

ApplicationContextAware {

private ApplicationContext context;

public void setApplicationContext(ApplicationContext arg0)

throws BeansException {

this.context = arg0;

}

public void register(Course course, Student student) {

int capacity = course.getCapacity();

if (++capacity > Course.MAX_CAPACITY) {

System.out.println("该课程已经人满,注册失败");

context.publishEvent(new CourseFullEvent(this));

} else {

course.addNewStudent();

student.setStudentId(course.getCapacity());

System.out.println("恭喜您,注册成功");

context.publishEvent(new RegisteredEvent(this));

}

}

}

Spring容器会自动地通过set方法把自己注入到实现了ApplicationContextAware接口的对象中,这样 StudentService的实现就可以通过所在的容器发布任何事件了,很简单,调用容器的publishEvent方法并传入所要发布的事件就行了。

最后要实现的组件就是监听者了,也就是Student,它实现了ApplicationListener接口,并把自己注册到Spring容器中。当事件 发生时,容器会通知它里面的监听者,Student收到事件通知,在onApplicationEvent方法中,判断事件类型,并对事件做出响应。 Student的代码如下:

public class Student implements ApplicationListener {

private int studentId;

public Student() {}

public void onApplicationEvent(ApplicationEvent arg0) {

if (arg0 instanceof RegisteredEvent) {

System.out.println("太好了,我注册的学号是" + this.studentId);

} else if (arg0 instanceof CourseFullEvent) {

System.out.println("来晚了,我没注册上");

}

}

public void setStudentId(int studentId) {

this.studentId = studentId;

}

}

当然,别忘了Spring的配置文件:




最后,写个小应用运行一下,看看效果如何:

public class SpecialBeanApp {

public static void main(String[] args) {

ApplicationContext ctx = new ClassPathXmlApplicationContext(

"applicationContext.xml");

// 开一门课

Course course = (Course) ctx.getBean("course");

// 开启注册课程的服务

StudentService service = (StudentService) ctx.getBean("studentService");

// 注册10个学生

for (int i = 0; i < 10; i++) {

Student student = (Student) ctx.getBean("student");

service.register(course, student);

}

}

}

最后再说明一点,Spring的事件机制是同步的,也就是阻塞式的,所以,对事件的处理要尽量简单快捷,否则会极大的影响应用程序的性能。我们期待着Spring2.0的后续版本能实现异步的事件机制。

本文内容总结:在Spring中发布自定义事件

原文链接:https://www.cnblogs.com/kinbos/archive/2013/02/27/2934650.html

以上是 在Spring中发布自定义事件 的全部内容, 来源链接: utcz.com/z/296581.html

回到顶部