java Spring @Aysnc approch通过JDK动态代理

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java Spring @Aysnc approch通过JDK动态代理相关的知识,希望对你有一定的参考价值。

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Objects;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

public class JdkProxySpringAsyncDemo {

	interface If {
		String originalMethod(String s);

		@InAsync(value = ExecutorType.CACHED)
		Future<String> originalMethodAsync(String s);
	}

	static class AsyncRes<T> implements Future<T> {

		T value;
		AsyncRes(T result) {
			this.value = result;
		}

		@Override
		public boolean cancel(boolean mayInterruptIfRunning) {
			return false;
		}

		@Override
		public boolean isCancelled() {
			return false;
		}

		@Override
		public boolean isDone() {
			return false;
		}

		@Override
		public T get() throws InterruptedException, ExecutionException {
			return value;
		}

		@Override
		public T get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException {
			return get();
		}
	}


	static class Original implements If {
		@Override
		public String originalMethod(String s) {
			return "Original " + s;
		}

		@Override
		public Future<String> originalMethodAsync(String s) {
			return  new AsyncRes<>("Original " + s + " in "+Thread.currentThread().getName());
		}
	}

	static class Handler implements InvocationHandler {

		private final If original;

		Handler(If original) {
			this.original = original;
		}

		@Override
		public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

			System.out.println("Before execution...");

			InAsync inAsync = method.getAnnotation(InAsync.class);

			Object invokeResult;

			if (Objects.nonNull(inAsync)) {
				ExecutorType executorType = inAsync.value();
				Executor executor;

				switch (executorType) {
					case CACHED:
						executor = Executors.newCachedThreadPool();
						break;
					case FOLKJOIN:
						executor = new ForkJoinPool();
						break;
					default:
						executor = Executors.newSingleThreadExecutor();
				}

				Callable<Object> task = () -> {
					try {
						Object result = method.invoke(original, args);
						if (result instanceof Future) {
							return ((Future<?>)result).get();
						}
					} catch (Exception ex) {
						ex.printStackTrace();
					} finally {
						((ExecutorService) executor).shutdown();
					}
					return null;
				};

				invokeResult = ((ExecutorService) executor).submit(task);
			} else {
				invokeResult = method.invoke(original, args);
			}

			System.out.println("End execution...");
			return invokeResult;
		}

	}

	public static void main(String[] args) throws ExecutionException, InterruptedException {
		Original original = new Original();

		Handler handler = new Handler(original);

		If f = (If) Proxy.newProxyInstance(If.class.getClassLoader(), new Class[]{If.class}, handler);

		String str = f.originalMethod("Hallo");
		System.out.println("result from proxy "+str);

		Future<String> future = f.originalMethodAsync("Hallooooo");
		System.out.println("result from proxy in future " + future.get());

	}

	@Target({ElementType.METHOD, ElementType.TYPE})
	@Retention(RetentionPolicy.RUNTIME)
	@Documented
	@interface InAsync {
		ExecutorType value() default ExecutorType.SINGLETHREAD;
	}


	enum ExecutorType {
		SINGLETHREAD,
		CACHED,
		FOLKJOIN
	}
}

以上是关于java Spring @Aysnc approch通过JDK动态代理的主要内容,如果未能解决你的问题,请参考以下文章

Spring Boot与任务

spring Boot 学习(四Spring Boot与任务)

javascript 使用PhantomJS和Aysnc.js的并行爬虫示例

提升 Spring Boot 吞吐量的 7 个神技,让你的项目飞起来!

promise与aysnc 与EventProxy

promise generator aysnc/await