苍穹外卖重拾01

微服务这块虽然还没看完, 但是想先把springboot再看一遍后,再去继续学习微服务

项目架构

这是一个多模块Maven项目,采用分层架构:

  • sky-common: 公共模块,包含工具类、配置等
  • sky-pojo: 实体类模块,包含DTO、VO、Entity等
  • sky-server: 核心业务模块,包含Controller、Service、Mapper等

项目细解

启动顺序

  1. main → SpringApplication.run

  2. 扫包 → 发现 @Configuration → 实例化配置类 → 调用 @Bean

  3. 启动内嵌 Tomcat → DispatcherServlet 注册完成

  4. 项目可对外提供服务

 sky-common模块(公共模块)

constant/: 常量定义

context/: 上下文管理

基础上下文,存储当前线程用户信息

exception/: 自定义异常类

  • 包含账号锁定、账号未找到、登录失败等各种业务异常
  • 都是继承自RuntimeException,因为java中只有这个类及其子类才是“非受检异常”不需要显示捕获或声明抛出,而对其他类,编译器会强制检查。
  • RuntimeException是为了让业务异常“可抛可不捕”,由调用者或全局处理器决定是否处理,避免代码被try-catch淹没

json/: java对象和字符串之间的序列化和反序列化

result/: 结果响应类

utils/: 工具类

JWT工具类
  • createJWT:用密钥 + 业务数据 → 生成一条防篡改的 Token。

  • parseJWT:用同样的密钥 → 验证 Token 合法性并取出业务数据。

HTTP 请求工具类
  • HttpClientUtil“项目中所有后端 HTTP 调用的统一交通工具”
  • 无论是 调用微信支付、查询物流、请求第三方地图接口、还是内部微服务通信,都靠它完成 GET/POST(表单或 JSON)。
  • 它是 “后端项目里的 Postman” —— 任何需要 向外发 HTTP 请求 的地方,都会先想到 HttpClientUtil

 sky-pojo模块(数据模型模块)

前端要看的包装成 VO,网络要传的包装成 DTO,数据库表的影子叫 DO/PO,夹在中间跑业务的叫 BO,仓库操作靠 DAO,不想引框架就是 POJO。

dto/: 数据传输对象

用于不同层之间传输数据,减少接口调用次数

entity/: 实体类

与PO类似,与数据库表结构一一对应

vo/: 视图对象

主要用于前端展示层,封装展示所需的数据

sky-server模块(核心业务模块)

controller/: 控制器

常用注解
功能分组注解作用(专业术语)
启动与配置@SpringBootApplication聚合 @Configuration + @EnableAutoConfiguration + @ComponentScan,用于启动 Spring Boot 应用。
@Configuration声明当前类为配置类,内部可定义 @Bean 方法。
@Bean将方法返回对象注册为 Spring IoC 容器管理的单例 Bean。
@Value将配置文件中的属性值注入到字段或方法参数。
@ConfigurationProperties将指定前缀的配置批量绑定到 POJO 并注册为 Bean。
组件声明@RestController组合 @Controller + @ResponseBody,控制器方法返回值直接序列化为 JSON。
@Controller声明控制器层组件,配合视图解析器返回页面。
@Service标记业务逻辑层组件,语义化别名。
@Repository标记持久层组件,并启用异常转换。
@Component通用型组件声明,可被组件扫描。
HTTP 映射@RequestMapping通用请求映射,可细化方法/路径/媒体类型。
@GetMappingRequestMethod.GET 快捷映射。
@PostMappingRequestMethod.POST 快捷映射。
@PutMappingRequestMethod.PUT 快捷映射。
@DeleteMappingRequestMethod.DELETE 快捷映射。
@PatchMappingRequestMethod.PATCH 快捷映射。
参数绑定@PathVariable将 URI 模板变量绑定到方法参数。
@RequestParam将查询参数或表单字段绑定到方法参数。
@RequestBody将 HTTP 请求体反序列化为 Java 对象。
@RequestHeader将指定请求头值绑定到方法参数。
@CookieValue将指定 Cookie 值绑定到方法参数。
异常处理@ControllerAdvice定义全局异常处理类,跨控制器生效。
@ExceptionHandler标注异常处理方法,捕获指定异常。
@ResponseStatus指定异常时返回的 HTTP 状态码。
依赖注入@Autowired按类型自动装配 Bean。
@Qualifier指定 Bean 名称,解决同类型多 Bean 冲突。
@ResourceJSR-250 按名称装配 Bean。
事务与缓存@Transactional声明式事务边界,方法级或类级。
@Cacheable方法结果缓存,下次调用直接返回缓存值。
生命周期@PostConstruct在 Bean 初始化完成后执行。
@PreDestroy在 Bean 销毁前执行。
MyBatis@Mapper标记接口为 MyBatis Mapper,自动生成代理实现。
@Param为 Mapper 接口多参数指定命名。
AOP@Aspect声明切面类,定义横切关注点。
@Before前置通知,方法执行前织入。
@Around环绕通知,可控制方法是否执行。
跨域与 WebSocket@CrossOrigin允许跨域请求,可细化到方法级。
@EnableWebSocketMessageBroker启用 STOMP 消息代理,支持 WebSocket。
自动注入

@Autowired接口变量 注入成 实现类对象
实现类靠 @Service(或 @Component)被 Spring 扫描注册,运行时通过 JDK 动态代理或 CGLIB 完成注入

如果抽象类(接口)有多个实现类,可以通过 @Qualifier 指定具体注入哪个实现类

service/: 业务逻辑层

各种业务接口及其实现类

PageHelper

PageHelper.startPage(...) 是让 下一条 SQL 自动带 LIMIT offset, size 的启动器,拦截 MyBatis 的 SQL 执行器并追加分页语句。

mapper/: 数据访问层

包含各种数据库操作接口和XML映射文件

都是抽象类,接口,

interceptor/: 拦截器

静态请求:

浏览器要的只是“现成的文件”,服务器不用做任何运算,直接把文件内容原样发回去即可,比如css、js、png文件,这些文件通常放在resources/static目录下

动态请求:

浏览器要的并不是“现成的文件”,而是需要服务器先运行一段java(controller方法)才能生成并返回结果。

  • 拦截器写在代码里只想拦“需要登录权限”的接口(动态请求)。

  • 如果静态资源(.js、.css、*.png)也被拦,浏览器就加载不到样式和图片,页面会“裸奔

config/: 配置类

注册自定义拦截器、静态资源映射等

handler/:异常处理类

注解适用范围说明常见用法示例备注
@RestControllerAdvice所有 @RestController全局异常 + 全局数据绑定 + 全局数据预处理,返回值直接写进 HTTP 响应体(相当于 @ControllerAdvice + @ResponseBody)。@RestControllerAdvice写 REST API 最常用。
@ControllerAdvice所有 @Controller与上面功能相同,但返回值默认走视图解析器(如 JSP、Thymeleaf)。@ControllerAdvice传统 MVC(页面渲染)场景用。
@ExceptionHandler单个类内部写在某个 Controller 内部的方法上,只对该 Controller 生效。@PostMapping("/login")
 
粒度最细,只适合局部异常。
@ResponseStatus单个异常类直接标在自定义异常类上,遇到该异常就返回指定的 HTTP 状态码及原因短语。@ResponseStatus(code = HttpStatus.CONFLICT, reason = "用户名已存在")简单场景,无需额外类。
@ResponseBody方法级与 @ControllerAdvice 或 @ExceptionHandler 搭配,让异常处理方法的返回值直接写进 HTTP 响应体。@ControllerAdvice


 
等同于 @RestControllerAdvice
@RestControllerAdvice(basePackages = "...")指定包范围只拦截指定包下的控制器,缩小粒度。@RestControllerAdvice(basePackages = "com.sky.admin")多模块项目常用。

aspect/: 切面类

  • @Aspect   :告诉Spring“这是个切面”
  • @Aspect + @Component 组合后,Spring 启动时会把它注册成 Bean,并织入到目标方法调用链里。

  • @Pointcut("execution(* com.sky.mapper.*.*(..)) && @annotation(com.sky.annotation.AutoFill)")  
    表示:拦截 com.sky.mapper 包下所有类的所有方法,再加一个条件:方法上必须带着 @AutoFill 注解。

annotation/: 自定义注解

1、@Target(METHOD) 约束它只能出现在方法级别;
@Retention(RUNTIME) 保证该注解会被编译进 .class 文件,并且在运行时通过反射可读。
因此,AutoFill 成为一个“可反射的元数据标记”。

2、使用时:@AutoFill(value= OperationType.UPDATE)        注解在方法上

3、@AutoFill 只是一个“标记”,真正让它产生自动填充行为的是切面(Aspect)——切面在运行期扫描到这个标记后,根据 value() 的值做对应的字段填充。

4、所以注解提供“声明”,切面完成“行为”;两者协作实现“声明式自动填充”。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值