我有以下弹簧夹豆。这个想法是它保留了一个东西的实例,并在某些东西发生变化时发出变化事件(同时提供旧值和新值):
public class Holder<T> implements ApplicationEventPublisherAware {
private final Class<T> payloadType; //because java generics are incomplete
private T curr; //latest value being held
private ApplicationEventPublisher publisher; //spring context ref
public Holder(Class<T> payloadType) {
this.payloadType = payloadType;
}
public void change() throws Exception {
T prev = curr;
curr = payloadType.newInstance();
publisher.publishEvent(new ContentsChangedEvent<>(prev, curr));
}
}
然后我有一个对这些事件做出反应的监听器类:
@Named
public class Listener {
@EventListener
public void onChange(ContentsChangedEvent<Cat> event) {
//never gets called
}
@EventListener
public void onErasedChange(ContentsChangedEvent<?> event) {
//does get called
}
}
我的问题是,通用(正确)事件侦听器方法永远不会被调用(获取Event<Cat>
的方法),只有被删除的方法。
完整性&#39;为了这里是spring context.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.2.xsd">
<context:annotation-config/>
<context:component-scan base-package="net.radai"/>
<bean id="holder" class="net.radai.Holder">
<constructor-arg type="java.lang.Class" value="net.radai.Cat"/>
</bean>
</beans>
我还把整件事放在github上 - https://github.com/radai-rosenblatt/spring-events。它是一个maven项目 - 你构建它并且你将得到一个失败的测试。
我做错了什么?
注意:在实际使用案例中,我希望有多个此类持有人并强制所有听众放弃与其无关的事件,这是不可接受的
答案 0 :(得分:1)
public class ContentsChangedEvent<T> extends ApplicationEvent{
public ContentsChangedEvent(Holder<T> source, T prev, T curr) {
super(source);
this.prev = prev;
this.curr = curr;
}
}
//Holder class
public void change() {
T prev = curr;
try {
curr = payloadType.newInstance();
} catch (Exception e) {
int g = 8;
}
publisher.publishEvent(new ContentsChangedEvent<T>(this, prev, curr));
}
将调用onChange和onErasedChange。
答案 1 :(得分:1)
如果在通用事件类中实现org.springframework.core.ResolvableTypeProvider,则侦听器将解析它。 例如:
import org.springframework.core.ResolvableType;
import org.springframework.core.ResolvableTypeProvider;
public class EventBase<T> {
public T payload;
}
public class AppEvent<T> extends EventBase<T> implements ResolvableTypeProvider {
@Override
public ResolvableType getResolvableType() {
return ResolvableType.forClassWithGenerics(
getClass(),
ResolvableType.forInstance(this.payload)
);
}
}
@Component
public class EventHandler {
@EventListener
public void handleString(AppEvent<String> event) {
System.out.println("Event[" + event.getClass().getSimpleName() + "], received:" + event);
}
@EventListener
public void handleLong(AppEvent<Long> event) {
System.out.println("Event[" + event.getClass().getSimpleName() + "], received:" + event);
}
}