基于EventBus核心原理的简单实现

通过对EventBus源码分析,剥离出核心api的实现:

1、EventBus.getDefault():EventBus的单例实现,保证全局只有一个EventBus类实例;

2、register():事件订阅者的注册

3、post():消息的发送

4、unregister():事件订阅者的注销

注:不考虑不同线程之间的消息发送,不考虑发送消息的优先级以及其他防止内存泄漏的优化处理等。

代码实现:

注解类:

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface EventM {
}

记录一个类以及对应的所有方法的类:目的是方便遍历每个类中的方法

import java.lang.reflect.Method;

public class ObjAndMethod {
    Method method;
    Object object;

    public ObjAndMethod(Method method, Object object) {
        this.method = method;
        this.object = object;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj instanceof ObjAndMethod) {
            ObjAndMethod objAndMethod = (ObjAndMethod) obj;
            return method.equals(objAndMethod.method) && object == objAndMethod.object;
        } else {
            return false;
        }
    }

    @Override
    public int hashCode() {
        return method.hashCode() + object.hashCode();
    }
}

核心逻辑类:

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class EventS {
    private volatile static EventS instance;
    //存放发送参数类型 与 注册类和注解方法 的对应关系
    private Map<Class<?>, List<ObjAndMethod>> paramAndObjMethedMap;
    //存放注册类 与 所有注解方法参数class 的对应关系 , 设计目的:方便paramAndObjMethedMap移除
    private Map<Object, List<Class<?>>> objAndParamMap;

    private EventS() {
        paramAndObjMethedMap = new HashMap<>();
        objAndParamMap = new HashMap<>();
    }

    public static EventS getInstance() {
        if (instance == null) {
            synchronized (EventS.class) {
                if (instance == null) {
                    instance = new EventS();
                }
            }
        }
        return instance;
    }

    <T> void register(T t) {
        Class<?> subscriberClass = t.getClass();
        //获取所有注册类中的方法
        Method[] methods = subscriberClass.getDeclaredMethods();
        for (Method method : methods) {
            //获取注册类中 被EventM 注解过的方法
            EventM eventM = method.getAnnotation(EventM.class);
            if (eventM != null) {
                //将注册类的相关信息添加到 paramAndObjMethedMap
                Class<?> paramClass = method.getParameterTypes()[0];
                List<ObjAndMethod> objAndMethodList = paramAndObjMethedMap.get(paramClass);
                if (objAndMethodList == null) {
                    objAndMethodList = new ArrayList<>();
                    paramAndObjMethedMap.put(paramClass, objAndMethodList);
                }
                ObjAndMethod objAndMethod = new ObjAndMethod(method, t);
                objAndMethodList.add(objAndMethod);

                将注册类的相关信息添加到 objAndParamMap
                List<Class<?>> classList = objAndParamMap.get(t);
                if (classList == null) {
                    classList = new ArrayList<>();
                    objAndParamMap.put(t, classList);
                }
                classList.add(paramClass);
            }
        }
    }

    <T> void unregister(T t) {
        List<Class<?>> classList = objAndParamMap.get(t);
        if (classList != null) {
            for (Class<?> aClass : classList) {
                List<ObjAndMethod> objAndMethodList = paramAndObjMethedMap.get(aClass);
                if (objAndMethodList != null) {
                    int size = objAndMethodList.size();
                    for (int i = 0; i < size; i++) {
                        ObjAndMethod objAndMethod = objAndMethodList.get(i);
                        if (objAndMethod.object == t){
                            objAndMethodList.remove(i);
                            i--;
                            size--;
                        }
                    }
                }
            }
        }
    }

    <T> void post(T t) {
        List<ObjAndMethod> objAndMethodList = paramAndObjMethedMap.get(t.getClass());
        if (objAndMethodList != null){
            for (ObjAndMethod objAndMethod : objAndMethodList) {
                try {
                    objAndMethod.method.invoke(objAndMethod.object,t);
                } catch (IllegalAccessException | InvocationTargetException e) {
                    e.printStackTrace();
                }
            }
        }
    }


}

使用到的知识点:

    java反射;

    泛型;

    注解;

个人理解:源码设计的巧妙之处在于核心类中的两个集合,通过两个Map集合,轻松实现对所有类及其方法的遍历查询,理解了这两个集合就理解了EventBus的核心工作源码,至于其他的功能都是在此基础上的延伸,算是锦上添花吧。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值