优秀开源项目解读(四) - Mblog开源博客项目

574 阅读3分钟

简介

一款基于 Spring Boot 的博客系统,支持多用户,支持切换主题!

技术栈

前端: Freemarker、Bootstrap、SeaJs

后端: JDK8、MySQL、Spring Boot、Spring-Data-JPA、Shiro、Lombok

Github:github.com/langhsu/mbl…

功能介绍

  • 个人注册登录
  • 个人信息修改保存
  • 发表博客
  • 文章评论、点赞
  • 消息通知
  • 后台博客管理、评论管理、系统配置等

项目启动步骤、项目详情

启动步骤

配置:src/main/resources/application-mysql.yml (数据库账号密码)、新建db_mblog的数据库
运行:src/main/java/com/mtons/mblog/BootApplication
访问:http://localhost:8080/
后台:http://localhost:8080/admin
账号:默认管理员账号为 admin/12345

web前台截图

项目代码结构分析

└─com
    └─mtons
        └─mblog
            │  BootApplication.java  #启动类
            │
            ├─base
            │  ├─lang
            │  │      Consts.java
            │  │      EntityStatus.java
            │  │      MtonsException.java
            │  │      Result.java
            │  │      Theme.java
            │  │
            │  ├─oauth #第三方登录
            │  │  │  APIConfig.java
            │  │  │  Oauth.java
            │  │  │  OauthBaidu.java
            │  │  │  OauthDouban.java
            │  │  │  OauthGithub.java
            │  │  │  OauthOsc.java
            │  │  │  OauthQQ.java
            │  │  │  OauthRenren.java
            │  │  │  OauthSina.java
            │  │  │
            │  │  └─utils
            │  │          Display.java
            │  │          ...
            │  │
            │  ├─storage #存储相关
            │  │  │  Storage.java
            │  │  │  StorageFactory.java
            │  │  │
            │  │  └─impl
            │  │          AbstractStorage.java
            │  │          AliyunStorageImpl.java
            │  │          NativeStorageImpl.java
            │  │          QiniuStorageImpl.java
            │  │          UpYunStorageImpl.java
            │  │
            │  └─utils
            │          BeanMapUtils.java
.            │          
            │
            ├─config
            │      ContextStartup.java #启动时候初始化全局配置、首页导航等
            │      RedisConfig.java
            │      ShiroConfig.java
            │      SiteConfig.java
            │      SiteOptions.java
            │      WebMvcConfig.java
            │
            ├─modules
            │  ├─aspect
            │  │      HibernateFilterAspect.java
            │  │      PostStatusFilter.java #文章状态过滤注解
            │  │
            │  ├─data #vo,一些传输对象
            │  │      AccountProfile.java 
            │  │      BadgesCount.java
            │  │      CommentVO.java
            │  │      ...
            │  │
            │  ├─entity
            │  │      Channel.java
            │  │      Comment.java
            │  │      ...
            │  │
            │  ├─event #基于spring的事件
            │  │  │  MessageEvent.java      #消息事件
            │  │  │  PostUpdateEvent.java   #文章发布事件(文章数统计、推送通知)
            │  │  │
            │  │  └─handler
            │  │          MessageEventHandler.java
            │  │          PostUpdateEventHandler.java
            │  │
            │  ├─hook #钩子,拦截器
            │  │  │  Hook.java
            │  │  │
            │  │  └─interceptor
            │  │      │  InterceptorHook.java
            │  │      │  InterceptorHookManager.java
            │  │      │  InterceptorHookSupport.java
            │  │      │
            │  │      └─impl
            │  │              HidenContentPugin.java  #因此部分内容的钩子
            │  │              ViewCopyrightPugin.java #声明内容版权的钩子
            │  │
            │  ├─repository
            │  │      ChannelRepository.java
            │  │      ...
            │  │
            │  ├─service
            │  │  │  ChannelService.java
            │  │  │  ...
            │  │  │
            │  │  └─impl
            │  │          ChannelServiceImpl.java
            │  │          ...
            │  │
            │  └─template #freemarker的模板引擎相关
            │      │  BaseMethod.java
            │      │  DirectiveHandler.java
            │      │  TemplateDirective.java
            │      │  TemplateModelUtils.java
            │      │
            │      ├─directive #声明模板
            │      │      ChannelDirective.java
            │      │      ContentsDirective.java
            │      │      ...
            │      │
            │      └─method #声明模板方法
            │              TimeAgoMethod.java
            │
            ├─shiro #shiro相关
            │  │  AccountRealm.java
            │  │  AccountSubjectFactory.java
            │  │  AuthenticatedFilter.java
            │  │  ICredentialsMatcher.java
            │  │
            │  └─tags #shiro与freemarker相关的标签
            │          AuthenticatedTag.java
            │          GuestTag.java
            │          HasAnyRolesTag.java
            │         ...
            │
            └─web
                ├─controller
                │  │  BaseController.java
                │  │
                │  ├─admin #后台管理接口
                │  │      AdminController.java
                │  │      ChannelController.java
                │  │      ...
                │  │
                │  ├─api
                │  │      ApiController.java
                │  │      package-info.java
                │  │
                │  └─site #博客接口
                │      │  ChannelController.java
                │      │  IErrorController.java
                │      │  IndexController.java
                │      │  SearchController.java
                │      │  TagController.java
                │      │  Views.java
                │      │
                │      ├─auth
                │      │      CallbackController.java
                │      │      ...
                │      │
                │      ├─comment
                │      │      CommentController.java
                │      │
                │      ├─posts
                │      │      MindMapController.java
                │      │      PostController.java
                │      │      UploadController.java
                │      │
                │      └─user
                │              FavorController.java
                │              SettingsController.java
                │              UsersController.java
                │
                ├─exceptions
                │      DefaultExceptionHandler.java
                │
                ├─filter
                │      RequestCostFilter.java
                │
                ├─formatter
                │      JsonUtils.java
                │      StringEscapeEditor.java
                │
                ├─interceptor
                │      BaseInterceptor.java
                │
                └─menu
                        Menu.java
                        MenuJsonUtils.java
                        MenusDirective.java

项目技术详情解读

发布与通知

在开发的过程中,事件会遇到这种场景:

做完一件事情之后,需要广播一系诶消息或者通知,告诉其他的模块进行一些事件处理,一般来说,可以一个一个去发送请求通知,但是这种方式比较耗时,且效率极低,那有没有比较好的解决方案呢?那就是事件监听,事件监听也是设计模式中 发布-订阅模式、观察者模式的一种实现。

观察者模式:在对象之间定义了一对多的依赖,这样一来,当一个对象改变状态,依赖它的对象会收到通知并自动更新。

Spring的事件为Bean和Bean之间的消息传递提供支持。当一个对象处理完某种任务后,通知另外的对象进行某些处理,常用的场景有进行某些操作后发送通知,消息,操作记录,发送短信、邮件等情况。 

Spring事件遵循的流程

自定义事件,继承ApplicationEvent(org.springframework.context.ApplicationEvent)

自定义事件监听,实现ApplicationListener(org.springframework.context.ApplicationListener)

使用容器触发事件:

发布事件,使用applicationContext发布事件, ApplicationEvent中,在自定义事件的构造方法中除了第一个source参数,其他参数都可以去自定义, 可以根据项目实际情况进行监听传参,这里就只定义个简单的String字符串的透传。

整体的逻辑实现步骤

第一步:分配自定义订阅和通知时间,继承ApplicationEvent

第二步:分配定义事件监听器,实现ApplicationListener

第三步:使用容器发布事件(订阅时间、通知事件)