观察者模式+反射对Event Bus框架做一个简单的探究

概述

我们知道Google Guava的EventBus类使用了,register() 函数用来注册观察者,通过post() 函数发送消息的时候,并非把消息发送给所有的观察者,是观察者模式典型的应用

下面对案例做个简单的探究

demo

有如下这几个类,期间的关系如图所示:

在这里插入图片描述

可能会涉及到其他的东西,会加在代码注释中

目录结构及部分代码实例如下:
在这里插入图片描述
在这里插入图片描述

Controller类:

Event Bus的使用方式是通过registry注册到EventBus中,通过post通知相关的方法执行,所有核心是registry和post

public class UserControllerEventBus {

    private EventBus eventBus;

    public UserControllerEventBus(){
        eventBus = new EventBus();
    }

    public String  register(String telephone,String password) throws Exception {

        UserService userService = new UserService();
        Long userId = userService.register(telephone,password);
        eventBus.registry(new SendMessageHandlerBus());
        eventBus.registry(new SendEmailHandlerBus());
        eventBus.registry(new SendMessageHandlerBus());
        eventBus.post(userId);
        return "register完成";
    }

    public static void main(String[] args) throws Exception {
        UserControllerEventBus userController = new UserControllerEventBus();
        String register = userController.register("1", "2");
        System.out.println(register);
    }
}

首先我们是对注解进行判断的,为此首先要定义一个注解
Subscribe注解

@Retention注解表示在何时使用,RUNTIME表示运行时
@Target注解表示作用在哪些方法上,METHOD表示方法

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

ObserverAction:ObserverAction类用来表示@Subscribe注解的方法,包含了我们需要作用的方法method和方法的对象object,因为只有通过这样才能调用相应的方法,execute中的参数是post传进来的,由Event Bus调用

public class ObserverAction {

    private Method method;
    private Object object;

    public ObserverAction(Method method,Object object){

        this.method = method;
        this.object = object;

    }

    public void execute(Object param){

        try {
            method.invoke(object,param);
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }

    }

}

Registry类:registry是核心类

public class Registry {

    private ConcurrentHashMap<Class<?>, Collection<ObserverAction>> actionMap = new ConcurrentHashMap<>();
	
	//注册
    public void registry(Object obj){

        Class<?> objClass = obj.getClass();

        ConcurrentHashMap<Class<?>, Collection<ObserverAction>> map = getObserverAction(obj);
        actionMap.putAll(map);

    }
	
	//返回所有的ObserverAction的List
    public List<ObserverAction> getActionList(){

        List<ObserverAction> observerActionList = new ArrayList<>();

        for (Collection<ObserverAction> oneValues:actionMap.values()) {
            observerActionList.addAll(oneValues);
        }

        return observerActionList;

    }
	
    public ConcurrentHashMap<Class<?>, Collection<ObserverAction>> getActionMap() {
        return actionMap;
    }
	/*
        一个类中存在多个@Subscribe指定的方法,每个@Subscribe指定的方法对应一个ObserverAction方法,
        为此一个类对应多个ObserverAction方法
     */
    private ConcurrentHashMap<Class<?>, Collection<ObserverAction>> getObserverAction(Object obj) {

        ConcurrentHashMap<Class<?>, Collection<ObserverAction>> actionMap = new ConcurrentHashMap<>();
        Class<?> aClass = obj.getClass();
        List<ObserverAction> observerActions = new ArrayList<>();
        //生成observeraction方法
        for (Method oneMethod:checkMethodWithAnotation(obj) ) {
           ObserverAction observerAction = new ObserverAction(oneMethod,obj);
           observerActions.add(observerAction);
        }

        actionMap.put(aClass,observerActions);
        return actionMap;
    }

	/*
        一个类中有多个方法,这个类中的方法有的使用了指定注解,有的没,为此需要进行判断
        获取到类注解上的方法,对方法的参数进行判断,有问题就抛出异常,没有问题则返回相应的方法
     */
    private List<Method> checkMethodWithAnotation(Object object) {

        List<Method> methodList = new ArrayList<>();
        Class<?> objectClass = object.getClass();
        Method[] declaredMethods = objectClass.getDeclaredMethods();
        for (Method method:declaredMethods) {
		//获取到它所有的方法,判断每个方法是否包含Subscribe注解
            if (method.isAnnotationPresent(Subscribe.class)){
		
                Class<?>[] parameterTypes = method.getParameterTypes();
                //等于1不会抛出异常,不等于1会抛出异常
                Preconditions.checkArgument(parameterTypes.length==1,"无法在Registr中注册");
                //包含注解放到List中
                methodList.add(method);
            }
        }
        return methodList;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值