外卖项目总结(2)
技术点
-
过滤器Filter - servlet 容器
背景:未登录的访客可以随意进入管理端界面
引入过滤器:实现员工身份验证,另外过滤器还可以实现缓存控制(在过滤器中直接对响应头相应的数据进行赋值来实现)
使用:- 定义实现类实现Filter接口,并重写方法(init初始化方法、doFilter拦截到请求时调用、destroy销毁方法)------生命周期
- 配置过滤器:@WebFliter(urlPatterns = "")注解,配置拦截器路径
- 启动类中通过@ServletComponentScan开启过滤器扫描
- 放行:filterChain.doFilter(servletRequest,servleResponse)
- FilterChain:在web应用中异常编写多个过滤器,过滤器按顺序执行
-
拦截器Interceptor - IOC容器
由Spring框架提供,动态拦截请求,本质是面向切面编程(AOP)的
应用场景:登录验证,权限验证,日志记录,性能监控......
使用:- 自定义类实现接口HandlerInterceptor,重写preHandle方法,交给IOC容器管理。
- 自定义拦截器注册类(配置类)
注意:先经过Filter过滤器,在进入拦截器Interceptor;Filter是由Java提供的,范围更广,Interceptor则是Spring 框架提供的,只能作用与框架内。
- 异常处理 - 全局异常处理器
3.1 @RestControllerAdvice 被用来定义全局异常处理程序和全局响应结果处理程序。
3.2 @ExceptionHandler 用来捕获自定义异常
3.3 自定义异常定义在common类继承自RuntimeException
4. AOP切面:
背景:
- 在对开发的功能模块进行日志记录时,每个模块都有大量重复的日志记录代码,导致代码臃肿,业务外逻辑与业务逻辑混合,不利于功能解耦。
- 公共字段自动填充:对数据库中的updatetime,createtime等公共字段的更新代码,重复且逻辑相同。
引入AOP切面:将横切关注点与业务逻辑分离,将其通用行为封装至横向模块,以达到对业务逻辑的增强。
应用场景:记录日志操作、权限管理、事务管理、公共字段填充
使用: - 引入依赖
- 编写自定义注解类:标识使用的方法
- 定义切面类,确定通知的类型(@Before/@After/@Around)
- 在需要使用的方法/类上增加注解进行使用
例如:公共字段自动填充 - 自定义注解AutoFill:用这个注解标识需要自动填充的方法。
@Target(作用目标:类或者方法或者属性,常用枚举)
@Retention(注解生效时间:runtime)
属性:OperationType value();//数据库操作类型:UPDATE INSERT
注意:注解属性 = 抽象方法(定义时) = 配置项(使用时)这是Java规范。@Target、@Retention是元注解(即修饰注解的注解) - 自定义切面类AutoFillAspect:统一拦截加入注解的方法,通过反射为公共字段赋值。
@Aspect:标识为切面
@Component:交给IOC
@Pointcut:标识切入点
@Before:前置通知(切入点)
Java
@Pointcut("execution(* com.sky.mapper.*.*(..)) && @annotation(com.sky.annotation.AutoFill)")//指定扫描的包和类
public void autoFillPointCut(){}
Java
@Before("autoFillPointCut()")
public void autoFill(JoinPoint joinPoint){}
参数:连接点 JointPoint
注意:Mapper中定义方法约定实体对象参数放第一个,为了后续通过反射获取
总结AOP的使用:
- 自定义注解:标识拦截那些方法或类。2个注解(Target、Retention),一个属性(枚举数据库操作类型)
- 自定义切面类:拦截+统一操作的逻辑
- 对应方法或类上加上注解
关于AOP的一些思考:
- 为什么不抽取为接口或静态类?
本质区别:
方式 | 本质 | 实现 | 特点 |
---|---|---|---|
接口/静态工具类 | 代码调用 | 需要在业务代码中手动调用方法 | 侵入式,增加代码耦合 |
AOP | 代理织入 | 运行时由框架(如Spring)自动在指定连接点执行 | 非侵入式,解耦,统一维护 |
日志、公共字段更新等这些操作是具体的实现,而接口是抽象的。
AOP完全分离业务与通用逻辑,业务板块甚至调用代码都没有。
AOP扩展性更强。
- AOP是java不支持多继承的扩展
传统的做法,将通用逻辑封装到一个父类,然后让所有业务类继承它,但这样强耦合,职责混乱,既有业务逻辑又有通用逻辑,有了自己的继承结构就无法继承工具类了。
AOP = 动态实现多继承的功能扩展方案
在 Java 单继承限制下,通过切面在运行时为类添加"多个父类功能",
例如:日志、权限、事务、缓存、字段填充等。