作用: 在方法上加上@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 输出信息会出问题