【JDK自带Observer和Observable】观察者模式主要的好处就是降低对象之间的耦合度,我不感知你做了什么,你是什么,只要你遵循约定的接口就行了
1.观察者
package com.app.demo.observe;
import java.util.Observable;
import java.util.Observer;
import lombok.Getter;
import lombok.Setter;
public class Student implements Observer
{
@Getter
@Setter
private String name;
@Getter
@Setter
private int score;
@Getter
@Setter
private boolean finished = false;
public Student(String name)
{
this.name = name;
}
@Override
public void update(Observable o, Object arg)
{
System.out.print(name+"has been notifyed.\r\n");
}
}
2.被观察者(主题)
package com.app.demo.observe;
import java.util.List;
import java.util.Observable;
import java.util.Observer;
public class Teacher extends Observable
{
//观察者和被观察者关系绑定
public void attach(List<Observer> students)
{
students.forEach(student -> this.addObserver(student));
System.out.print(String.format("This teacher has %d students\r\n",
this.countObservers()));
}
//布置作业
public void ArrangeExam()
{
this.setChanged();
//通知观察者
this.notifyObservers();
}
}
3.test类
package com.app.demo.observe;
import java.util.Arrays;
public class Event
{
public static void main(String[] args)
{
Teacher teacher = new Teacher();
Student zhangsan = new Student("zhangsan");
Student lisi = new Student("liis");
Student wangwu = new Student("wangwu");
teacher.attach(Arrays.asList(zhangsan,lisi,wangwu));
teacher.ArrangeExam();
}
}
【Spring中的事件机制】
如下程序,ApplicationEventPublisher 是个接口,那么其具体实现类是谁呢?debug发现是AnnotationConfigEmbeddedWebApplicationContext,也就是bean容器,也就是teacher把publish任务代理给了spring
1.观察者
package com.app.demo.event;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;
@Component
public class Lisenter implements ApplicationListener<MyEvent> {
public void onApplicationEvent(MyEvent event) {
System.out.println("Lisenter has been notifyed," + event.getTopic());
}
}
package com.app.demo.event;
import lombok.Getter;
import lombok.Setter;
public class Student {
@Setter
@Getter
private String name;
@Getter
@Setter
private int score;
public Student(String name) {
this.name = name;
}
}
2.事件发布者
package com.app.demo.event;
import java.util.List;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;
import org.springframework.stereotype.Component;
import lombok.Getter;
import lombok.Setter;
@Component
public class Teacher implements ApplicationEventPublisherAware {
@Setter
@Getter
private List<Student> students;
@Getter
@Setter
private ApplicationEventPublisher publisher;
public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
this.publisher = applicationEventPublisher;
}
}
3.事件
package com.app.demo.event;
import org.springframework.context.ApplicationEvent;
import lombok.Getter;
import lombok.Setter;
public class MyEvent extends ApplicationEvent{
@Getter
@Setter
private String topic;
/**
*
*/
private static final long serialVersionUID = 719028814464386671L;
public MyEvent(Teacher source) {
super(source);
String summry = "Teacher will take a exam!";
topic = summry;
System.out.println(summry);
}
}
4.Test类
package com.app.demo.event;
import java.util.Arrays;
import javax.annotation.PostConstruct;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class Test {
@Autowired
private Teacher teacher;
@PostConstruct
private void run() {
Student zhangsan = new Student("zhangsan");
Student lisi = new Student("liis");
Student wangwu = new Student("wangwu");
teacher.setStudents(Arrays.asList(zhangsan, lisi, wangwu));
teacher.getPublisher().publishEvent(new MyEvent(teacher));
}
}