发帖    主题    评论    推荐    标签    作者    订阅    查搜    注册   登陆   关注
 
面向对象 设计模式 领域驱动设计 企业架构 框架 开发教程 微服务 CQRS 扩展性 并发编程 事件溯源 分布式 SOA

guava eventbus不支持spring的aop代理

                   
2014-04-11 16:31
赞助商链接

今天在使用guava eventbus发送事件的时候,post之后没有进入相应的处理方法断点中,发觉很奇怪,然后就看了看eventbus的源代码,其中有一处:
public void register(Object object) {
Multimap<Class<?>, EventSubscriber> methodsInListener =
finder.findAllSubscribers(object);
subscribersByTypeLock.writeLock().lock();
try {
subscribersByType.putAll(methodsInListener);
} finally {
subscribersByTypeLock.writeLock().unlock();
}
}

@Override
public Multimap<Class<?>, EventSubscriber> findAllSubscribers(Object listener) {
Multimap<Class<?>, EventSubscriber> methodsInListener = HashMultimap.create();
Class<?> clazz = listener.getClass();
for (Method method : getAnnotatedMethods(clazz)) {
Class<?>[] parameterTypes = method.getParameterTypes();
Class<?> eventType = parameterTypes[0];
EventSubscriber subscriber = makeSubscriber(listener, method);
methodsInListener.put(eventType, subscriber);
}
return methodsInListener;
}
发现findAllSubscribers方法中的 Class<?> clazz = listener.getClass();代码只是获取监听器的class对象,但此时spring已经对该监听器生成了代理类,所以获取到的始终都是proxy,而在这个proxy对象中没有相关的处理方法,所以根本就没有注册成功,所以就进入不了断电了,想修改源代码来支持spring的代理类,还在实践中....

不知道有没有童鞋已经遇到这个问题并有其他的解决方案的没?

2014-04-12 10:10

请问你把 guava eventbus 用在什么场景或者什么类型的项目下啦?

2014-04-15 09:43

用在了cqrs的event机制上了,因为是异步的,且不需要执行结果,但是命令总线部分需要执行结果,所以命令总线是自己实现的。

问题我自己解决了,因为guava eventbus在注册的时候只是简单的从注册类中查找对应的监听器,所以在注册之前先判断是否是代理类(spring的代理类都是包含‘$’),如果是代理类就将代理类中的源对象找出来,然后注册源对象:
private IEventHandler findProxySource(IEventHandler handler){
Method getTargetSource = null;
try {
try {
getTargetSource = handler.getClass().getDeclaredMethod("getTargetSource");
Object singletonTargetSource = getTargetSource.invoke(handler, new Object[]{});
Method getTarget = singletonTargetSource.getClass().getDeclaredMethod("getTarget");
Object target = getTarget.invoke(singletonTargetSource, new Object[]{});
return (IEventHandler)target;
} catch (NoSuchMethodException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
e.printStackTrace();
}
} catch (SecurityException e) {
e.printStackTrace();
}
return null;
}
这样就可以注册成功了

2014-04-16 14:21

这个原因可能是因为 spring用的动态代理模式,代理类丢失的注解等信息,
在spring配置中加上
<aop:aspectj-autoproxy proxy-target-class="true"/>

也许可以解决你的问题

2018-04-16 14:29

你这个问题是怎么解决的,从哪里判断代理类,麻烦告之一下, 谢谢

eventBus      guava      动态代理      spring3     

赞助商链接

赞助商链接

返回顶部

移动版 关于本站 使用帮助 联系反馈 最佳分辨率1366x768
OpenSource JIVEJDON Powered by JdonFramework Code © 2002-20 jdon.com