微人事项目代码泛读结对练习经验分享_微人事代码精读,2024年最新拥有百万粉丝的大牛讲述学大数据开发的历程

先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前阿里P7

深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新大数据全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
img
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上大数据知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以添加V获取:vip204888 (备注大数据)
img

正文

(2) 体系结构图(包图):通过绘制体系结构图来了解整个软件的总体设计思路;

(3) 类之间的调用关系图:通过绘制类之间的调用关系图来掌握微人事的具体设计;

(4) 核心类的主要作用:通过给出核心类的主要作用来进一步加深对软件设计的理解。

1.MailReceiver类

@Component
 public class MailReceiver {
 
   public static final Logger logger = LoggerFactory.getLogger(MailReceiver.class);
 
   @Autowired
   JavaMailSender javaMailSender;
   @Autowired
   MailProperties mailProperties;
   @Autowired
   TemplateEngine templateEngine;
   @Autowired
   StringRedisTemplate redisTemplate;
 
   @RabbitListener(queues = MailConstants.MAIL\_QUEUE\_NAME)
   public void handler(Message message, Channel channel) throws IOException {
     Employee employee = (Employee) message.getPayload();
     MessageHeaders headers = message.getHeaders();
     Long tag = (Long) headers.get(AmqpHeaders.DELIVERY\_TAG);
     String msgId = (String) headers.get("spring\_returned\_message\_correlation");
     if (redisTemplate.opsForHash().entries("mail\_log").containsKey(msgId)) {
       //redis 中包含该 key,说明该消息已经被消费过
       logger.info(msgId + ":消息已经被消费");
       channel.basicAck(tag, false);//确认消息已消费
       return;
     }
     //收到消息,发送邮件
     MimeMessage msg = javaMailSender.createMimeMessage();
     MimeMessageHelper helper = new MimeMessageHelper(msg);
     try {
       helper.setTo(employee.getEmail());
       helper.setFrom(mailProperties.getUsername());
       helper.setSubject("入职欢迎");
       helper.setSentDate(new Date());
       Context context = new Context();
       context.setVariable("name", employee.getName());
       context.setVariable("posName", employee.getPosition().getName());
       context.setVariable("joblevelName", employee.getJobLevel().getName());
       context.setVariable("departmentName", employee.getDepartment().getName());
       String mail = templateEngine.process("mail", context);
       helper.setText(mail, true);
       javaMailSender.send(msg);
       redisTemplate.opsForHash().put("mail\_log", msgId, "javaboy");
       channel.basicAck(tag, false);
       logger.info(msgId + ":邮件发送成功");
     } catch (MessagingException e) {
       channel.basicNack(tag, false, true);
       e.printStackTrace();
       logger.error("邮件发送失败:" + e.getMessage());
     }
   }
 }

主要作用:

这段代码是一个邮件接收器 MailReceiver,通过 RabbitMQ 监听特定队列中的消息,并处理发送邮件的逻辑。让我简单解释一下代码的主要功能:

  1. 通过 @Autowired 注解注入了 JavaMailSender、MailProperties、TemplateEngine 和 StringRedisTemplate 实例。
  2. 使用 @RabbitListener 注解监听名为 MailConstants.MAIL_QUEUE_NAME 的 RabbitMQ 队列, MailConstants.MAIL_QUEUE_NAME的值可以在MailConstants常量类找到

public static final String MAIL_QUEUE_NAME = “javaboy.mail.queue”;

  1. 在 handler 方法中,从消息中获取员工信息,并检查消息是否已经被消费过(通过 Redis)。
  2. 如果消息未被消费过,则利用MimeMessage构建邮件内容并发送邮件,发送成功后将消息 ID 记录到 Redis 缓存中。
  3. 利用try-catch进行处理,如果发送过程中出现异常,将消息标记为未确认状态,并记录错误日志。

2.各个Control类(以SalaryControl类为例)

@RestController
 @RequestMapping("/salary/sob")
 public class SalaryController {
   @Autowired
   SalaryService salaryService;
 
   @GetMapping("/")
   public List<Salary> getAllSalaries() {
     return salaryService.getAllSalaries();
   }
 
   @PostMapping("/")
   public RespBean addSalary(@RequestBody Salary salary) {
     if (salaryService.addSalary(salary) == 1) {
       return RespBean.ok("添加成功!");
     }
     return RespBean.error("添加失败!");
   }
 
   @DeleteMapping("/{id}")
   public RespBean deleteSalaryById(@PathVariable Integer id) {
     if (salaryService.deleteSalaryById(id) == 1) {
       return RespBean.ok("删除成功!");
     }
     return RespBean.error("删除失败!");
   }
 
   @PutMapping("/")
   public RespBean updateSalaryById(@RequestBody Salary salary) {
     if (salaryService.updateSalaryById(salary) == 1) {
       return RespBean.ok("更新成功!");
     }
     return RespBean.error("更新失败!");
   }
 }

这个项目以Restful风格开发控制器,这个用例SalaryControl的作用是用于处理与薪资信息相关的HTTP请求。

  1. 通过@Autowired自动注入了SalaryService服务,用于处理与薪资信息相关的业务逻辑,一般来说功能的实现都需要放到service层进行处理,Controller层专注处理通讯问题。
  2. @GetMapping(“/”)注解的getAllSalaries()方法处理HTTP的GET请求,用于获取所有的薪资信息列表。
  3. @PostMapping(“/”)注解的addSalary(@RequestBody Salary salary)方法处理HTTP的POST请求,用于添加新的薪资信息。
  4. @DeleteMapping(“/{id}”)注解的deleteSalaryById(@PathVariable Integer id)方法处理HTTP的DELETE请求,根据提供的id删除特定的薪资信息。
  5. @PutMapping(“/”)注解的updateSalaryById(@RequestBody Salary salary)方法处理HTTP的PUT请求,用于更新特定的薪资信息。

选择这个类作为样例是因为这个使用到了比较全面的RestfulAPI中的GET(获取)、POST(创建)、DELETE(删除)和PUT(更新),用于实现对薪资信息的增删改查功能。

  1. SecurityConfig安全
@Configuration
 public class SecurityConfig extends WebSecurityConfigurerAdapter {
   @Autowired
   HrService hrService;
   @Autowired
   CustomFilterInvocationSecurityMetadataSource customFilterInvocationSecurityMetadataSource;
   @Autowired
   CustomUrlDecisionManager customUrlDecisionManager;
 
   @Bean
   PasswordEncoder passwordEncoder() {
     return new BCryptPasswordEncoder();
   }
 
   @Override
   protected void configure(AuthenticationManagerBuilder auth) throws Exception {
     auth.userDetailsService(hrService);
   }
 
   @Override
   public void configure(WebSecurity web) throws Exception {
     web.ignoring().antMatchers("/css/\*\*", "/js/\*\*", "/index.html", "/img/\*\*", "/fonts/\*\*", "/favicon.ico", "/verifyCode");
   }
 
   @Bean
   LoginFilter loginFilter() throws Exception {
     LoginFilter loginFilter = new LoginFilter();
     loginFilter.setAuthenticationSuccessHandler((request, response, authentication) -> {
           response.setContentType("application/json;charset=utf-8");
           PrintWriter out = response.getWriter();
           Hr hr = (Hr) authentication.getPrincipal();
           hr.setPassword(null);
           RespBean ok = RespBean.ok("登录成功!", hr);
           String s = new ObjectMapper().writeValueAsString(ok);
           out.write(s);
           out.flush();
           out.close();
         }
     );
     loginFilter.setAuthenticationFailureHandler((request, response, exception) -> {
           response.setContentType("application/json;charset=utf-8");
           PrintWriter out = response.getWriter();
           RespBean respBean = RespBean.error(exception.getMessage());
           if (exception instanceof LockedException) {
             respBean.setMsg("账户被锁定,请联系管理员!");
           } else if (exception instanceof CredentialsExpiredException) {
             respBean.setMsg("密码过期,请联系管理员!");
           } else if (exception instanceof AccountExpiredException) {
             respBean.setMsg("账户过期,请联系管理员!");
           } else if (exception instanceof DisabledException) {
             respBean.setMsg("账户被禁用,请联系管理员!");
           } else if (exception instanceof BadCredentialsException) {
             respBean.setMsg("用户名或者密码输入错误,请重新输入!");
           }
           out.write(new ObjectMapper().writeValueAsString(respBean));
           out.flush();
           out.close();
         }
     );
     loginFilter.setAuthenticationManager(authenticationManagerBean());
     loginFilter.setFilterProcessesUrl("/doLogin");
     ConcurrentSessionControlAuthenticationStrategy sessionStrategy = new ConcurrentSessionControlAuthenticationStrategy(sessionRegistry());
     sessionStrategy.setMaximumSessions(1);
     loginFilter.setSessionAuthenticationStrategy(sessionStrategy);
     return loginFilter;
   }
 
   @Bean
   SessionRegistryImpl sessionRegistry() {
     return new SessionRegistryImpl();
   }
 
   @Override
   protected void configure(HttpSecurity http) throws Exception {
     http.authorizeRequests()
         .withObjectPostProcessor(new ObjectPostProcessor<FilterSecurityInterceptor>() {
           @Override
           public <O extends FilterSecurityInterceptor> O postProcess(O object) {
             object.setAccessDecisionManager(customUrlDecisionManager);
             object.setSecurityMetadataSource(customFilterInvocationSecurityMetadataSource);
             return object;
           }
         })
         .and()
         .logout()
         .logoutSuccessHandler((req, resp, authentication) -> {
               resp.setContentType("application/json;charset=utf-8");
               PrintWriter out = resp.getWriter();
               out.write(new ObjectMapper().writeValueAsString(RespBean.ok("注销成功!")));
               out.flush();
               out.close();
             }
         )
         .permitAll()
         .and()
         .csrf().disable().exceptionHandling()
         //没有认证时,在这里处理结果,不要重定向
         .authenticationEntryPoint((req, resp, authException) -> {
               resp.setContentType("application/json;charset=utf-8");
               resp.setStatus(401);
               PrintWriter out = resp.getWriter();
               RespBean respBean = RespBean.error("访问失败!");
               if (authException instanceof InsufficientAuthenticationException) {
                 respBean.setMsg("请求失败,请联系管理员!");
               }
               out.write(new ObjectMapper().writeValueAsString(respBean));
               out.flush();
               out.close();
             }
         );
     http.addFilterAt(new ConcurrentSessionFilter(sessionRegistry(), event -> {
       HttpServletResponse resp = event.getResponse();
       resp.setContentType("application/json;charset=utf-8");


**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**

**需要这份系统化的资料的朋友,可以添加V获取:vip204888 (备注大数据)**
![img](https://i-blog.csdnimg.cn/blog_migrate/eefd4616ee9367dfcb293e6b147d7473.png)

**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**

ication/json;charset=utf-8");


**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**

**需要这份系统化的资料的朋友,可以添加V获取:vip204888 (备注大数据)**
[外链图片转存中...(img-hrYwRtvz-1713402096715)]

**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值