合并处理请求

  • config添加切面增强器的bean
package com.hj.config;

import com.hj.mergeprocess.MergeProcessBefore;
import com.hj.mergeprocess.annotation.MergeProcessMethodAnnotation;
import org.springframework.aop.Advisor;
import org.springframework.aop.support.DefaultPointcutAdvisor;
import org.springframework.aop.support.annotation.AnnotationMatchingPointcut;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @author huangjie
 */
@Configuration
public class MergeProcessAopBeanConfig {
    @Bean
    public MergeProcessBefore mergeProcessBefore(){
        return new MergeProcessBefore();
    }

    @Bean
    public AnnotationMatchingPointcut annotationMatchingPointcut(){
        return AnnotationMatchingPointcut.forMethodAnnotation(MergeProcessMethodAnnotation.class);
    }

    @Bean
    public Advisor registerAdvisor(){
        DefaultPointcutAdvisor defaultPointcutAdvisor = new DefaultPointcutAdvisor();
        defaultPointcutAdvisor.setPointcut(annotationMatchingPointcut());
        defaultPointcutAdvisor.setAdvice(mergeProcessBefore());
        defaultPointcutAdvisor.setOrder(10);
        return defaultPointcutAdvisor;
    }
}
  • 自定义注解
package com.hj.mergeprocess.annotation;

import com.hj.mergeprocess.AbstractMergeProcessHandler;

import java.lang.annotation.*;

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Inherited
public @interface MergeProcessMethodAnnotation {
    int concurrencyCount() default 10;

    Class<? extends AbstractMergeProcessHandler> mergeProcessHandler();
}
  • 相关接口和处理类 
    package com.hj.mergeprocess;
    
    
    import java.util.ArrayList;
    import java.util.List;
    import java.util.Map;
    import java.util.concurrent.CompletableFuture;
    import java.util.concurrent.LinkedBlockingDeque;
    import java.util.function.Function;
    
    public abstract class AbstractMergeProcessHandler<T> implements MergeProcessHandler<T>{
    
        LinkedBlockingDeque<RequestEntity<T>> deque = new LinkedBlockingDeque<>();
    
        private void addRequestEntity(RequestEntity<T> requestEntity) {
            deque.addLast(requestEntity);
        }
    
    
        protected void processRequest(Function<List<RequestEntity<T>>, Map<String ,T>> function, int concurrencyCount) {
            int size = deque.size();
            List<RequestEntity<T>> requestEntities = new ArrayList<>(size);
            List<RequestEntity<T>> futureEntityList = new ArrayList<>(size);
    
            for (int i = deque.size(); i > 0; i--) {
                RequestEntity<T> requestEntity = deque.poll();
                requestEntities.add(requestEntity);
                futureEntityList.add(requestEntity);
            }
            if(size>concurrencyCount){
                Map<String, T> result = doProcessRequest(requestEntities, function);
    
                for (RequestEntity<T> requestEntity : futureEntityList) {
                    String requestId = requestEntity.getRequestId();
                    T responseEntity = result.get(requestId);
                    requestEntity.getFuture().complete(responseEntity);
                }
                return;
            }
            for (RequestEntity<T> requestEntity : futureEntityList) {
                requestEntity.getFuture().complete(null);
            }
        }
    
        protected void addRequestPerThread(ThreadLocal<CompletableFuture<T>> threadLocal,Object requestBody,String requestId){
            CompletableFuture<T> future = new CompletableFuture<>();
            threadLocal.set(future);
            RequestEntity<T> requestEntity = new RequestEntity<>();
            requestEntity.setRequestBody(requestBody);
            requestEntity.setRequestId(requestId);
            requestEntity.setFuture(future);
            addRequestEntity(requestEntity);
        }
    
        protected int getQueueSize(){
    
            return deque.size();
        }
    
        private Map<String, T> doProcessRequest(List<RequestEntity<T>> requestEntities,
                                                Function<List<RequestEntity<T>>, Map<String, T>> function) {
            return function.apply(requestEntities);
        }
    
        protected abstract Object packageQueryArgs(Object[] args);
    
        protected abstract String getRequestId(Object arg);
    
    }
    

     

package com.hj.mergeprocess;


import com.hj.mergeprocess.annotation.MergeProcessMethodAnnotation;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;

import java.lang.reflect.Method;
import java.util.concurrent.CompletableFuture;

public class MergeProcessBefore implements MethodInterceptor {
    @Override
    public Object invoke(MethodInvocation invocation) throws Throwable {
        MergeProcessInterface mergeProcessInterface = (MergeProcessInterface) invocation.getThis();

        Class<?> clazz = Class.forName(invocation.getThis().getClass().getName());

        Method method = clazz.getMethod(invocation.getMethod().getName(), invocation.getMethod().getParameterTypes());

        MergeProcessMethodAnnotation annotation = method.getAnnotation(MergeProcessMethodAnnotation.class);

        String simpleBeanName = annotation.mergeProcessHandler().getSimpleName();

        //获取对应的bean service
        MergeProcessHandler mergeProcessHandler = CustomerContext.getApplicationContext().getBean(toLowerCaseFirstOne(simpleBeanName), MergeProcessHandler.class);

        ThreadLocal<CompletableFuture<Object>> futureThreadLocal = mergeProcessInterface.getFutureThreadLocal();

        mergeProcessHandler.mergeProcess(futureThreadLocal, invocation.getArguments(), annotation.concurrencyCount());

        return invocation.proceed();
    }

    private String toLowerCaseFirstOne(String simpleBeanName) {
        Character.isLowerCase(simpleBeanName.charAt(0)) {
            return simpleBeanName;
        }
        return Character.toLowerCase(simpleBeanName.charAt(0)) + simpleBeanName.substring(1);
    }
}

 

package com.hj.mergeprocess;

import java.util.concurrent.CompletableFuture;

public interface MergeProcessHandler<T> {
    void mergeProcess(ThreadLocal<CompletableFuture<T>> threadLocal, Object[] args, int concurrencyCount);
}

 

package com.hj.mergeprocess;

import java.util.concurrent.CompletableFuture;

public interface MergeProcessInterface {
    ThreadLocal<CompletableFuture<Object>> getFutureThreadLocal();
}

 

package com.hj.mergeprocess;

import lombok.Data;

import java.io.Serializable;
import java.util.concurrent.CompletableFuture;

public class RequestEntity<T> implements Serializable {
    /**
     * 请求唯一标志id
     */
    String requestId;

    /**
     * 请求体参数
     */
    Object requestBody;

    /**
     * 请求回调future
     */
    CompletableFuture<T> future;

    public String getRequestId() {
        return requestId;
    }

    public void setRequestId(String requestId) {
        this.requestId = requestId;
    }

    public Object getRequestBody() {
        return requestBody;
    }

    public void setRequestBody(Object requestBody) {
        this.requestBody = requestBody;
    }

    public CompletableFuture<T> getFuture() {
        return future;
    }

    public void setFuture(CompletableFuture<T> future) {
        this.future = future;
    }
}
package com.hj.mergeprocess;

import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
import java.util.function.Function;

/**
 * @author huangjie
 */
@Component
public class ViewMergeProcess extends AbstractMergeProcessHandler<Object> {
    @Override
    public void mergeProcess(ThreadLocal<CompletableFuture<Object>> threadLocal, Object[] args, int concurrencyCount) {
        //封装请求参数
        packageQueryArgs(args);

        String requestId = getRequestId("");

        //添加请求
        addRequestPerThread(threadLocal,null, requestId);

        //...定时获取deque里面的数据判断是否做处理

          //...
        if (lock.tryLock()) {
            try {
                TimeUnit.MICROSECONDS.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }finally {
                lock.unlock();
            }

            if (getQueueSize()==0) {
                return;
            }
            //processRequest(...)
        }

        //处理  自己传入future()
        processRequest(new Function<List<RequestEntity<Object>>, Map<String, Object>>() {
            @Override
            public Map<String, Object> apply(List<RequestEntity<Object>> requestEntities) {
                return null;
            }
        },concurrencyCount);

        //处理  自己传入future()
        processRequest(new Function<List<RequestEntity<Object>>, Map<String, Object>>() {
            @Override
            public Map<String, Object> apply(List<RequestEntity<Object>> requestEntities) {
                return null;
            }
        },concurrencyCount);
    }


    @Override
    protected Object packageQueryArgs(Object[] args) {
        return null;
    }

    public String getRequestId(Object obj){
        return UUID.randomUUID().toString();
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值