观察者模式
当对象间存在一对多关系时,则使用观察者模式(Observer Pattern)。比如,当一个对象被修改时,则会自动通知它的依赖对象。观察者模式属于行为型模式。
意图:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
主要解决:一个对象状态改变给其他对象通知的问题,而且要考虑到易用和低耦合,保证高度的协作。
下面我将实现一个用cglib动态代理实现对一个对类的观察,当该类调用设置的方法后将会触发一个回调
希望大家对jdk1.8的特性有了解比如lamda表达式,因为下面会用到
首先定位一个接口,接口中定义回调方法
public interface Observer {
void callback();
}
编写一个被观察的对象
public class Subject {
private String state;
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
}
编写一个事件的注册器
/**
* 事件注册器
*/
public class EventListeners {
private static Map<Class<?>, Map<Method, List<Observer>>> events = new HashMap<>();
public static void addListener(Class<?> subject, Method method, List<Observer> observer) {
Map<Method, List<Observer>> methodMapMap = events.get(subject);
if (methodMapMap != null) {
checkObjectHaveMethodAndPutObserver(subject, method, observer, methodMapMap);
}else {
Map<Method,List<Observer>> methedsObservers=new HashMap<>();
checkObjectHaveMethodAndPutObserver(subject, method, observer, methedsObservers);
events.put(subject,methedsObservers);
}
}
private static void checkObjectHaveMethodAndPutObserver(Class<?> subject, Method method, List<Observer> observer, Map<Method, List<Observer>> methodMapMap) {
Arrays.stream(subject.getDeclaredMethods()).forEach(e->{
if (e.getName().equals(method.getName())){
methodMapMap.put(method,observer);
}
});
}
public static void notice(Class<?> object,Method method) {
Map<Method, List<Observer>> methodListMap = events.get(object);
if (methodListMap!=null){
methodListMap.get(method).forEach(e->e.callback());
}
}
public static boolean haveMethodObServer(Class<?> object,Method method){
Map<Method, List<Observer>> methodListMap = events.get(object);
if (methodListMap!=null){
List<Observer> observers = methodListMap.get(method);
if (observers!=null&&!observers.isEmpty()){
return true;
}
}
return false;
}
}
这里我用了一个Map键为Class,值为另外一个Map这个Map键为方法,值为一个回调方法的List集合
创建CGlibProSubject
public class CGlibProSubject implements MethodInterceptor {
@Override
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
String typeName = obj.getClass().getTypeName();
String myClass = typeName.substring(0, typeName.indexOf("$"));
Class<?> aClass = obj.getClass().getClassLoader().loadClass(myClass);
if (EventListeners.haveMethodObServer(aClass, method)) {
EventListeners.notice(aClass, method);
}
Object o = proxy.invokeSuper(obj, args);
return o;
}
}
测试
public class Test {
public static void main(String[] args) throws NoSuchMethodException {
Subject subject = new Subject();
Method setState = subject.getClass().getMethod("setState", String.class);
Observer observer=()->System.out.println("调用了该方法!");
Observer observer2=()->System.out.println("恭喜你又被调用了");
EventListeners.addListener(Subject.class,setState,Arrays.asList(observer,observer2));
CGlibProSubject cGlibProSubject = new CGlibProSubject();
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(Subject.class);
enhancer.setCallback(cGlibProSubject);
Subject o = (Subject) enhancer.create();
o.setState("aaa");
o.getState();
}
}
结果
调用了该方法!
恭喜你又被调用了
这里的实现可能有点复杂,简单的实现可以百度一下有很多简单的实现,学习设计模式主要是了解思想