作用: 在方法上加上@Async()注解就能使该方法变为异步方法,就会开启新的线程去执行
注意: 适用于非controller层
Async注解定义:
package com.future.common.annotation;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
@Retention(RUNTIME)
@Target(METHOD)
public @interface Async {}拦截器代码:
package com.future.common.interceptor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import com.future.common.annotation.Async;
import com.jfinal.aop.Interceptor;
import com.jfinal.aop.Invocation;
public class AsyncInterceptor implements Interceptor {
	private static ExecutorService cachedPool = Executors.newCachedThreadPool();
	@Override
	public void intercept(Invocation inv) {
		if (inv.getMethod().getAnnotation(Async.class) != null) {
		        //无返回值方法
			if (inv.getMethod().getReturnType().equals(Void.TYPE)) {
				cachedPool.submit(() -> {
					inv.invoke();
				});
                        //需要返回值方法
			} else {
				@SuppressWarnings("unchecked")
				Future<Object> future = cachedPool.submit(() -> {
					inv.invoke();
					return ((Future<Object>) inv.getReturnValue()).get();
				});
				inv.setReturnValue(future);
			}
			return;
		} else {
			inv.invoke();
		}
	}
}无返回值方法使用:
	@Async()
	public void validateUser(String usernameOrPhone, String password) {
		SysUser user = this.sysUserDao.findUserByUsernameOrPhone(usernameOrPhone);
		if (user == null) {
			throw new AuthenticationException("不存在用户名为[" + usernameOrPhone + "]的用户!");
		}
		if("0".equals(user.getSfyxdl()) || StrKit.isBlank(user.getSfyxdl())){
			throw new AuthenticationException("该员工不允许登录系统!");
		}
		String passwordDb = user.getPassword();
		if (passwordDb == null || !passwordDb.equals(SecureUtil.md5(password))) {
			throw new AuthenticationException("密码错误!");
		}
	}有返回值方法使用:
注意返回值要是Futrue类型的
	@Async()
	public Future<SysUser> findUserById(String userid) {
		if(StrKit.isBlank(userid)){
			throw new AppException("用户信息为空!");
		}
		return CompletableFuture.completedFuture(this.sysUserDao.findById(userid));
	}调用者获取返回值:
Future<SysUser> user = this.sysUserService.findUserById(userid); SysUser u = user.get();
关注我的公众号,免费获取Java + Jfinal学习视频

 
 
 
 
 
 
 
 
 
如果是为了让客户端尽快得到响应, inv.invoke() 后面应该还要添加一句:
inv.getController().renderNull();
因为在新原线程响应客户端以后, response 已经有 render 动作向其输出信息了,如果异步线程中再次对 response 输出信息会出问题