项目中需要整合web框架和apama平台,用Apama提供的engineClient互相链接。在交互时将java类封装成event会非常麻烦,目前知道两种办法:
1、拼接成字符串:将消息拼成字符串
String eventStr = "com.event.TestEvent('field1','field2','field3')";
Event event = new Event(eventStr);
2、用Event类包装
EventType eventType = new EventType("com.event.TestEvent")
eventType.addField('field1name', StringFieldType.TYPE);
eventType.addField('field2name', StringFieldType.TYPE);
eventType.addField('field3name', StringFieldType.TYPE);
Event event = new Event(eventType);
event.setField('field1name', field1);
event.setField('field2name', field2);
event.setField('field3name', field3);
每一次交互都需要用这样的方法处理一遍,代码容易出错也不易维护,就用了注解方式处理
注解:EventField
package com.test.common.apama;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 用于标记变量在EVENT中的名称及类型
* @Author: ZH
* @Date: Created on 16:28 2018/3/13.
*/
@Documented
@Inherited
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.FIELD})//次注解作用于类和字段上
public @interface EventField {
/**
* 获取名称
* @return
*/
String name() default "";
}
注解处理类ApamaUtils:
package com.test.common.apama;
import com.apama.event.Event;
import com.apama.event.parser.BooleanFieldType;
import com.apama.event.parser.DictionaryFieldType;
import com.apama.event.parser.EventType;
import com.apama.event.parser.FloatFieldType;
import com.apama.event.parser.IntegerFieldType;
import com.apama.event.parser.SequenceFieldType;
import com.apama.event.parser.StringFieldType;
import com.finesys.common.utils.StringUtils;
import java.lang.reflect.Field;
/**
* APAMA工具类
*
* @Author: ZH
* @Date: Created on 15:59 2018/3/13.
*/
public class ApamaUtils {
/***
* 根据类获取EventType-只能处理int、String、double、float、char、int[]、double[]、float[]、string[]、boolean[]、map<string,string>
* @param packageName
* @param clazz
* @return
*/
public static EventType getEventTypeByClass(String packageName, Class clazz) {
EventField packageInfo = (EventField) clazz.getAnnotation(EventField.class);
if (StringUtils.isEmpty(packageName) && packageInfo != null) {
packageName = packageInfo.name();
}
if (StringUtils.isEmpty(packageName)) {
throw new NullPointerException("未获取packageName");
}
EventType eventType = new EventType(packageName);
Field[] fields = clazz.getDeclaredFields();
if (fields != null && fields.length > 0) {
for (Field field : fields) {
//解析注解
EventField fieldType = field.getAnnotation(EventField.class);
if (fieldType == null) {
continue;
}
//string类型
String simpleName = field.getType().getSimpleName();
//获取变量名称
String name = field.getName();
if (StringUtils.isNotEmpty(fieldType.name())) {
name = fieldType.name();
}
if (simpleName.equals("String") || simpleName.equals("char")) {
eventType.addField(name, StringFieldType.TYPE);
continue;
}
//int类型
if (simpleName.equals("int")) {
eventType.addField(name, IntegerFieldType.TYPE);
continue;
}
//double类型
if (simpleName.equals("double") || simpleName.equals("float")) {
eventType.addField(name, FloatFieldType.TYPE);
continue;
}
//boolean类型
if (simpleName.equals("boolean")) {
eventType.addField(name, BooleanFieldType.TYPE);
continue;
}
//String[]类型数组
if (simpleName.equals("String[]") ) {
eventType.addField(name, new SequenceFieldType(StringFieldType.TYPE));
continue;
}
//int[]类型数组
if (simpleName.equals("int[]") ) {
eventType.addField(name, new SequenceFieldType(IntegerFieldType.TYPE));
continue;
}
//double[]类型数组或者float[]类型
if (simpleName.equals("double[]")||simpleName.equals("float[]") ) {
eventType.addField(name, new SequenceFieldType(FloatFieldType.TYPE));
continue;
}
//boolean[]类型数组
if (simpleName.equals("boolean[]")||simpleName.equals("float[]") ) {
eventType.addField(name, new SequenceFieldType(BooleanFieldType.TYPE));
continue;
}
//map类型,只支持String\String类型
if (simpleName.equals("Map") ) {
eventType.addField(name, new DictionaryFieldType(StringFieldType.TYPE,StringFieldType.TYPE));
continue;
}
}
}
return eventType;
}
public static Event getEventByObject(Object object) {
return getEventByObject(null, object);
}
/**
* 获取指定对象的Event
* @param packageName
* @param object
* @return
*/
public static Event getEventByObject(String packageName, Object object) {
Event event = new Event(getEventTypeByClass(packageName,object.getClass()));
Field[] fields = object.getClass().getDeclaredFields();
if (fields != null && fields.length > 0) {
for (Field field : fields) {
//解析注解
EventField eventField = field.getAnnotation(EventField.class);
if (eventField == null) {
continue;
}
//修改权限
boolean accessFlag = field.isAccessible();
field.setAccessible(true);
Object o;
try {
//获取变量值
o = field.get(object);
} catch (IllegalAccessException e) {
e.printStackTrace();
continue;
}
String name = field.getName();
if (StringUtils.isNotEmpty(eventField.name())) {
name = eventField.name();
}
if (StringUtils.isNotEmpty(name) && o != null) {
event.setField(name, o);
}
//还原权限
field.setAccessible(accessFlag);
}
}
return event;
}
@EventField(name = "com.text.Test")
static class Test {
@EventField(name = "String")
public String StringName;
@EventField
public int intName;
@EventField()
private float floatName;
}
}
在使用注解时变量声明顺序应该和event中顺序一致,否则赋值会混乱。考虑在注解中加一个排序字段。