java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > springboot通过注解实现多线程

springboot如何通过注解实现多线程

作者:aiyongbo123456

在Spring Boot中实现异步方法时,如果直接在调用类中使用`@Async`注解,可能会导致异步失败,正确的做法是将实现异步的方法放在一个独立的类中,并通过Spring生成的bean来调用这个方法,这样可以成功实现异步

springboot通过注解实现多线程

1、springboot启动类中添加 @EnableAsync

package com.zr.gktjweb;


import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableAsync;

@SpringBootApplication
@EnableAsync
public class GktjwebApplication {

    public static void main(String[] args) {

        SpringApplication.run(GktjwebApplication.class, args);
    }

}

2、在调用类之外的另一个类方法中添加

package com.zr.gktjweb.aspect;

import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

//@Component
public class AsyThread {
//    @Override
    @Async
    public void run() {
        System.out.println("---------异步线程---------"+Thread.currentThread().getName());
    }
}

3、在另一个类中调用此方法

package com.zr.gktjweb.controller.login;

import com.zr.gktjweb.aspect.AsyThread;
import com.zr.gktjweb.common.HttpClientUtil;
import com.zr.gktjweb.common.ResponseBean;
import com.zr.gktjweb.constant.SysCode;
import com.zr.gktjweb.model.SysUser;
import com.zr.gktjweb.util.ComUtil;
import com.zr.gktjweb.util.JSONUtils;
import com.zr.gktjweb.util.UserUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import net.sf.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;

@Api(tags = "登录")
@Controller
public class LoginController {
    @Value("${baseurl}")
    private String baseurl;
    @Value("${login_url}")
    private String loginUrl;
    @Value("${logout_url}")
    private String logoutUrl;
    @Value("${syslogin_url}")
    private String sysloginUrl;
    @Value("${updateUserSessionByusername_url}")
    private String updateUserSessionByusernameUrl;
    @Value("${updatePass_url}")
    private String updatePassUrl;
    private static final Logger LOGGER = LoggerFactory.getLogger(LoginController.class);

    @ApiOperation(value = "登录", notes = "登录验证")
    @ApiImplicitParams({@ApiImplicitParam(name = "username", value = "姓名", required = true, dataType = "String"),
            @ApiImplicitParam(name = "password", value = "密码", required = true, dataType = "String")
    })
    @RequestMapping(value = "/login.do", method = RequestMethod.POST)
    @ResponseBody
    public ResponseBean login(String username, String password) {
        String url = baseurl + loginUrl;
        Map<String, String> map = new HashMap<>();
        map.put("username", username);
        map.put("password", password);
        String result = "";
        new AsyThread().run();
        System.out.println("--------当前线程--------"+Thread.currentThread().getName());
        //请求服务失败
        try {
            result = HttpClientUtil.doPost(url, map);
        } catch (Exception e) {
            e.printStackTrace();
            LOGGER.error("用户登录", e);
            return new ResponseBean(SysCode.errCode, "系统异常,请联系管理员", "");
        }
        JSONObject json = JSONObject.fromObject(result);
        //登录验证未通过
        if (!json.getString("code").equals(SysCode.successCode + "")) {
            ResponseBean responseBean = JSONUtils.jsonToObject(ResponseBean.class, result);
            return responseBean;
        }
        //验证通过,在session中设置token
        JSONObject dataJson = (JSONObject) json.get("data");
        String userJson = dataJson.getString("user");
        SysUser sysUser = JSONUtils.jsonToObject(SysUser.class, userJson);
        JSONObject tokenJson = (JSONObject) dataJson.get("token");
        String token = tokenJson.getString("token");
        UserUtil.setToken(token);
        UserUtil.setUserSession(sysUser);
        //第一次登陆修改密码
        if(ComUtil.isEmpty(sysUser.getLastlogindate())){
            return new ResponseBean(SysCode.retPwdCode, "", "");
        }
        String url1 = "/index.html";
        Map<String, Object> resMap = new HashMap<>();
        resMap.put("url", url1);
        return new ResponseBean(SysCode.successCode, "登录成功", resMap);
    }

    /**
     * 注销登录
     *
     * @param request
     * @return
     */
    @RequestMapping("/loginout.do")
    public String loginOut(HttpServletRequest request) {
        request.getSession().invalidate();
        String url=baseurl+logoutUrl;
        HttpClientUtil.doGet(url);
        return "redirect:/";
    }

    @PostMapping("/users/updatePass.do")
    @ApiOperation(value = "修改密码")
    @ResponseBody
    public ResponseBean changePassword(String username, String oldPassword, String newPassword) {
        String url = baseurl + updatePassUrl;
        Map<String, String> map = new HashMap<>();
        map.put("username", username);
        map.put("oldPassword", oldPassword);
        map.put("newPassword", newPassword);
        String result = HttpClientUtil.doPost(url, map);
        ResponseBean responseBean = JSONUtils.jsonToObject(ResponseBean.class, result);
        //修改密码后重新登录
        ResponseBean loginResult=login(username,newPassword);
        //登录验证未通过
        if (!loginResult.getCode().toString().equals(SysCode.successCode + "")) {
            return loginResult;
        }
        return responseBean;
    }

    @ApiOperation(value = "当前登录用户")
    @GetMapping("/sys/login.do")
    @ResponseBody
    public SysUser getLoginInfo() {
        return UserUtil.getCurrentUser();
    }
}

调用controller层后结果如下:

实现异步失败。

5、后改为将实现异步的类

注入到controller层。通过spring生成的bean来调用异步方法:

package com.zr.gktjweb.aspect;

import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

@Component
public class AsyThread {
//    @Override
    @Async
    public void run() {
        System.out.println("---------异步线程---------"+Thread.currentThread().getName());
    }
}

package com.zr.gktjweb.controller.login;

import com.zr.gktjweb.aspect.AsyThread;
import com.zr.gktjweb.common.HttpClientUtil;
import com.zr.gktjweb.common.ResponseBean;
import com.zr.gktjweb.constant.SysCode;
import com.zr.gktjweb.model.SysUser;
import com.zr.gktjweb.util.ComUtil;
import com.zr.gktjweb.util.JSONUtils;
import com.zr.gktjweb.util.UserUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import net.sf.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;

@Api(tags = "登录")
@Controller
public class LoginController {
    @Value("${baseurl}")
    private String baseurl;
    @Value("${login_url}")
    private String loginUrl;
    @Value("${logout_url}")
    private String logoutUrl;
    @Value("${syslogin_url}")
    private String sysloginUrl;
    @Value("${updateUserSessionByusername_url}")
    private String updateUserSessionByusernameUrl;
    @Value("${updatePass_url}")
    private String updatePassUrl;
    private static final Logger LOGGER = LoggerFactory.getLogger(LoginController.class);

    @Autowired
    AsyThread asyThread;


    @ApiOperation(value = "登录", notes = "登录验证")
    @ApiImplicitParams({@ApiImplicitParam(name = "username", value = "姓名", required = true, dataType = "String"),
            @ApiImplicitParam(name = "password", value = "密码", required = true, dataType = "String")
    })
    @RequestMapping(value = "/login.do", method = RequestMethod.POST)
    @ResponseBody
    public ResponseBean login(String username, String password) {
        String url = baseurl + loginUrl;
        Map<String, String> map = new HashMap<>();
        map.put("username", username);
        map.put("password", password);
        String result = "";
        asyThread.run();
        System.out.println("--------当前线程--------"+Thread.currentThread().getName());
        //请求服务失败
        try {
            result = HttpClientUtil.doPost(url, map);
        } catch (Exception e) {
            e.printStackTrace();
            LOGGER.error("用户登录", e);
            return new ResponseBean(SysCode.errCode, "系统异常,请联系管理员", "");
        }
        JSONObject json = JSONObject.fromObject(result);
        //登录验证未通过
        if (!json.getString("code").equals(SysCode.successCode + "")) {
            ResponseBean responseBean = JSONUtils.jsonToObject(ResponseBean.class, result);
            return responseBean;
        }
        //验证通过,在session中设置token
        JSONObject dataJson = (JSONObject) json.get("data");
        String userJson = dataJson.getString("user");
        SysUser sysUser = JSONUtils.jsonToObject(SysUser.class, userJson);
        JSONObject tokenJson = (JSONObject) dataJson.get("token");
        String token = tokenJson.getString("token");
        UserUtil.setToken(token);
        UserUtil.setUserSession(sysUser);
        //第一次登陆修改密码
        if(ComUtil.isEmpty(sysUser.getLastlogindate())){
            return new ResponseBean(SysCode.retPwdCode, "", "");
        }
        String url1 = "/index.html";
        Map<String, Object> resMap = new HashMap<>();
        resMap.put("url", url1);
        return new ResponseBean(SysCode.successCode, "登录成功", resMap);
    }

    /**
     * 注销登录
     *
     * @param request
     * @return
     */
    @RequestMapping("/loginout.do")
    public String loginOut(HttpServletRequest request) {
        request.getSession().invalidate();
        String url=baseurl+logoutUrl;
        HttpClientUtil.doGet(url);
        return "redirect:/";
    }

    @PostMapping("/users/updatePass.do")
    @ApiOperation(value = "修改密码")
    @ResponseBody
    public ResponseBean changePassword(String username, String oldPassword, String newPassword) {
        String url = baseurl + updatePassUrl;
        Map<String, String> map = new HashMap<>();
        map.put("username", username);
        map.put("oldPassword", oldPassword);
        map.put("newPassword", newPassword);
        String result = HttpClientUtil.doPost(url, map);
        ResponseBean responseBean = JSONUtils.jsonToObject(ResponseBean.class, result);
        //修改密码后重新登录
        ResponseBean loginResult=login(username,newPassword);
        //登录验证未通过
        if (!loginResult.getCode().toString().equals(SysCode.successCode + "")) {
            return loginResult;
        }
        return responseBean;
    }

    @ApiOperation(value = "当前登录用户")
    @GetMapping("/sys/login.do")
    @ResponseBody
    public SysUser getLoginInfo() {
        return UserUtil.getCurrentUser();
    }
}

访问contrller层后,结果如下:

成功实现异步。

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

您可能感兴趣的文章:
阅读全文