在Spring中发布自定义事件
本文内容纲要:在Spring中发布自定义事件
在Java中,事件机制的实现包括三个基本组件,事件、事件发布者和事件监听者。在Spring中,事件机制的实现也同样包括这三个基本组件,但 Spring框架对这些组件实现了高层封装和抽象,使得事件的发布过程非常的简单,而且降低了组件之间的耦合性。但事情总没有完美的,事件组件和 Spring框架之间的耦合则不可避免。不管怎样,Spring还是帮助我们简单而优雅的实现了事件机制。下面就来看看如何在Spring中实现自定义事 件的发布和监听。
假设这样一个场景:新学期开了一门新课,学生要通过注册取得上课的资格,课程不可能接受太多的学生,当注册人数达到一定数量后,就不再允许注册这门课程了(我们这门新课只接受7个学生,先到先得哦)。
先实现和事件没关系的组件——课程,代码如下:
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