该篇通过注解构建映射关系,主要有三种:
- 获取类信息
- 获取方法信息
- 获取参数名
1.注解
1.1 类注解
package edu.xupt.cs.factory.anno;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
@Retention(RUNTIME)
@Target(ElementType.TYPE)
public @interface AActionClass {
}
1.2 方法注解
package edu.xupt.cs.factory.anno;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface AActionMethod {
String action();
}
1.3 参数注解
package edu.xupt.cs.factory.anno;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.PARAMETER)
public @interface AActionType {
String parameterName();
}
2 方法表
- 参数信息表:
根据方法注解的参数名,获取对应的参数值。那么需要构建映射关系。
package edu.xupt.cs.factory.anno;
import java.lang.reflect.Parameter;
public class ParameterInfo {
private String name;
private Parameter parameter;
public String getName() {
return name;
}
public ParameterInfo setName(String name) {
this.name = name;
return this;
}
public Parameter getParameter() {
return parameter;
}
public ParameterInfo setParameter(Parameter parameter) {
this.parameter = parameter;
return this;
}
}
2.方法表
主要记录方法、参数信息。供分发器使用。
package edu.xupt.cs.factory.anno;
import edu.xupt.cs.action.abstract_.BeanDefination;
import edu.xupt.cs.factory.ArgumentMaker;
import java.lang.reflect.Parameter;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
public class ActionBeanDefination extends BeanDefination {
//参数列表
private final List<ParameterInfo> parameterInfos;
{
parameterInfos = new LinkedList<>();
}
@Override
//解析Gson字符串参数
public Object[] getValues(Parameter[] parameters, String strValues) {
ArgumentMaker argumentMaker = new ArgumentMaker(strValues);
Iterator<ParameterInfo> iter = getParameterInfosIterator();
Object[] values = new Object[getParameterListSize()];
for (int i = 0; iter.hasNext(); i++) {
ParameterInfo parameterInfo = iter.next();
Object value = argumentMaker.getArgument(parameterInfo.getName(),
parameterInfo.getParameter().getParameterizedType());
values[i] = value;
}
return values;
}
public void addParameterInfo(ParameterInfo parameterInfo) {
if (parameterInfos.contains(parameterInfo)) {
return;
}
parameterInfos.add(parameterInfo);
}
public void removeParameterInfo(ParameterInfo parameterInfo) {
parameterInfos.remove(parameterInfo);
}
public Iterator<ParameterInfo> getParameterInfosIterator() {
return parameterInfos.iterator();
}
public int getParameterListSize() {
return parameterInfos.size();
}
}
getValues方法中的argumentMaker封装了Gson,解析参数字符串。
3.静态工厂
构建请求与方法映射关系.
这里使用了包扫描工具,获取每个注解标记的类。
package edu.xupt.cs.factory.anno;
import com.mec.util.PackageScan;
import edu.xupt.cs.action.abstract_.ActionBeanFactory;
import edu.xupt.cs.action.abstract_.BeanDefination;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
public class AnnoActionBeanFactory extends ActionBeanFactory {
public BeanDefination getAction(String action) {
BeanDefination beanDefination = actionPool.get(action);
return beanDefination;
}
@Override
public void scannActionMapping(String path) {
try {
new PackageScan() {
@Override
protected void dealClass(Class<?> klass) {
try {
if (klass.isAnnotationPresent(AActionClass.class)) {
Object object = klass.newInstance();
Method[] methods = klass.getDeclaredMethods();
for (Method method : methods) {
if (method.isAnnotationPresent(AActionMethod.class)) {
ActionBeanDefination abd = new ActionBeanDefination();
abd.setKlass(klass);
abd.setMethod(method);
abd.setObject(object);
String action = method.getAnnotation(AActionMethod.class).action();
Parameter[] parameters = method.getParameters();
for (Parameter parameter : parameters) {
if (parameter.isAnnotationPresent(AActionType.class)) {
String name = parameter.getAnnotation(AActionType.class).parameterName();
ParameterInfo parameterInfo = new ParameterInfo().
setName(name).
setParameter(parameter);
abd.addParameterInfo(parameterInfo);
} else {
try {
throw new ParameterAnnoExption("参数未注解名字");
} catch (Exception e) {
e.printStackTrace();
}
}
}
actionPool.put(action, abd);
}
}
}
} catch (InstantiationException | IllegalAccessException e) {
e.printStackTrace();
}
}
}.scanPackage(path);
} catch (Exception e) {
e.printStackTrace();
}
}
}