Java后端核心知识速记笔记 —— Maven Spring IOC MVC MyBatis 一站式总结附代码示例mavenRequest和Response区别Spring依赖注入概念解释常见注解Spring Resource不同路径文件读方法Spring MVC概念解释常见注解Spring Session流程传统 HttpSession版Redis版拦截器配置拦截器Mybatis概念解释常见注解流程代码示例整体链路实战mavenmaven坐标:用于唯一标识一个Jar/项目方便从仓库下载依赖。groupIdorg.example/groupId//组织/公司/个人的ID使用反域名形式artifactIdjava_maven_test/artifactId//项目的IDversion1.1.2-SNAPSHOT/version//代码的版本一个pom.xml文件里只能有一个dependencies /dependencies ,可以有多个dependency/dependencymaven会强制所有java项目的结构一样src/main/java放源码src/main/resources:放配置文件src/test/java:放单元测试的代码pom.xml:定义项目坐标。依赖管理。构建与生命周期控制Request和Response区别在网络传输的角度Request请求表示客户端浏览器/App向服务器发送需求和数据例如访问地址、提交表单、携带参数等Response响应表示服务器处理完请求后返回结果例如页面内容、JSON 数据、状态码或 Cookie。在后端代码角度Request 用来读取用户传来的信息Response 用来向客户端输出处理结果本质上就是Request 负责输入Response 负责输出。物理层面Request 是前端发来的数据包Response 是后端发回去的数据包。逻辑层面Request 是你的输入参数Response 是你的返回结果。HTTP层面Request和Response是一来一回成对出现的。Spring依赖注入概念解释Bean:指的是放在Spring容器里的对象有生命周期作用域和依赖注入等特性(可通过接口引用实现多态)IOC控制反转一个思想把对象的创建交给Spring容器来控制而不是程序员自己依赖A类里需要B类的实例那么就说B是A类的依赖依赖注入由 Spring 容器统一调度将 A 类所依赖的 B 实例在 A 实例创建时自动交给 A 的过程。这样就不需要自己去new对象了常见注解Bean(方法级别注解)把注解方法执行后的返回值交给Spring容器Autowired(属性级别注解)注入依赖Component(类级别注解)将当前类标记为一个Spring Bean实现IOC。Spring 启动时由Component Scan机制扫描到带此标签的类并自动实例化new放入 Spring 容器。service告诉Spring这是一个业务类。Component语义化注解下面也是Controller:这是Controller层的类负责接收 HTTP 请求、处理用户输入并返回响应与前端交互RepositoryDAO层数据访问层。现在用MyBatis时Mapper基本可完全替代它Configuration将当前类标记为一个Spring Bean实现IOC。告诉Spring这是一个配置类PostConstruct(方法级别注解)标记在非静态、无参、返回值为 void的实例方法上由 Spring 容器在完成Autowired 依赖注入后自动触发运行一次可以放一些初始化的代码一般来说Bean用于第三方类/手动配置对象Component用于自己写的类Spring Resource不同路径文件读方法在电脑本地(绝对路径)路径比如d:/mywork/a.md直接通过File读写: File filenew File(“d:/mywork/a.md”);在工程目录下(含有 pom.xml 的位置mywork/lantian.png和第一种情况一样在src/main/resources的目录下的文件通过ResourceLoader去读文件(不能写文件),resources目录内容最终会被打包进classpath(这也是为什么会有前缀classpath)。要使用try-with-resources的写法把流的创建写在try后的括号里这样可以在执行完代码后关闭流下面这段代码可以读以上三种路径的文件URL路径文件注意不同文件路径的前缀可能不同位置读取方式前缀示例项目内resources/ResourceLoader / ClassPathclasspath:xxx.properties绝对路径file:file:D:/data/xxx.txt远程URLhttp:/https:https://...ServicepublicclassFileServiceImplimplementsFileService{AutowiredprivateResourceLoaderloader;OverridepublicStringgetContent(StringpathName){// 1. classpath:config.txt (resources下)// 2. file:C:/temp/test.txt (绝对路径工程目录下)// 3. https://example.com/api.json (远程资源)try(InputStreaminloader.getResource(pathName).getInputStream()){returnIOUtils.toString(in,utf-8);}catch(IOExceptione){returnnull;}}}Spring MVC概念解释Session:服务器端用来存储用户数据的机制Session默认有超时时间如30分钟浏览器关闭不一定失效。Session ID这是连接用户的唯一凭证通常通过 Cookie 返回给浏览器。Cookie(可长期存储):服务器发送并存储在浏览器上的一小段文本数据随后的每次 HTTP 请求都会将其自动携带并发送回服务器。(里面有session ID)Cookie存客户端小而轻Session存服务端安全但占资源。Cookie的属性属性维度属性名称示例值核心作用与描述基础数据NameSESSIONCookie 的名称不区分大小写但建议保持一致。Valueabc123xyz存储的数据内容通常是加密后的 SessionID 或 Token。生命周期ExpiresWed, 22 Oct 2026...绝对过期时间。到达该 GMT 时间点后浏览器会删除该 Cookie。Max-Age3600相对有效期秒。从浏览器收到开始计算。优先级高于Expires。-若不设置上述两项则为会话 Cookie浏览器关闭后立即消失。作用范围Domainexample.com指定哪些域名可以接收此 Cookie。不设则默认为当前域名不含子域名。Path/指定哪些路径下的请求可以带上此 Cookie。通常设为/表示全站通用。安全性HttpOnlytrue/false最重要。设为true后JS 脚本无法通过document.cookie读取防 XSS 攻击。Securetrue/false设为true后该 Cookie 只能通过HTTPS协议传输防明文监听。跨站策略SameSiteLax(默认)防 CSRF 攻击。控制第三方网站请求时是否携带该 CookieStrict/Lax/None。常见注解Controller(类级别注解)告诉Spring这是一个处理http请求的类。默认通过返回字符串来跳转到对应的 HTML 页面模板。RequestMapping(类/方法级别注解)括号里定义访问路径注解的代码块去处理request请求GetMapping方法专门用于处理Get请求PostMapping方法专门用于处理Post请求RequestParam(方法参数):用于提取URL里的参数(不是定义参数)如?id1ResponseBody类/方法告诉Spring把方法返回的结果(如果返回的是普通字符串它就直接返回原文本如果返回的是对象它会通过Jackson库转为JSON。传送给前端(浏览器)而不用去找HTML页面模板RequestBody:用于接收HTTP 请求体中的 JSON 数据Spring 会将 JSON 自动反序列化为Java 对象通常是 DTO并注入到方法参数中。RestController(类)ControllerResponseBodySpring Session流程传统 HttpSession版第一次请求浏览器发送请求没有 Cookie服务器收到后配置session后发送响应携带Set-Cookie: JSESSIONIDabc123这个是告诉浏览器去创建对应的cookie浏览器接收到后自动保存这个cookie第n次请求浏览器发送请求(携带Cookie: JSESSIONIDabc123)服务器接收到Cookie 里的 JSESSIONID后去对应的session对象如果 Session 未过期则继续使用其中的数据如登录状态。如果已过期则重新创建新的 Session并返回新的 Cookie。浏览器保存 SessionIDRedis保存 Session 数据。Redis版第一次请求在地址框输入URL后浏览器发送请求(请求里没有Cookie)。后端创建 Session并生成 SessionID将Session数据存入Redis。响应浏览器(set-Cookie :SESSIONabc123)。浏览器保存这个Cookie第n次请求在地址框输入URL后浏览器请求含有这个URL对应的Cookie(包含SessionID)。后端根据传来的SessionID去redis里找对应的数据如果 Session 未过期则恢复登录状态、用户信息等。如果已过期则创建新的 Session并返回新的 Cookie。浏览器保存 SessionIDRedis保存 Session 数据。拦截器Spring MVC 拦截器用于在 Controller 前后执行公共逻辑。核心接口HandlerInterceptor通过实现HandlerInterceptor接口可重写preHandle、postHandle、afterCompletion常用于登录校验、权限控制、日志记录等。执行顺序preHandle() - Controller - postHandle() - 页面渲染 - afterCompletion()publicclassLoginInterceptorimplementsHandlerInterceptor{// Controller方法执行之前这里是登录校验OverridepublicbooleanpreHandle(HttpServletRequestrequest,HttpServletResponseresponse,Objecthandler)throwsException{Objectuserrequest.getSession().getAttribute(user);if(usernull){response.sendRedirect(/login);returnfalse;}returntrue;}//Controller方法执行之后OverridepublicvoidpostHandle(HttpServletRequestrequest,HttpServletResponseresponse,Objecthandler,ModelAndViewmodelAndView)throwsException{}// 整个请求完成后包括渲染完毕OverridepublicvoidafterCompletion(HttpServletRequestrequest,HttpServletResponseresponse,Objecthandler,Exceptionex)throwsException{}}配置拦截器现在你有了拦截器但它们不会自动生效。你需要告诉Spring MVC去使用这些拦截器。这就是WebMvcConfigurer接口的作用。ConfigurationpublicclassWebConfigimplementsWebMvcConfigurer{Override//这里InterceptorRegistry是spring框架内部的工具类publicvoidaddInterceptors(InterceptorRegistryregistry){// 注册你的拦截器registry.addInterceptor(newLoginInterceptor())// 指定拦截哪些路径支持通配符.addPathPatterns(/**)// 指定排除哪些路径.excludePathPatterns(/static/**,/js/**,/css/**);// 你可以注册多个拦截器它们会按注册顺序执行registry.addInterceptor(newAuthInterceptor()).addPathPatterns(/api/**);}}总结拦截器解三个相关的类/接口HandlerInterceptor接口编写拦截逻辑的接口。需要实现其中的方法如preHandle()、postHandle()、afterCompletion()。WebMvcConfigurer接口Spring MVC 的扩展配置接口用于注册拦截器等配置。InterceptorRegistry类spring框架内部的工具类通过这个类实现对拦截器的管理(通过它来设置拦截器的拦截路径addPathPatterns和排除路径excludePathPatterns)Mybatis概念解释DAO层(Mapper层)负责与数据库交互执行增删改查操作。在 MyBatis 中通常体现为 Mapper 接口及其对应 SQL 映射。DO层用于映射数据库表结构的对象属性通常对应表字段主要用于数据持久化。**DTO层 ** 数据传输对象。主要用于 Service 层和 Controller 层之间的数据传递。比如注册时前端传来的字段很多但你只需要其中几个存入数据库。VO显示层对象。专门用于封装返回给前端页面展示的数据。Service层负责核心业务逻辑处理。Controller层负责接收前端请求、调用 Service 层处理业务并将结果返回给前端。XML 映射文件可以把 SQL 语句写在.xml文件中。ResultMap解决数据库字段名与 Java 属性名不一致的问题。动态SQL根据条件动态生成 SQL常用if、where、foreach。#{ }预编译参数占位安全。${ }字符串替换。有SQL注入风险(一般不使用了)。常见注解Mapper将 MyBatis 的 Mapper接口标记为 Spring 可识别并管理的Bean从而生成其代理对象用于执行数据库操作。流程Request: 前端发送请求。Controller: 接收请求将参数封装进DTO。Service: 执行业务逻辑比如查一下余额够不够再决定扣钱。Mapper (DAO): Service 调用 Mapper 接口。MyBatis 底层: 匹配 XML 里的 SQL将DO对象里的数据持久化到数据库。Response: 数据库返回结果 - 转换成VO- Controller 返回给前端。代码示例DO层:publicclassUserDO{privateLongid;privateStringuserName;privateStringuserEmail;// 故意与数据库字段名 user_email 不一致用于演示 resultMapprivateIntegerstatus;// Getter, Setter, NoArgsConstructor...}DAO层MapperpublicinterfaceUserMapper{// 演示 insertintinsertUser(UserDOuser);// 演示 select, if (动态条件查询)ListUserDOselectUsers(Param(name)Stringname,Param(status)Integerstatus);// 演示 foreach (批量查询)ListUserDOselectUsersByIds(Param(ids)ListLongids);}XML文件包含sql语句映射关系Mapper 接口的方法名必须与 XML 中的id一一对应。查询方向数据库 → Java对象resultMap标签:定义数据库查询结果字段与 DO 对象属性之间的映射关系用于将查询结果封装为Java 对象写入方向Java对象 → 数据库xml文件里#{example}是从对应的方法参数里获得值?xml version1.0 encodingUTF-8 ?!DOCTYPEmapperPUBLIC-//mybatis.org//DTD Mapper 3.0//ENhttp://mybatis.org/dtd/mybatis-3-mapper.dtd//mapper标签的namepath指向改xml对应DAO层(mapper层)mappernamespacecom.example.mapper.UserMapperresultMapidUserResultMaptypecom.example.entity.UserDOidpropertyidcolumnid/resultpropertyuserNamecolumnuser_name/resultpropertyuserEmailcolumnuser_email/resultpropertystatuscolumnstatus//resultMap//sql关键字的标签id和DAO对象的方法名一一对应 //resultMao属性的值决定采用哪个映射方式selectidselectUsersresultMapUserResultMapSELECT id, user_name, user_email, status FROM sys_userwhereiftestname ! null and name ! AND user_name LIKE CONCAT(%, #{name}, %)/ififteststatus ! nullAND status #{status}/if/where/selectselectidselectUsersByIdsresultMapUserResultMapSELECT * FROM sys_user WHERE id INforeachcollectionidsitemidopen(separator,close)#{id}/foreach/selectinsertidinsertUseruseGeneratedKeystruekeyPropertyidINSERT INTO sys_user (user_name, user_email, status) VALUES (#{userName}, #{userEmail}, #{status})/insert/mapperResult:importlombok.Data;/** * 统一后端返回结果封装类 * param T 响应数据的泛型类型 */Data// 使用 Lombok 自动生成 Getter/SetterpublicclassResultT{privateIntegercode;// 状态码例如 200-成功, 500-系统异常, 401-未授权privateStringmsg;// 提示信息描述本次请求的状态privateTdata;// 具体业务数据可以是对象、列表、或 null// 私有化构造器强制通过静态方法创建对象符合工厂模式设计思想privateResult(){}/** * 成功响应 - 带数据 */publicstaticTResultTsuccess(Tdata){ResultTresultnewResult();result.code200;result.msgsuccess;result.datadata;returnresult;}/** * 成功响应 - 不带数据 */publicstaticTResultTsuccess(){returnsuccess(null);}/** * 失败响应 - 自定义错误信息 */publicstaticTResultTerror(Stringmsg){ResultTresultnewResult();result.code500;result.msgmsg;returnresult;}/** * 失败响应 - 自定义状态码和错误信息 */publicstaticTResultTerror(Integercode,Stringmsg){ResultTresultnewResult();result.codecode;result.msgmsg;returnresult;}}DTO// 接收前端查询条件的传输对象publicclassUserQueryDTO{privateStringname;privateIntegerstatus;privateListLongids;// Getters/Setters...}Service实现类ServicepublicclassUserServiceImplimplementsUserService{AutowiredprivateUserMapperuserMapper;OverrideTransactional// 保证操作的原子性publicLongregisterUser(UserDOuser){userMapper.insertUser(user);returnuser.getId();// 返回插入后的主键}OverridepublicListUserDOfindUsers(UserQueryDTOquery){// 如果传入了具体 ID 列表优先走批量查询否则走动态搜索if(query.getIds()!null!query.getIds().isEmpty()){returnuserMapper.selectUsersByIds(query.getIds());}returnuserMapper.selectUsers(query);}}Controller层:RestControllerRequestMapping(/api/users)publicclassUserController{AutowiredprivateUserServiceuserService;PostMapping(/search)publicResultListUserDOsearch(RequestBodyUserQueryDTOquery){ListUserDOlistuserService.findUsers(query);returnResult.success(list);}PostMapping(/save)publicResultLongsave(RequestBodyUserDOuser){LongiduserService.registerUser(user);returnResult.success(id);}}整体链路标准调用流程前端 → Controller → DTO → Service业务处理 → Mapper接口 → XML/SQL → 数据库↓DO / VO实战