ParameterizedType 是泛型/参数化类型,其定义如下:
public interface java.lang.reflect.ParameterizedType extends Type { Type[] getActualTypeArguments(); Type getRawType(); Type getOwnerType(); }
ParameterizedTypeImpl 实现类
public class ParameterizedTypeImpl implements ParameterizedType { private final Type[] actualTypeArguments; private final Class> rawType; private final Type ownerType; private ParameterizedTypeImpl(Class> var1, Type[] var2, Type var3) { this.actualTypeArguments = var2; this.rawType = var1; this.ownerType = (Type)(var3 != null ? var3 : var1.getDeclaringClass()); this.validateConstructorArguments(); } private void validateConstructorArguments() { TypeVariable[] var1 = this.rawType.getTypeParameters(); if (var1.length != this.actualTypeArguments.length) { throw new MalformedParameterizedTypeException(); } else { for(int var2 = 0; var2 < this.actualTypeArguments.length; ++var2) { } } } public static ParameterizedTypeImpl make(Class> var0, Type[] var1, Type var2) { return new ParameterizedTypeImpl(var0, var1, var2); } }ParameterizedType的方法有什么?
- Type[] getActualTypeArguments()
注意,在某些情况下,返回的数组为空。如果此类型表示嵌套在参数化类型中的非参数化类型,则会发生这种情况。
返回:
表示此类型的实际类型参数的 Type 对象的数组
- Type getRawType()
返回 Type 对象,表示声明此类型的类或接口。
返回:
Type 对象,表示声明此类型的类或接口
- Type getOwnerType()
返回 Type 对象,表示此类型是其成员之一的类型。例如,如果此类型为 O
.I ,则返回 O的表示形式。 如果此类型为顶层类型,则返回 null。
返回:
Type 对象,表示此类型是其成员之一的类型。如果此类型是顶层类型,则返回 null
以下演示ParameterizedType的属性值,通过实例打印出方法的返回结果,我们先定义如下的对象。
@Data class Person { private String name; private Integer age; } @Data public class SingleResponse{ private T data; public T getData() { return data; } public void setData(T data) { this.data = data; } } @Data class Holder { private List list; SingleResponse response; private Map.Entry map; }
单元测试类如下;
@Test public void testParameterizedMethod() { Holder holder = new Holder(); Field[] fields = holder.getClass().getDeclaredFields(); for (Field field : fields) { //返回一个 Type 对象,它表示此 Field 对象所表示字段的声明类型。 //如果 Type 是一个参数化类型,则返回的 Type 对象必须准确地反映源代码中使用的实际类型参数。 Type type = field.getGenericType(); if (type instanceof ParameterizedType) { ParameterizedType pt = (ParameterizedType) type; Type[] actualTypes = pt.getActualTypeArguments(); Type ownerType = pt.getOwnerType(); Type rawType = pt.getRawType(); StringBuilder sb = new StringBuilder(); sb.append("actualTypes :"); for (Type item : actualTypes) { sb.append(item.getTypeName() + ", "); } System.out.println(sb); System.out.println("ownerType : " + ownerType); System.out.println("rawType :" + rawType); System.out.println("--------------------"); } } }
程序输出结果:
actualTypes :java.lang.String, ownerType : null rawType :interface java.util.List -------------------- actualTypes :com.jd.flow.reflect.ParameterizedTypeTest$Person, ownerType : null rawType :class com.jd.cjg.flow.dto.SingleResponse -------------------- actualTypes :java.lang.Integer, java.lang.String, ownerType : interface java.util.Map rawType :interface java.util.Map$Entry --------------------ParameterizedType 在HTTP API中的使用
在Http Restful Api接口中,我们通常使用一个响应的包装类来统一我们的HTTP响应结果。如下定义
public class SingleResponse{ private T data; public T getData() { return data; } public void setData(T data) { this.data = data; } public static SingleResponse success() { SingleResponse response = new SingleResponse(); response.setSuccess(true); return response; } public static SingleResponse success(T data) { SingleResponse response = new SingleResponse<>(); response.setSuccess(true); response.setData(data); return response; } public static SingleResponse failure(String errCode, String errMessage) { SingleResponse response = new SingleResponse(); response.setSuccess(false); response.setCode(errCode); response.setMessage(errMessage); return response; } }
我们模拟接收到响应的JSON数据转包装类的 测试。
@Test public void testRestful() { // 申请单Client Object FlowReqCO flowReqCO = new FlowReqCO(); flowReqCO.setReqId("12344"); flowReqCO.setApplyUser("yangyanping"); SingleResponseParameterizedType 在工厂方法模式中的应用response = SingleResponse.success(flowReqCO); //模拟 Restful API json 结果 String body = JSON.toJSonString(response); // 模拟客户端获取到json 转换对象 Type parameterizedTypeClass = ParameterizedTypeImpl.make(SingleResponse.class, new Type[]{FlowReqCO.class}, null); response = JSON.parseObject(body, parameterizedTypeClass); System.out.println(response.getData().getReqId()); }
在一些较复杂的业务中,如果我们把大量的业务逻辑代码堆砌到服务中,会导致服务方法任何一个的变更都会引起服务类的变更,违反单一职责原则
单一职责原则(SRP:Single responsibility principle)又称单一功能原则,面向对象五个基本原则(SOLID)之一。它规定一个类应该只有一个发生变化的原因。
我们可以借鉴Spring MVC Controller的处理方式,使用委派模式把请求转发给一个Executor处理器去执行,代码如下:
我们先定义抽象的处理器接口:
public abstract class CommandExecutor{ private final Class> requestType; public CommandExecutor() { Type type = this.getClass().getGenericSuperclass(); ParameterizedType pt = (ParameterizedType) type; Type[] actualTypes = pt.getActualTypeArguments(); this.requestType = actualTypes[0].getClass(); } public Class> getRequestType() { return requestType; } public abstract S execute(R cmd); }
具体的创建申请单命令处理器
public class FlowReqSubmitCommandExecutor extends CommandExecutor{ @Override public String execute(FlowReqSubmitCommand cmd) { return "创建申请单成功"; } }
单元测试:
@Test public void testExecutor(){ FlowReqSubmitCommandExecutor executor = new FlowReqSubmitCommandExecutor(); String result = executor.execute(new FlowReqSubmitCommand()); System.out.println(result); }
我们还可以定义一个处理器工厂,在Spring 启动完成后缓存所有的处理器类
@Slf4j public class CommandFactory implements ApplicationContextAware, InitializingBean, ApplicationListener{ private static final AtomicBoolean initFlag = new AtomicBoolean(); private static ApplicationContext applicationContext; private static Map , CommandExecutor> commandExecutorMap = Maps.newHashMap(); @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { this.applicationContext = applicationContext; } @Override public void afterPropertiesSet() throws Exception { this.register(); } @Override public void onApplicationEvent(ContextRefreshedEvent contextRefreshedEvent) { log.info("CommandFactory spring start!"); } public static CommandExecutor getExecutor(Class> claz) { return commandExecutorMap.get(claz); } public static CommandExecutor getExecutor(Command command) { return commandExecutorMap.get(command.getClass()); } private void register() throws Exception { if (!initFlag.compareAndSet(false, true)) { return; } Map beanMap = applicationContext.getBeansOfType(CommandExecutor.class); for (Map.Entry entry : beanMap.entrySet()) { CommandExecutor commandExecutor = entry.getValue(); commandExecutorMap.put(commandExecutor.getRequestType(), commandExecutor); } } }
根据命令Command 查找处理器并执行请求
@Test public void testCommandFactory() { FlowReqSubmitCommand cmd = new FlowReqSubmitCommand(); CommandFactory.getExecutor(cmd).execute(cmd); }
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)