线程池+枚举+反射调用不同接口获得统一返回数值

首先接口函数的定义:使用策略模式,不同的接口实现类统一实现一个被实现的接口类

public interface ThreadServiceBase {
    /**
     *
     * 用来被继承使用
     */
}

然后不同的接口实现类都实现这个接口,每个实现类有自己的定义业务接口,例如

接口定义好后,定义枚举类,枚举类有两种模式,

THREADTHREE("threadThree",new ThreadThreeServiceImpl()),
THREADONE("threadOne",new ThreadServiceImpl());

or
THREADTHREE("threadThree", "ThreadThreeServiceImpl"),
THREADONE("threadOne", "ThreadServiceImpl");

l分别对应的线程的处理方式如下:

// 这里使用的是枚举类中new对象后直接调用的方式

public class ThreadPoolInterfaceInvoke implements Callable<Pair<Integer, Integer>> {
    private static final Logger logger = LoggerFactory.getLogger(ThreadPoolInterfaceInvoke.class);

    /*开发思路:一个线程只能调用一次,外部使用线程池过来调用,所以这里需要配备四个接口的调用参数。
     * 用到了  线程  参数传递  枚举  反射*/
    private String v;

    /**
     *
     */
    private Pair<Integer, Integer> pairThreadLocal;

    public ThreadPoolInterfaceInvoke(){}
    public ThreadPoolInterfaceInvoke(String v){
        this.v = v;
    }

    @Override
    public Pair<Integer, Integer> call() throws Exception {
        ThreadService threadService = (ThreadService)ThreadEnum.get(v).getServiceClass();
        int threadOne = threadService.threadOne();
        logger.info("threadOne name v:{}, threadOne value:{}",v,threadOne);
        int threadTwo = threadService.threadTwo();
        logger.info("threadTwo name v:{}, threadTwo value:{}",v,threadTwo);
        pairThreadLocal = new Pair<Integer, Integer>(threadOne,threadTwo);
        return pairThreadLocal;
    }
}

// 这种方式是通过,反射原理从spring工厂获取bean在调用方法

public class ThreadPoolInterfaceInvokeTwo implements Callable<Pair<Integer, Integer>> {
    private static final Logger logger = LoggerFactory.getLogger(ThreadPoolInterfaceInvokeTwo.class);

    /*开发思路:一个线程只能调用一次,外部使用线程池过来调用,所以这里需要配备四个接口的调用参数。
     * 用到了  线程  参数传递  枚举  反射*/
    private String v;

    /**
     * 
     */
    private Pair<Integer, Integer> pairThreadLocal;

    public ThreadPoolInterfaceInvokeTwo(String v){
        this.v = v;
    }

    @Override
    public Pair<Integer, Integer> call() throws Exception {
        // 枚举获得 类名称  或则  获得类.class
        String serviceClass = ThreadEnumTwo.get(v).getServiceClass();
        // 根据类名 或者.class获得反射类  
        // 这里需注意,如果是name的方式需要在@Service("ThreadThreeServiceImpl")注明,否则spring工厂找不到bean,当然也可以直接使用.class的方式。后续贴出代码,这里不展示
        ThreadServiceBase bean = (ThreadServiceBase) SpringContextUtil.getBean(serviceClass);
        Class<? extends ThreadServiceBase> aClass = bean.getClass();
        // 获取方法  这里的方法名需要不同接口实现时使用相同的方法名
        Method threadOne = aClass.getMethod("threadOne", null);
        // 调用方法
        int invokeOne = (int)threadOne.invoke(aClass.newInstance(), null);

        Method threadTwo = aClass.getMethod("threadTwo", null);
        int invokeTwo = (int)threadTwo.invoke(aClass.newInstance(), null);

        logger.info("invokeOne name v:{}, invokeOne value:{}",v,threadOne);
        logger.info("invokeTwo name v:{}, invokeTwo value:{}",v,threadTwo);
        pairThreadLocal = new Pair<Integer, Integer>(invokeOne,invokeTwo);
        return pairThreadLocal;
    }
}

 

线程写好后,下一步是定义线程池。这里就不作赘述。

// 这里只贴出了上面的一种方式,其实两个都差不多。

// 我这里使用的springboot中自带的schdule方式,可以自行选择其他定时任务,quatz, xx_job,eslate_job,timer等都一样使用代码逻辑

@Async//此注解是config中的线程池使用定时任务。
@Component
public class ScheduleThradInterfaceTwo {
    private static final org.slf4j.Logger log = LoggerFactory.getLogger(ScheduleThradInterfaceTwo.class);

    @Scheduled(cron = "0 0/1 * * * ?")
    public void scheduled() throws Exception{
        log.info("ScheduleThradInterfaceTwo---------------------");
        // 固定大小线程池的使用
        ThreadPoolExecutor threadPool = new ThreadPoolExecutor(
                                 2,                             //核心线程池大小
                                 Runtime.getRuntime().availableProcessors(),   //最大核心线程池大小(CPU密集型,根据CPU核数设置)
                                 3,                         //超时了没有人调用就会释放
                                 TimeUnit.SECONDS,                             //超时单位
                                 new LinkedBlockingDeque<>(3),                 //阻塞队列
                                 Executors.defaultThreadFactory(),             //线程工厂,创建线程的,一般不用动
                                 new ThreadPoolExecutor.AbortPolicy());
        // 使用多线程  lsit 一起调用
        List<ThreadPoolInterfaceInvokeTwo> list = Arrays.asList(
                new ThreadPoolInterfaceInvokeTwo(ThreadEnum.THREADTHREE.getServiceName()),
                new ThreadPoolInterfaceInvokeTwo(ThreadEnum.THREADONE.getServiceName()));

        List<Future<Pair<Integer, Integer>>> futures = null;
        try {
            futures = threadPool.invokeAll(list);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        List<Integer> integers = new ArrayList<>();
// 待结果统一返回后,整理结果集
        futures.stream().forEach( fu -> {
            try {
                Pair<Integer, Integer> integerIntegerPair = fu.get();
                integers.add(integerIntegerPair.getKey());
                integers.add(integerIntegerPair.getValue());
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (ExecutionException e) {
                e.printStackTrace();
            }
        });


        log.info("ScheduleThradInterfaceTwo输出结果---------------------------------------------------------------------:"+integers.toString());




    }
}

springContexUtils如下:

@Component
public class SpringContextUtil implements ApplicationContextAware {

    public static ApplicationContext applicationContext;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        SpringContextUtil.applicationContext = applicationContext;
    }

    public ApplicationContext getApplicationContext() {
        return applicationContext;
    }

    public static Object getBean(String name) {
        return applicationContext.getBean(name);
    }

    public <T> T getBean(Class<T> clazz) {
        return applicationContext.getBean(clazz);
    }

    public <T> T getBean(String name, Class<T> clazz) {
        return getApplicationContext().getBean(name, clazz);
    }
}

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
好的,您想了解关于使用 @ExceptionHandler + @ControllerAdvice +枚举实现全局异常统一处理的内容,这是一个常用的方案,可以实现全局异常的捕获和处理,让程序更加健壮和稳定。 @ExceptionHandler注解用于标记一个方法,该方法用于处理指定的异常类型。@ControllerAdvice注解用于标记一个类,该类用于处理全局异常。枚举则可以用于定义异常类型,方便异常处理时的统一管理。 在实现全局异常处理时,我们可以通过 @ExceptionHandler 注解来捕获指定的异常类型,并在方法中进行相应的处理。@ControllerAdvice注解可以让我们在一个类中定义多个 @ExceptionHandler方法,用于处理不同类型的异常。同时,我们也可以使用枚举来定义不同的异常类型,方便管理和调用。 下面是一个简单的示例,演示如何使用 @ExceptionHandler + @ControllerAdvice +枚举实现全局异常统一处理: ```java @ControllerAdvice public class GlobalExceptionHandler { @ExceptionHandler(value = BusinessException.class) @ResponseBody public ResultVO handleBusinessException(BusinessException e) { return ResultVO.error(e.getCode(), e.getMessage()); } } public enum ExceptionEnum { PARAMETER_ERROR(1001, "参数错误"), DATA_NOT_FOUND(1002, "数据不存在"), SYSTEM_ERROR(5000, "系统错误"); private final int code; private final String message; ExceptionEnum(int code, String message) { this.code = code; this.message = message; } public int getCode() { return code; } public String getMessage() { return message; } } public class BusinessException extends RuntimeException { private final int code; public BusinessException(int code, String message) { super(message); this.code = code; } public BusinessException(ExceptionEnum exceptionEnum) { super(exceptionEnum.getMessage()); this.code = exceptionEnum.getCode(); } public int getCode() { return code; } } ``` 在上面的示例中,GlobalExceptionHandler类标记了@ControllerAdvice注解,用于全局异常处理。其中,handleBusinessException方法用于处理BusinessException异常,返回一个ResultVO对象,其中包含错误码和错误信息。 BusinessException则是一个自定义的异常类,它包含一个code属性和一个message属性,用于表示异常的错误码和错误信息。同时,它还提供了一个构造方法,可以根据ExceptionEnum来构造一个BusinessException对象。 ExceptionEnum则是一个枚举类,包含了不同的异常类型,每个异常类型都有一个对应的错误码和错误信息。 在实际开发中,我们可以根据实际需求来定义不同的异常类型和错误码,以便更好地管理和调用
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值