java之ParameterizedType应用

java之ParameterizedType应用,第1张

java之ParameterizedType应用 什么是ParameterizedType?

     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 对象的数组

  • 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");
        SingleResponse 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());
    }
ParameterizedType 在工厂方法模式中的应用

在一些较复杂的业务中,如果我们把大量的业务逻辑代码堆砌到服务中,会导致服务方法任何一个的变更都会引起服务类的变更,违反单一职责原则

单一职责原则(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);
    }

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zaji/5438210.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-11
下一篇 2022-12-11

发表评论

登录后才能评论

评论列表(0条)