基于javaweb+springboot的健身管理系统(Java+ssm+springboot)

主要技术:springmvc、 springboot 、mybatis、mysql 、jQuery、layui、css、jsp shiro权限控制

主要功能截图如下:
用户登录、首页主要功能有:会员信息管理、会员到期续费管理、充值管理、教练课程管理、私教管理、器材管理、小商品售卖管理、信息统计、修改密码等主要功能:

















适用

课程设计,大作业,毕业设计,项目练习,学习演示等

    private AdminuserDao adminuserDao;/*** @Description: 输入端口号直接跳转登录界面* xiaoc* @Date: 2020/4/29*/@RequestMapping("/")public String beforeLogin(){return "login";}/*** @Description: 管理员登录验证方法* xiaoc* @Date: 2020/4/4
    }/*** @Description: 修改密码* xiaoc* @Date: 2020/5/1*/@RequestMapping("/upd/updPassword")public String updPasswordConfirm(String oldPassword,String newPassword,String newPasswordAgain,HttpSession httpSession,Model model){Pattern p = Pattern.compile("^(?=.*[A-Za-z])(?=.*\\d)(?=.*[$@$!.%*#?&])[A-Za-z\\d$@$!.%*#?&]{8,}$");Matcher m = p.matcher(newPassword);if(!m.matches()){model.addAttribute("msg","新密码最少为8位并为字母+数字+特殊字符");return "WEB-INF/jsp/updPassword";
     * xiaoc* @Date: 2020/4/4*/@RequestMapping("/dl/yz")public String login(String username, String password,HttpSession httpSession,Model model){Subject subject= SecurityUtils.getSubject();UsernamePasswordToken userToken=new UsernamePasswordToken(username,DigestUtils.md5Hex(password));try{subject.login(userToken);Adminuser a= adminuserDao.findByAdminNameAndAdminPassword(username,DigestUtils.md5Hex(password));httpSession.setAttribute("user",a);return "WEB-INF/jsp/index";}catch (UnknownAccountException e){model.addAttribute("msg","用户名或密码错误,请重新输入");return "login";}/*Adminuser a= adminuserDao.findByAdminNameAndAdminmima(username,password);if(a!=null){httpSession.setAttribute("user",a);return "WEB-INF/jsp/index" ;}model.addAttribute("mag","账号或密码错误");return "login";*/}
        //注册缓存defaultWebSecurityManager.setCacheManager(getEhCacheManager());return defaultWebSecurityManager ;}@Beanpublic AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(){System.out.println("开启了Shiro注解支持");AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();authorizationAttributeSourceAdvisor.setSecurityManager(getDefaultWebSecurityManager());return authorizationAttributeSourceAdvisor;}@Bean@ConditionalOnMissingBeanpublic DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {DefaultAdvisorAutoProxyCreator defaultAAP = new DefaultAdvisorAutoProxyCreator();defaultAAP.setProxyTargetClass(true);return defaultAAP;}@Bean
     * 这个类是为了对密码进行编码的 ,* 防止密码在数据库里明码保存 , 当然在登陆认证的时候 ,* 这个类也负责对form里输入的密码进行编码* 处理认证匹配处理器:如果自定义需要实现继承HashedCredentialsMatcher*///    @Bean("hashedCredentialsMatcher")//    public HashedCredentialsMatcher getHashedCredentialsMatcher() {//        HashedCredentialsMatcher credentialsMatcher = new HashedCredentialsMatcher();//        //指定加密方式为MD5//        credentialsMatcher.setHashAlgorithmName("MD5");//        //加密次数//        credentialsMatcher.setHashIterations(1024);
    public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {DefaultAdvisorAutoProxyCreator defaultAAP = new DefaultAdvisorAutoProxyCreator();defaultAAP.setProxyTargetClass(true);return defaultAAP;}@Beanpublic ShiroFilterFactoryBean getShiroFilterFactoryBean(){ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean() ;//设置网页安全管理器shiroFilterFactoryBean.setSecurityManager(getDefaultWebSecurityManager());Map<String,String> map = new LinkedHashMap<String,String>() ;//定义可以直接访问的资源map.put("/login.jsp","anon") ;map.put("/vcode.jsp","anon");
        //设置网页安全管理器shiroFilterFactoryBean.setSecurityManager(getDefaultWebSecurityManager());Map<String,String> map = new LinkedHashMap<String,String>() ;//定义可以直接访问的资源map.put("/login.jsp","anon") ;map.put("/vcode.jsp","anon");map.put("/dl/yz","anon") ;map.put("/static/**","anon") ;//取消认证map.put("/logout","logout") ;////  map.put("/add.jsp","perms[user:*]") ;map.put("/**","user") ;shiroFilterFactoryBean.setFilterChainDefinitionMap(map);shiroFilterFactoryBean.setLoginUrl("/login.jsp");shiroFilterFactoryBean.setUnauthorizedUrl("/unauth.jsp");return shiroFilterFactoryBean ;
    @Beanpublic EhCacheManager getEhCacheManager(){EhCacheManager ehCacheManager = new EhCacheManager() ;ehCacheManager.setCacheManagerConfigFile("classpath:ehcache-shiro.xml");return ehCacheManager ;}@Beanpublic CookieRememberMeManager rememberMeManager() {//System.out.println("ShiroConfiguration.rememberMeManager()");CookieRememberMeManager cookieRememberMeManager = new CookieRememberMeManager();cookieRememberMeManager.setCookie(rememberMeCookie());//rememberMe cookie加密的密钥 建议每个项目都不一样 默认AES算法 密钥长度(128 256 512 位)//  cookieRememberMeManager.setCipherKey(Base64.decode("2AvVhdsgUs0FSA3SDFAdag=="));return cookieRememberMeManager;}@Bean
     */@RequestMapping("/dl/yz")public String login(String username, String password,HttpSession httpSession,Model model){Subject subject= SecurityUtils.getSubject();UsernamePasswordToken userToken=new UsernamePasswordToken(username,DigestUtils.md5Hex(password));try{subject.login(userToken);Adminuser a= adminuserDao.findByAdminNameAndAdminPassword(username,DigestUtils.md5Hex(password));httpSession.setAttribute("user",a);return "WEB-INF/jsp/index";}catch (UnknownAccountException e){model.addAttribute("msg","用户名或密码错误,请重新输入");return "login";}/*Adminuser a= adminuserDao.findByAdminNameAndAdminmima(username,password);if(a!=null){httpSession.setAttribute("user",a);return "WEB-INF/jsp/index" ;}model.addAttribute("mag","账号或密码错误");
     * xiaoc* @Date: 2020/4/4*/@RequestMapping("/dl/yz")public String login(String username, String password,HttpSession httpSession,Model model){Subject subject= SecurityUtils.getSubject();UsernamePasswordToken userToken=new UsernamePasswordToken(username,DigestUtils.md5Hex(password));try{subject.login(userToken);Adminuser a= adminuserDao.findByAdminNameAndAdminPassword(username,DigestUtils.md5Hex(password));httpSession.setAttribute("user",a);
     */@RequestMapping("/dl/yz")public String login(String username, String password,HttpSession httpSession,Model model){Subject subject= SecurityUtils.getSubject();UsernamePasswordToken userToken=new UsernamePasswordToken(username,DigestUtils.md5Hex(password));try{subject.login(userToken);Adminuser a= adminuserDao.findByAdminNameAndAdminPassword(username,DigestUtils.md5Hex(password));httpSession.setAttribute("user",a);return "WEB-INF/jsp/index";}catch (UnknownAccountException e){model.addAttribute("msg","用户名或密码错误,请重新输入");return "login";}/*Adminuser a= adminuserDao.findByAdminNameAndAdminmima(username,password);if(a!=null){httpSession.setAttribute("user",a);return "WEB-INF/jsp/index" ;}model.addAttribute("mag","账号或密码错误");return "login";*/}
        subject.logout();return "redirect:/login";}/*** @Description: 跳转到修改密码界面* xiaoc* @Date: 2020/5/1*/@RequestMapping("/updPassword")public String updPassword(){return "WEB-INF/jsp/updPassword";}/*** @Description: 修改密码
    @RequestMapping("/exit")  public String exit(HttpSession session){  session.invalidate();return "login";}  @RequestMapping("/myInfo")  public String myInfo(HttpSession session){  String account=(String) session.getAttribute("account");List<Map<String,Object>> list = userService.findUserByAccount(account);session.setAttribute("userInfo", JSON.toJSON(list));return "user/index";
    public CookieRememberMeManager rememberMeManager() {//System.out.println("ShiroConfiguration.rememberMeManager()");CookieRememberMeManager cookieRememberMeManager = new CookieRememberMeManager();cookieRememberMeManager.setCookie(rememberMeCookie());//rememberMe cookie加密的密钥 建议每个项目都不一样 默认AES算法 密钥长度(128 256 512 位)//  cookieRememberMeManager.setCipherKey(Base64.decode("2AvVhdsgUs0FSA3SDFAdag=="));return cookieRememberMeManager;}@Beanpublic DefaultWebSecurityManager getDefaultWebSecurityManager(){DefaultWebSecurityManager defaultWebSecurityManager = new DefaultWebSecurityManager() ;
     * @Date: 2020/5/1*/@RequestMapping("/upd/updPassword")public String updPasswordConfirm(String oldPassword,String newPassword,String newPasswordAgain,HttpSession httpSession,Model model){Pattern p = Pattern.compile("^(?=.*[A-Za-z])(?=.*\\d)(?=.*[$@$!.%*#?&])[A-Za-z\\d$@$!.%*#?&]{8,}$");Matcher m = p.matcher(newPassword);if(!m.matches()){model.addAttribute("msg","新密码最少为8位并为字母+数字+特殊字符");return "WEB-INF/jsp/updPassword";}if(!newPassword.equals(newPasswordAgain)){model.addAttribute("msg","两次输入新密码不一致,请重新输入");return "WEB-INF/jsp/updPassword";}Adminuser adminuser=(Adminuser) httpSession.getAttribute("user");if(null != adminuser){if(!adminuser.getAdminPassword().equals(DigestUtils.md5Hex(oldPassword))){model.addAttribute("msg","原密码不正确,请重新输入");
    @Beanpublic EhCacheManager getEhCacheManager(){EhCacheManager ehCacheManager = new EhCacheManager() ;ehCacheManager.setCacheManagerConfigFile("classpath:ehcache-shiro.xml");return ehCacheManager ;}@Beanpublic CookieRememberMeManager rememberMeManager() {//System.out.println("ShiroConfiguration.rememberMeManager()");CookieRememberMeManager cookieRememberMeManager = new CookieRememberMeManager();cookieRememberMeManager.setCookie(rememberMeCookie());//rememberMe cookie加密的密钥 建议每个项目都不一样 默认AES算法 密钥长度(128 256 512 位)//  cookieRememberMeManager.setCipherKey(Base64.decode("2AvVhdsgUs0FSA3SDFAdag=="));return cookieRememberMeManager;}@Bean
        map.put("/vcode.jsp","anon");map.put("/dl/yz","anon") ;map.put("/static/**","anon") ;//取消认证map.put("/logout","logout") ;////  map.put("/add.jsp","perms[user:*]") ;map.put("/**","user") ;shiroFilterFactoryBean.setFilterChainDefinitionMap(map);shiroFilterFactoryBean.setLoginUrl("/login.jsp");shiroFilterFactoryBean.setUnauthorizedUrl("/unauth.jsp");return shiroFilterFactoryBean ;}
}
用户管理控制层:
@Controller
@RequestMapping("/user")
public class UserController {@Resource  private IUserService userService;  @ResponseBody@RequestMapping("/login")  public String toIndex(User user,HttpSession session){
    @Beanpublic DefaultWebSecurityManager getDefaultWebSecurityManager(){DefaultWebSecurityManager defaultWebSecurityManager = new DefaultWebSecurityManager() ;defaultWebSecurityManager.setRealm(getMyRealm());//注册记住我defaultWebSecurityManager.setRememberMeManager(rememberMeManager());//注册缓存defaultWebSecurityManager.setCacheManager(getEhCacheManager());return defaultWebSecurityManager ;}@Beanpublic AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(){System.out.println("开启了Shiro注解支持");AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();authorizationAttributeSourceAdvisor.setSecurityManager(getDefaultWebSecurityManager());return authorizationAttributeSourceAdvisor;}@Bean@ConditionalOnMissingBean
        shiroFilterFactoryBean.setUnauthorizedUrl("/unauth.jsp");return shiroFilterFactoryBean ;}
}
用户管理控制层:
@Controller
@RequestMapping("/user")
public class UserController {@Resource  private IUserService userService;  @ResponseBody@RequestMapping("/login")  public String toIndex(User user,HttpSession session){  String account=user.getAccount();user=userService.userLogin(user.getAccount(),user.getPwd());if(user!=null){
    @RequestMapping("/classTable")  public String classTable(HttpSession session){  List<Map<String,Object>> list = userService.findClass();session.setAttribute("classInfo", JSON.toJSON(list));return "user/classTable";}  @RequestMapping("/teachList")  public String teachList(HttpSession session){  return "user/teachList";}  @ResponseBody@RequestMapping("/selectTeach")  public String selectTeach(HttpSession session,Integer id){  List<Map<String,Object>> list = userService.findSeTeach(id);
    //        //指定加密方式为MD5//        credentialsMatcher.setHashAlgorithmName("MD5");//        //加密次数//        credentialsMatcher.setHashIterations(1024);//        credentialsMatcher.setStoredCredentialsHexEncoded(true);//        return credentialsMatcher;//    }@Beanpublic MyRealm getMyRealm(){MyRealm myRealm = new MyRealm() ;//        myRealm.setCredentialsMatcher(getHashedCredentialsMatcher());return myRealm ;}@Beanpublic SimpleCookie rememberMeCookie() {//System.out.println("ShiroConfiguration.rememberMeCookie()");//这个参数是cookie的名称,对应前端的checkbox的name = rememberMeSimpleCookie simpleCookie = new SimpleCookie("ckbox");//<!-- 记住我cookie生效时间30天 ,单位秒;-->simpleCookie.setMaxAge(259200);return simpleCookie;}@Bean
            adminuserDao.updPassword(adminuser.getAdminId(), DigestUtils.md5Hex(newPassword));}Subject subject = SecurityUtils.getSubject();subject.logout();return "redirect:/login.jsp";}
}
密码加密方式:
@Configuration
public class ShiroConfig {/*** 密码校验规则HashedCredentialsMatcher* 这个类是为了对密码进行编码的 ,* 防止密码在数据库里明码保存 , 当然在登陆认证的时候 ,* 这个类也负责对form里输入的密码进行编码
     session.setAttribute("SelectTeachInfo", JSON.toJSON(list));return "true";}  @ResponseBody@RequestMapping("/chooseTeach")  public String chooseTeach(Integer id,Integer cid,Integer uid){  userService.chooseTeach(id,cid,uid);return "true";}  @ResponseBody@RequestMapping("/updateUserInfo")  public String updateUserInfo(Integer id,String account,Integer sex,Integer age,String name,String pwd,String tel,String address){  userService.updateUserInfo(id,account,sex,age,name,pwd,tel,address);
    //        HashedCredentialsMatcher credentialsMatcher = new HashedCredentialsMatcher();//        //指定加密方式为MD5//        credentialsMatcher.setHashAlgorithmName("MD5");//        //加密次数//        credentialsMatcher.setHashIterations(1024);//        credentialsMatcher.setStoredCredentialsHexEncoded(true);//        return credentialsMatcher;//    }@Beanpublic MyRealm getMyRealm(){
@Configuration
public class ShiroConfig {/*** 密码校验规则HashedCredentialsMatcher* 这个类是为了对密码进行编码的 ,* 防止密码在数据库里明码保存 , 当然在登陆认证的时候 ,* 这个类也负责对form里输入的密码进行编码* 处理认证匹配处理器:如果自定义需要实现继承HashedCredentialsMatcher*///    @Bean("hashedCredentialsMatcher")//    public HashedCredentialsMatcher getHashedCredentialsMatcher() {//        HashedCredentialsMatcher credentialsMatcher = new HashedCredentialsMatcher();//        //指定加密方式为MD5//        credentialsMatcher.setHashAlgorithmName("MD5");//        //加密次数//        credentialsMatcher.setHashIterations(1024);//        credentialsMatcher.setStoredCredentialsHexEncoded(true);//        return credentialsMatcher;//    }@Beanpublic MyRealm getMyRealm(){MyRealm myRealm = new MyRealm() ;
     }else{return "false";}}  @RequestMapping("/Forward")  public String loginForward(){  return "user/index";}  @RequestMapping("/exit")  public String exit(HttpSession session){  session.invalidate();return "login";}  @RequestMapping("/myInfo")  public String myInfo(HttpSession session){  String account=(String) session.getAttribute("account");List<Map<String,Object>> list = userService.findUserByAccount(account);session.setAttribute("userInfo", JSON.toJSON(list));return "user/index";}
    public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {DefaultAdvisorAutoProxyCreator defaultAAP = new DefaultAdvisorAutoProxyCreator();defaultAAP.setProxyTargetClass(true);return defaultAAP;}@Beanpublic ShiroFilterFactoryBean getShiroFilterFactoryBean(){ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean() ;//设置网页安全管理器shiroFilterFactoryBean.setSecurityManager(getDefaultWebSecurityManager());Map<String,String> map = new LinkedHashMap<String,String>() ;//定义可以直接访问的资源map.put("/login.jsp","anon") ;map.put("/vcode.jsp","anon");map.put("/dl/yz","anon") ;map.put("/static/**","anon") ;//取消认证map.put("/logout","logout") ;//
    @RequestMapping("/Forward")  public String loginForward(){  return "user/index";}  @RequestMapping("/exit")  public String exit(HttpSession session){  session.invalidate();return "login";}  @RequestMapping("/myInfo")  public String myInfo(HttpSession session){  String account=(String) session.getAttribute("account");List<Map<String,Object>> list = userService.findUserByAccount(account);session.setAttribute("userInfo", JSON.toJSON(list));return "user/index";}
        subject.logout();return "redirect:/login";}/*** @Description: 跳转到修改密码界面* xiaoc* @Date: 2020/5/1*/@RequestMapping("/updPassword")public String updPassword(){return "WEB-INF/jsp/updPassword";}/*** @Description: 修改密码* xiaoc* @Date: 2020/5/1*/@RequestMapping("/upd/updPassword")public String updPasswordConfirm(String oldPassword,String newPassword,String newPasswordAgain,HttpSession httpSession,Model model){Pattern p = Pattern.compile("^(?=.*[A-Za-z])(?=.*\\d)(?=.*[$@$!.%*#?&])[A-Za-z\\d$@$!.%*#?&]{8,}$");Matcher m = p.matcher(newPassword);if(!m.matches()){model.addAttribute("msg","新密码最少为8位并为字母+数字+特殊字符");return "WEB-INF/jsp/updPassword";
        //注册缓存defaultWebSecurityManager.setCacheManager(getEhCacheManager());return defaultWebSecurityManager ;}@Beanpublic AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(){System.out.println("开启了Shiro注解支持");AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();authorizationAttributeSourceAdvisor.setSecurityManager(getDefaultWebSecurityManager());return authorizationAttributeSourceAdvisor;}@Bean@ConditionalOnMissingBeanpublic DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {DefaultAdvisorAutoProxyCreator defaultAAP = new DefaultAdvisorAutoProxyCreator();

适用

课程设计,大作业,毕业设计,项目练习,学习演示等

基于javaweb+springboot的健身管理系统(Java+ssm+springboot)相关推荐

  1. 基于javaweb+mysql的健身管理系统(java+ssm+springboot)

    基于javaweb+mysql的健身管理系统(java+ssm+springboot) 运行环境 Java≥8.MySQL≥5.7 开发工具 eclipse/idea/myeclipse/sts等均可 ...

  2. 基于javaweb+springboot的健身房管理系统(Java+ssm+springboot)

    基于javaweb+springboot的健身房管理系统(Java+ssm+springboot) 主要技术:springmvc. springboot .mybatis.mysql .jQuery. ...

  3. 基于javaweb的高校运动会管理系统(java+ssm+jsp+js+jquery+mysql)

    基于javaweb的高校运动会管理系统(java+ssm+jsp+js+jquery+mysql) 运行环境 Java≥8.MySQL≥5.7.Tomcat≥8 开发工具 eclipse/idea/m ...

  4. 基于javaweb的律师事务所律师管理系统(java+ssm+html+js+jsp+mysql)

    基于javaweb的律师事务所律师管理系统(java+ssm+html+js+jsp+mysql) 运行环境 Java≥8.MySQL≥5.7.Tomcat≥8 开发工具 eclipse/idea/m ...

  5. 基于javaweb的设备台账管理系统(java+ssm+html+jsp+js+mysql)

    基于javaweb的设备台账管理系统(java+ssm+html+jsp+js+mysql) 运行环境 Java≥8.MySQL≥5.7.Tomcat≥8 开发工具 eclipse/idea/myec ...

  6. 基于javaweb的医药信息管理系统(java+ssm+html+easyui+mysql)

    基于javaweb的医药信息管理系统(java+ssm+html+easyui+mysql) 运行环境 Java≥8.MySQL≥5.7.Tomcat≥8 开发工具 eclipse/idea/myec ...

  7. 基于javaweb的中药药方管理系统(java+ssm+jsp+bootstrap+mysql)

    基于javaweb的中药药方管理系统(java+ssm+jsp+bootstrap+mysql) 运行环境 Java≥8.MySQL≥5.7.Tomcat≥8 开发工具 eclipse/idea/my ...

  8. 基于javaweb的酒吧后台管理系统(java+ssm+jsp+html+mysql)

    基于javaweb的酒吧后台管理系统(java+ssm+jsp+html+mysql) 运行环境 Java≥8.MySQL≥5.7.Tomcat≥8 开发工具 eclipse/idea/myeclip ...

  9. 基于javaweb的网吧计费管理系统(java+ssm+html+js+jsp+mysql)

    基于javaweb的网吧计费管理系统(java+ssm+html+js+jsp+mysql) 运行环境 Java≥8.MySQL≥5.7.Tomcat≥8 开发工具 eclipse/idea/myec ...

最新文章

  1. 里程碑 | 原来大脑有两套GPS!陆军军医大学张生家团队发现海马外全新空间导航系统...
  2. ONES 万事联合创始人 amp; CTO 冯斌:企业服务产品的探索实践
  3. asp.net面试题收集[2006.4.28更新]
  4. 实用 —— PowerCLI (一)
  5. 很实用的一篇HTTP状态码
  6. js-cookie使用方法
  7. python字符串对齐_Python - 字符串对齐
  8. 世界手机号码格式_世界上手机号码最长的国家是中国,最短的是哪个国家?
  9. Spark基础学习笔记05:搭建Spark Standalone模式的集群
  10. Spring Boot快速上手
  11. where,having与 group by连用的区别
  12. 十分钟弄懂最快的APP自动化工具uiautomator2
  13. linux远程备份视频教程,linux实现自动远程备份(scp+ssh)
  14. Python--模块微谈
  15. Kaggle实战之房价预测
  16. 阿里大牛:如何画出一图胜千言的技术架构图?
  17. MSOCache文件夹能否删除?
  18. 计算机毕业设计Javaweb实验室课表管理系统(源码+系统+mysql数据库+lw文档)
  19. python比赛积分类算法题_python常用算法题
  20. 个人支付收款方案-PayJS

热门文章

  1. 测试芯片的软件,SynoChip芯片测试程序
  2. POJ使用指南——1
  3. STC89C52之直流电机 ----自学笔记
  4. css规范(书写顺序)
  5. 如果你请求返回是502, 这个时候怎么定位这个问题?
  6. Java基础练习-输入的年份、产品类型和随机数产生固定资产编号
  7. 车联网,车载ivi(hu)等。
  8. 阿里资深架构师钟华曰:中台战略思想与架构实战;含内部实施手册
  9. 关于Python的mock
  10. Mock InjectMocks ( @Mock 和 @InjectMocks )区别