# SpringprotogenesisStudy **Repository Path**: south-it-school-project/spring-stud ## Basic Information - **Project Name**: SpringprotogenesisStudy - **Description**: 原生编写spring原生编写spring原生编写spring原生编写spring原生编写spring原生编写spring原生编写spring - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 0 - **Created**: 2025-04-27 - **Last Updated**: 2025-10-10 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # Spring学习 ## Spring 简介 最主要是简化官方组件:EJB(因为配置bean很复杂) Spring 是一个非常大的工厂,基于非常大的容器工厂,可以管理任何一个bean的对象 #### Web 环境专属作用域 | 作用域类型 | 描述 | 生命周期 | | ---------- | ----------------------------- | -------------------------------------- | | request | 每次 HTTP 请求创建一个新 Bean | 从请求开始到响应结束 | | session | 同一 HTTP 会话共享一个 Bean | 从会话创建到会话失效(超时或主动销毁) | ## SpringBoot3简介 Spring Boot帮助你创建独立的、生产级的基于Spring的应用程序。大多数Spring Boot应用程序只需要很少的Spring配置。 极大地降低了企业级开发的复杂度 主要目标有: 为所有Spring开发者提供一种快速的入门体验 做到开箱即用 提供大量非功能性特性相关项目(例如:内嵌服务器、安全、指标、健康检查、外部配置) 无代码生成、无需编写XML 系统环境要求 Spring Boot 3.0.0 需要 Java 17. 还需要Spring Framework 6.0.0-M2 及以上版本。 开发工具IntelliJ IDEA 2021.2.1以及更高版本。 ## 支持以下构建根据的版本: 构建工具 版本 Maven 3.5+ Gradle 7.x (7.4 or later) Spring Boot支持以下嵌入式servlet容器: ## 容器名称 Servlet版本 Tomcat 10.0 5.0 Jetty 11.0 5.1 Undertow 2.2 (Jakarta EE 9 variant) 5.1 Spring Boot应用程序部署到任何兼容servlet 5.0+的容器中。 容器工厂 BeanFactory ## 安装 Spring Boot 3可以与经典的Java开发工具一起使用,也可以作为命令行工具安装。无论那种方式都需要Java 17及以上版本。 maven Spring Boot3与Apache Maven 3.5或更高版本兼容。如果还没有安装Maven,可以按照maven.apache.org上的说明进行操作。 大多数操作系统,Maven可以使用包管理器安装,如果你用的OSX Homebrew,可以使用brew install maven。Ubuntu用户可以使用sudo apt-get install maven。使用Chocolatey的Windows用户使用choco install maven。 Spring Boot依赖使用org.springframework.boot groupId。通常,你的Maven POM文件继承自spring-boot-starter-parent项目,并声明对一个或多个“Starter”的依赖。 Spring Boot还提供了一个可选的Spring Boot Maven Plugin来创建可执行的jar文件。 开发第一个Spring Boot程序 此章节快速搭建一个Spring Boot 3应用程序,使用的开发工具IDEA+Maven。 Spring Boot官方提供了非常便捷的工具Spring Initializr帮助开发者快速的搭建Spring Boot应用程序,IDEA也集成了此工具。 Spring Data 数据获取 Spring AMQP 消息传递 Spring Security 验证授权 Spring Cloud 服务治理 ## 1.创建项目或者模块,选择Spring Initializr,Java版本为17 ![img](https://spring-boot-3.oss-cn-beijing.aliyuncs.com/1.jpg) ## 2.选择Spring Boot版本3.0.0,以及Spring Web依赖 ## ![2](https://spring-boot-3.oss-cn-beijing.aliyuncs.com/2.jpg)3.目录结构 ![img](https://spring-boot-3.oss-cn-beijing.aliyuncs.com/3.jpg) ## 4.pom.xml文件解析 ```java 4.0.0 org.springframework.boot spring-boot-starter-parent 3.0.0-M2 me.renpeng first-springboot3-maven 0.0.1-SNAPSHOT first-springboot3-maven first-springboot3-maven 17 org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-test test org.springframework.boot spring-boot-maven-plugin spring-milestones Spring Milestones https://repo.spring.io/milestone false spring-milestones Spring Milestones https://repo.spring.io/milestone false ``` ## 5.application.properties ```java server : //应用启动端口 port:8082 servlet: //如果你的上下文路径是/,这意味着应用程序部署在服务器URL命名空间的根目录,不需要额外的路径段来访问它。 context-path:/ ``` ## 6.接口开发 新建FirstController类 ```java @RestController public class FirstController { @RequestMapping("/hello") String hello() { return "First Spring Boot 3 Application!"; } } ``` ## 7.启动程序 ![img](https://img-blog.csdnimg.cn/img_convert/52a12c8347c8307cea93e1ba0c472eb1.png) ## 8.访问接口 浏览器或者PostMan访问接口http://localhost:8080/hello,结果: ```java ➜ ~ curl 'http://localhost:8080/hello' First Spring Boot 3 Application! ``` ![de505e186b082d0c221aef7f9ea4150](E:\电脑内容\网站相关\笔记\Java\图片\de505e186b082d0c221aef7f9ea4150.png) 跑项目的时候推荐使用Lombok Sping Web(使用这个去跑) ## Sping两大重要特性 容器 负责创建跟管理类的相关的东西,再植入了IOC容器的内容 ### 动态代理 动态代理是一种在运行时动态生成代理类并实例化对象的机制。它的核心思想是: 1. **代理类不会在编译期存在**,而是在运行期根据指定的接口动态生成字节码并加载到 JVM。 2. 所有对代理对象的方法调用,最终都会被分派到一个统一的 **InvocationHandler**(调用处理器)中,由它来决定如何处理、转发或增强方法。 这样,你无需手写大量 boilerplate 代码,就能在运行时拦截、增强调用逻辑。 ### 静态代理 静态代理是一种在编译时生成代理类,不同的接口必须要编写一个代理类 1. **为目标接口手动编写一个代理类**,该代理类实现同一接口,并持有一个对真实对象(RealSubject)的引用。 2. 客户端通过代理类调用接口方法,代理类在调用真实对象方法之前或之后添加增强逻辑。 ### IoC设计思想(IoC控制反转) 如果有IoC的项目里复杂的对象管理工作就摆脱 在传统开发中,我们需要直接在对象内部通过new方式创建别的对象 这就相当于建立了对象间的依赖 如果有IoC的项目里面,你只需要将你设计好的对象交给第三方的IoC的容器进行管控就可以了,而不是在你对象内部,直接创建的方式来完成 IoC的出现能非常方便地帮我们,根据配置文件,来方便地创建、以及组装对象之间的依赖关系,这就是XML配bean #### 扩展: ##### **核心思想**: 控制反转意味着将对象的创建和依赖关系交由 Spring 容器管理,而不是由程序代码直接控制。这种机制使得程序更加灵活和解耦,提升了代码的可维护性和扩展性。 ##### **依赖注入**: 通过构造器注入、setter 注入或接口注入,将对象所需的依赖传递给它,而不是让对象自行创建依赖。 ##### 我们要理解到底控制的是什么? 其实就是控制对象的创建,IOC 容器根据配置文件来创建对象,在对象的生命周期内,在不同时期根据不同配置进行对象的创建和改造。 ##### 那什么被反转了? 其实就是关于创建对象且注入依赖对象的这个动作,本来这个动作是由我们程序员在代码里面指定的,例如对象 A 依赖对象 B,在创建对象 A 代码里,我们需要写好如何创建对象 B,这样才能构造出一个完整的 A。 而反转之后,这个动作就由 IOC 容器触发,IOC 容器在创建对象 A 的时候,发现依赖对象 B ,根据配置文件,它会创建 B,并将对象 B 注入 A 中。 这里要注意,注入的不一定非得是一个对象,也可以注入配置文件里面的一个值给对象 A 等等。 ### AOP面向切面编程 AOP是这个针对面向对象编程的一种补充,切面编程的目的就是为了将业务目的进行而外的增强或扩展,Spring中的AOP是基于JDK动态代理技术和CGLJB动态代理实现的。 因为你可以在不改变原代码,功能流程的基础上,加入新功能 他用的原理就是:动态代理技术 这个跟设计模式中的"代理模式"的思想是一样的这也就是面试常问的 #### AOP术语 ##### 切面(Aspest) 切面(本质上也是一个类)是用于编写增强逻辑的一个类(处理器、拦截器) ##### 通知/增强(Advice): 增强(本质上也是方法)就是对目标行为(方法)植入额外的逻辑代码,从而增强原有的功能 **前置通知(Before Advice)**:目标方法执行之前 **后置通知(After Advice)**:目标方法执行之后(无论方法正常返回还是抛异常都会执行) **环绕通知(Around Advice)**:最强大也最灵活的通知,包裹目标方法前后 **异常通知(AfterThrowing Advice)**:目标方法抛出异常时做出的事情 **最终通知(Finally Advice)**:在目标方法执行结束后**总会执行**,无论方法是正常返回还是抛出异常 ##### 切入点(Pointcut) 切入点类似一个切入的坐标,目的就是要找到目标对象的哪些方法进行切入或增强,切入点可以使用表达式进行描述 ##### 连接点(Joinpoint) 目标对象的方法(被切入的方法)就称之为连接点,一个切入点可以对应目标对象的多个连接点 ##### 代理(Proxy) 代理对象是 AOP 框架在目标对象外层生成的“壳”,客户端拿到的其实是代理。它负责拦截对目标方法的调用,将调用路由到切面里的通知链上。 ##### 目标(Target) 目标对象指被增强的那个业务对象,即实际执行业务逻辑的实例。通知最终都是作用在它的连接点(方法)上。 ##### 织入(Weaver): 将切面中的增强逻辑应用到目标具体的连接点上并产生代理的过程称之为织入。 通俗理解来讲:**织入**就是把“你想要加的那些额外功能”自动地、透明地“缝”进原本的方法里,让原本的**业务代码不动** 可分为: **编译时织入**:需要特殊的类加载器(LTW) **类加载时织入**:需要特殊的编译器(CTW) **运行时织入**:通常使用JDK或看CGLJB在程序运行创建代理对象 Spring就是基于运行时织入(注意:Spring仅仅只是用到了Aspect的切入点表达式和注释,但并没有使用Aspect类加载跟编译时织入功能,而是使用JDK和CGLIB在运行时生成代理对象。) ## 使用Spring项目的缺点 项目越做越复杂、庞大,就需要引入很多的配置文件 太多的配置非常繁杂,有时候呢,也难以理解,容易配置出错 很多人刚开始学Sping,光XML配Bean这一步会困扰很多人 ## Spring Boot的出现 他的出现并不是为了取代Spring而是为了让开发者更方便、简化地使用Spring。 Spring Boot的出现那就是直接将原先 Spring里复杂的 XmlBean的配置给砍掉了! 核心思想:约定大于配置 CoC: Convention over Configuration 开发人员仅需规定应用中不符合约定的那部分定制化一下就OK了 不过一般大部分约定俗成的东西Spring Boot已经帮你配置好了 Sping Boot无论去集成什么内容,都变得非常容易 例如像集成:数据库、缓存、权限、web容器、监控、消息队列 ### 在没有使用Spring Boot之前用Spring开发一个Web项目 最起码要做以下几件事或者说要以下几个步骤 1.配置Maven依赖 2.配置web.xml 加载Spring或Spring MVC 3.配置数据库连接、配置Spring事务 4.配置加载配置文件的读取,开始注解 5.配置日志文件 .... 配置完这些之后还要配置Tomcat进行调试 ### 如果使用了Spring Boot开发一个web项目就会变的非常的便捷 你只需要建立一个Spring Boot的工程配置好Maven依赖基本上就可以启动了,因为SpringBoot帮你自动配置好了,以前XML里面的那些复杂的配置SpringBoot全部帮你规避了 #### 在开发方面 各种各样的Starter开箱即用 在Starter的出现也从本质上颠覆了传统的JavaEE项目的代码复用方法 像以前的JavaEE项目,就是拷贝源代码过来复用,要么打个包jar给别人 但是有了Spring Boot Starter之后你只需要添加Maven依赖其他任何一个东西其他自动配置Starter自己就可以完成了 #### 配置方面 配置方面机器简化原先复杂的XML 配 Bean 直接给槟弃掉了 所有的Bean全部都是自动配置、自动注入 ### 部署方面 因为Spring Boot本身就内嵌了Tomcat容器,不需要再去配外置的Tomcat ### 而这个简化的内容是 #### 1.大板斧 这就是直接将原先Spring里复杂的XML Bean的配置给砍掉了 ### Spring Boot的根本核心思想 约定大于配置 已经内置服务器不需要使用Tomcat那些内容了 ## ssh解释 ![ssh](E:\电脑内容\网站相关\笔记\Java\图片\ssh.png) 通俗的来讲就是完成MVC模型中的C部分的功能,用于接收请求,并且来处理,简单理解就是现如今,学Spring MVC或者Spring Boot里面的Controller的功能,这就是Struts 然后第二个S就是所谓的Spring,SSH里用Spring,它只是想用Spring的最核心的所谓的IoC容器,利用它可以很方便的管理我们代码中各种各样的对象,因为IoC的出现就是为了减少对象耦合,简约对象的管理 然后SSH里面的H就是Hibernate Struts落寞的原因 它很多做法和写法耦合性很强,性能不是很好,它对内存耗损什么的很大,曾经爆出有很多高危的漏洞安全有风险 Spring 推出的Spring MVC成功之后基于Spring MVC集成了各种:自动装箱、开箱即用、自动配置等等一系列自动化机制才变成了现在的Spring Boot Hibernate 数据库的操作映射框架 或者叫ORM层框架,现在的替代品还是太多了,竞争力也很大(MyBaits、JPA)ORM框架各有各的,特点跟长处 ## SSM解释 ![image-20240711144542856](C:\Users\admin\AppData\Roaming\Typora\typora-user-images\image-20240711144542856.png) 我们把SSH里面的Struts ->Spring MVC把里面的“H”->MyBatis 这就是SSM框架 即使现在已经比较好用 也很主流也推荐学 但是SSM里面的一些比如什么 XML配Bean等这种配置 **还有一些比如Tomcat的配置劝退了很多初学者所以Spring Boot这个JavaEE框架横空出现了,所以SpringBoot当下更加推荐去学** ## 前后端分离的开发模式 ### 耦合方式 因为现在前端很多内容复杂了之后像JSP这种套模板的技术,它没有办法高效的去开发,因为需求复杂了之后原生的那些html、js、css这种的开发方式,包括Jquery等等这些技术点,在做复杂页面的时候就会变得非常的繁杂,因为本质原因还是因为前端那个时候没有工程化、模块化和可复用化的思维来做,因为那会没有像Spring这样工程化的开发框架,所以就会出现开发必然就会出现各种各样的不协调,还有一些效率低和扯皮的问题,所以从公司项目管理的角度来看,这种开发模式就会非常影响开发效率 ### 非耦方式(前端后端分离) 据上面所言,所以我们前端跟后端的事情分开来做,我们要把前端开发的责任从后端开发工程师身上拿掉,我们要给前端开发工程师一个单独的岗位和责任领域,我们不能让他们总是使用野生的开发模式,不能一天到晚去copy什么html代码段、js代码段以及css样式,人肉去试错、去调试等等,前端也需要工程化、项目化的思维来做,所以这才是前后端分离开发模式最开始的来源 前端后端分离它本身并不是一个技术问题,而是一个工程化考量和项目管理的问题,自此之后,前端开始独立出来了,那技术上的问题又怎么去解决呢?学过前端开发的话都会说:前端开发这玩儿怎么那么繁琐?怎么这么玄学?学习的时候都是东拼西凑,面向复制粘贴 copy html 代码 copy js代码 copy css样式 东拼西凑,反正就是靠往上堆积,来试图完成你要的页面和效果,你就会感觉这玩意它开发起来就是没有Java开发,那么有逻辑,那么好管理,包括代码复用性也是,前端开发可能都是在收集代码片段,都是东拼西凑 复制粘贴 来完成代码复用 但是后端开发它不一样,有各种各样的工具类、jar包、Maven依赖, 很明显后端开发有一种工程化的思维,可以满足长期演进和迭代的目标 但是前端那时候并没有这种工程化的思维,所以后面才会有vue.js React.js这些前端框架的出现它们是从本质上颠覆了前端开发的游戏规则,前端开发组件化框架,但是我们更愿意叫它:前端开发工程化框架,因为自此开始 大家都遵循一套体系来进行约束性的开发,前端开发也越来越工程化、组件化,越来越有章可循,而且前端代码也更好复用了 自从Node出现,前端开发也可以借助Node来开发各种各样的工具,进行辅助开发,比如各种各样的包管理器、编译工具等等,这也是前端开发迈入工程化、迭代化、可复用的一个很重要的方面 #### 前后端分离到底要怎么样去实施呢? 一般软件开发来讲简化的话一般有四大步骤 1.设计 2.开发 3.测试 4.部署 所以真正的前后端分离应该参透到以上的每一个步骤中去,这才能算得上真正的前后端分离 ##### 首先是第一个阶段设计阶段 设计的第1个层面当然是系统设计 后端系统设计比较好理解,包括后端架构:系统架构设计、数据库、中间件、缓存,主要是考虑性能、容量、扩展性、可维护性方面,前端也应该如此,一定要满足一个长期可演进性、可迭代性的内容,在设计阶段也得考虑 ##### 第一阶段的第二阶段就是接口设计 前后端分离之后,前后端系统通过接口进行交互这个是肯定的,这时候模型(Model)层,接口的约定极其重要,包括接口的请求方式,数据类型,还有一些数据的格式等等,不然,前后端开发工程师永远在为了某个破接口扯来扯去 ##### 第二阶段开发阶段 前端跟后端各自按照先约定的接口独立去开发,互相不需要扯皮,前后端无发人员为了某个接口的事情出现扯皮,我觉得开发其实称不上严格独立的这种前后端开发,总有一方要被迫去改东西、去妥协的内容,这其实还不是要耦合,前端现在在诸如Vue、React等这些当下非常火热的组件化框架的帮助下,他确实可以独立的去驱动页面、独立的开发, 数据方面也可以(从mock服务器去拿数据)虚拟化、模拟化完全不需要依赖于实时的后端接口,而后端也只需要把你的接口写好、提供好,按照之前评审好的接口约定来提供数据就可以了,而且后端一套接口可以提供很多类型的前端使用比如:web网页、手机app、微信小程序等等 ##### 第三阶段测试阶段 基本保证:前后端独立可测试,前端就是页面、跳转、展示、输入、传参等等,后端主要保证数据接口的提供、数据格式、校验、异常情况、权限问题等等 ##### 第四个阶段部署上线阶段 前后端分离之后,前后端项目可独立、可部署 最后一个问题就是:前后端分离确实是很适合复杂的项目,看起来看很好,缺点就是有些公司就是为了做前后端分离才做的前后端分离,从上面的讲述之中,前后端分离是需要成本的,特别是你想做一个彻彻底底的前后端分离项目,不管你是人力成本还是开发成本还是工具成本还有部署成本,都是不小的,如果是小项目强行前后端分离就会很麻烦,有些内容他做的不彻底,它就会带来非常多的负担,而不是便利性了,所以说并不是所有项目都适合前后端分离,这个要看性价比跟实际的需求去做的 前后端分不分离并不是一个技术性问题而是一个工程考量的问题 # 接口与包 ## Spring 框架 ApplicationContext 核心笔记 ### 一、ApplicationContext 初始化方式 1. **基于 XML 的初始化** ```java ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml"); ``` **作用**:加载类路径下的 **beans.xml** 配置文件,初始化 Spring 容器。 **特点**:XML 配置是经典方式,适合管理复杂的 Bean 依赖关系。 ### 二、Bean 的获取方式 1. **通过 Bean 名称 + 类型获取** ```java UserService userService = context.getBean("userService", UserService.class); ``` **适用场景**:当接口有多个实现类时,需明确指定 Bean 名称。 **注意**:Bean 名称需与 XML 中配置的 **id** 或 **name** 属性一致。 2. **直接通过类型获取** ```java UserService userService = context.getBean(UserService.class); ``` **前提条件**:该接口在容器中**只有一个实现类**,否则会抛出 **NoUniqueBeanDefinitionException**。 ### 三、Bean 的作用域(单例 vs 原型) 1. **单例模式(Singleton)** ```java UserService s1 = context.getBean(UserService.class); UserService s2 = context.getBean(UserService.class); System.out.println(s1 == s2); // 输出 true ``` **特点**:Spring 默认作用域,容器中仅存在一个实例,所有请求返回同一对象。 **XML 配置**: ```xml ``` 2. **原型模式(Prototype)** ```java // 若 XML 中配置 scope="prototype" UserService s1 = context.getBean(UserService.class); UserService s2 = context.getBean(UserService.class); System.out.println(s1 == s2); // 输出 false ``` **特点**:每次请求创建新实例,适合有状态的 Bean。 **XML 配置**: ```xml ``` ### 1. `@Autowired` (Spring 原生注解) - **作用**: 按类型自动装配依赖 - **使用位置**: 构造器、Setter 方法、字段 - **重要特性**: - `required` 属性(默认 `true`,依赖不存在时抛出异常) - 与 `@Qualifier` 联用实现按名称装配 - **代码示例**: ```java @Service public class OrderService { // 字段注入(不推荐生产环境) @Autowired private PaymentService paymentService; // 构造器注入(推荐) @Autowired public OrderService(PaymentService paymentService) { this.paymentService = paymentService; } // Setter 注入 @Autowired public void setLogger(Logger logger) { // ... } } ``` ### `@Qualifier` (解决歧义性) - **作用**: 当存在多个同类型 Bean 时指定具体实现 - **典型场景**: 同一接口多个实现类 - **示例**: ```java @Component @Qualifier("smsService") public class SmsNotification implements NotificationService {} @Component @Qualifier("emailService") public class EmailNotification implements NotificationService {} @Service public class UserService { @Autowired @Qualifier("smsService") // 明确指定实现 private NotificationService notificationService; } ``` ### `@Primary` (设置默认实现) - **作用**: 当存在多个同类型 Bean 时标记优先选择项 - **示例**: ```java @Configuration public class AppConfig { @Bean @Primary // 默认选择此实现 public DataSource mysqlDataSource() { return new MysqlDataSource(); } @Bean public DataSource oracleDataSource() { return new OracleDataSource(); } } ``` ### 4. `@Resource` (JSR-250 标准) - **特点**: - 默认按名称匹配 (`name` 属性) - 不支持构造器注入 - 无 `required` 属性 - **示例**: ```java public class InventoryService { @Resource(name = "redisCache") // 按名称匹配 private CacheService cacheService; } ``` ### 5. `@Inject` (JSR-330 标准) - **特点**: - 需要 `javax.inject` 依赖 - 功能类似 `@Autowired`,但无 `required` 属性 - **示例**: ```java import javax.inject.Inject; public class ShippingService { @Inject private LogisticsService logisticsService; } ``` ## Spring+配置类(SpringBoot) ## 代码: ```java import org.springframework.web 这个是Spring MVC的jar包 import org.springframework.boot 这个是Spring Boot的jar包 import org.springframework.beans这个是Spring的jar包 import jakarta 这个是javax的jar包 ``` ### 配置文件后缀 .properties (按照的是xxx.xxx.xxx = “内容”) .yml (按照的是的对象的方式去弄的更加清晰明了) ``` yml配置文件: server: port: 8080 (配置端口信息) spring: web: resources: static-locations: - classpath:/template/(配置静态资源并且能映射出去) ``` ### 代码注解: ```java package org.examplea.demo1; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class Demo1Application { public static void main(String[] args) { SpringApplication.run(Demo1Application.class, args); } } ``` #### @SpringBootApplication 注解通常被用于Spring Boot应用程序的入口类上,用于启动Spring Boot应用程序 ```java package org.examplea.demo1.controller; import jakarta.annotation.Resource; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; @RestController @RequestMapping("/test") public class TestController { @PostMapping("/wzy") @GetMapping("/wzy") public String test(){ return "我王部长也会SpringBoot了"; } } ``` ```java package org.examplea.demo1.controller; import jakarta.annotation.Resource; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; @Controller @RequestMapping("/test") public class TestController { @PostMapping("/wzy") @ResponseBody public String test(){ return "我王部长也会SpringBoot了"; } } ``` @RestController与@Controller类似,但是@RestController会自动将返回值转换为JSON格式,@Controller不会需要自己手动自己设置。 @ResponseBody设置这个方法返回的值变成JSON @RequestMapping它用于映射HTTP请求和控制器方法之间的关系 @GetMapping("/hello"): 这个注解表示该方法处理的是 HTTP GET 请求,并且请求的 URL 路径为/hello,并且返回一个字符串:我王部长也会SpringBoot了 @POSTMapping("/hello"): 这个注解表示该方法处理的是 HTTP POST 请求,并且请求的 URL 路径为/hello,并且返回一个字符串:我王部长也会SpringBoot了 ```java package org.examplea.demo1.controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; @Controller public class IndexController { @RequestMapping("/index") public String index() { return "index.html"; } } ``` 默认不加@ResponseBody他这个还可以返回静态资源 ``` @Autowired private SomeService someService; ``` 用于自动装配Spring容器中的Bean。 ``` @Resource private SomeService someService; @Resource(name = "specificService") private SomeService someService; @Resource(type = SomeService.class) private SomeService someService; ``` 默认情况下,@Resource会根据字段名或者属性名来查找对应的Bean,并进行注入 可以通过 `name` 属性显式指定要注入的 Bean 的名称。 除了按照名称注入外,`@Resource` 也支持按照类型进行注入,通过 `type` 属性指定要注入的 Bean 的类型。 ```Java @Component public class EmailProperties { //发件人邹箱 public String user = "3110898894@qq.com"; //发件人邮箱授权码l public String code = "gjtgjbthajimdghe"; //发件人邮箱对应的服务器域名,如果是163邮箱:smtp.163.com · qq邮箱:smtp.qq.com public String host = "smtp.qq.com"; //身份验证开关 private boolean auth = true; ... } ``` 作用:用于标识一个类是Spring容器中的组件。@Component是Spring框架中的一个通用注解,用于标注一个类作为Spring Bean。 `@Component` 注解在 Spring 中表示一个类是 Spring 管理的组件。以下是它的作用: 1. **创建 Bean**:当你使用 `@Component` 注解一个类时,Spring 会在组件扫描期间自动检测到它,并创建该类的实例,将其作为 Spring Bean 管理。 2. **依赖注入**:通过标记一个类为 `@Component`,你可以允许其他 Bean 通过依赖注入来使用它。例如,如果另一个类需要 `EmailProperties`,Spring 会在创建那个类时提供 `EmailProperties` 实例。 3. **生命周期管理**:Spring 管理带有 `@Component` 的 Bean 的生命周期,包括初始化、销毁和任何必要的依赖解析。 4. **配置属性**:当与 `@ConfigurationProperties` 一起使用时,`@Component` 允许 Spring 将在 `application.properties` 或 `application.yml` 中定义的属性绑定到 `EmailProperties` 类的字段。 `@Value` 注解是 Spring 框架中用于从配置文件(如 `application.properties` 或 `application.yml`)中获取属性值并将其注入到 Spring 管理的 Bean 对象中的工具。它是依赖注入的一种形式,用于简化配置数据的管理。 **注入字符串类型的配置**:从配置文件中获取字符串类型的属性值并注入。 **注入基本数据类型**:将配置文件中的数值类型或布尔值类型注入到字段中。 **处理占位符和默认值**:当配置文件中的某个值不存在时,可以为其设置默认值。 `@ConfigurationProperties(prefix = "email")` 是 Spring 框架中用于绑定配置文件中的一组属性到 Java Bean 对象的注解。相比 `@Value`,它可以更灵活地处理多个相关属性,并且可以直接将它们映射到一个 POJO(Plain Old Java Object)类的字段中。 **创建配置类**:编写一个 Java 类,用于存储配置文件中的属性。 **配置文件定义**:在配置文件中定义对应的属性集合。 **使用 `@ConfigurationProperties` 进行属性注入**。 @SpringBootApplication 里面一般包括 @EnableAutoConfiguration @ComponentScan(这个就是扫Bean并且注入Bean的一个注解) Bean注册 | 注解 | 说明 | 位置 | | ----------- | -------------------- | --------------------------------------------- | | @Component | 声明bean的基础注解 | 不属于以下三类时,用此注解 | | @Controller | @Component的衍生注解 | 标注在控制器类上 | | @Service | @Component的衍生注解 | 标注在业务类上 | | @Repository | @Component的衍生注解 | 标注在数据访问类上(由于与mybatis整合,用的少) | 如果要注册的bean对象来自于第三方(不是自定义的),是无法用 @Component 及衍生注解声明bean的 给了2个方法给我们注册Bean @Bean @lmport ## 配置文件 properties配置文件(application.properties) 这个配置文件的配置内容docs.sping.io/sping-boot/docs/current/reference/html/application-properties.html#appendix.application-propertes server.port = 9090(端口修改) server.servlet.context-path=/start(虚拟目录修改) localhost:9090/start/后面是资源路径 yaml配置文件 application.yml/application.yaml server: port: 9191 servlet: context-path:/start2 ## Bean注册 | 注解 | 说明 | 位置 | | ----------- | -------------------- | --------------------------------------------- | | @Component | 声明bean的基础注解 | 不属于以下三类时,用此注解 | | @Controller | @Component的衍生注解 | 标注在控制器类上 | | @Service | @Component的衍生注解 | 标注在业务类上 | | @Repository | @Component的衍生注解 | 标注在数据访问类上(由于与mybatis整合,用的少) | ### 使用maven 引入jar包 mvn install:install-file -Dfile=jar包在本地磁盘的路径 (mvn install:install-file:使用本地的文件方式来安装Maven的坐标 -Dfile= 这个jar包本地磁盘的路径) -Dgroupld=组织名称 (-Dgroupld 它是来指定jar包安装好了之后我们的组织名是什么) -Dartifactld=项目名称 (-Dartifactld 它是来指定这个坐标安装好了之后那么它的工程名字叫什么) -Dversion =版本号 (-Dversion 来指定一下版本是多少) -Dpackaging=打包方式 (-Dpackaging 来指定一下打包的方式(默认的是jar)) ``` @springBootApplication public class springBootRegisterApplication{ public static void main(Stringll args){ ApplicationContext context = SpringApplication.run(SpringbootRegisterApplication.class, args); //如何判断这个方法Resolver给到了bean对象里面,用SpringApplication.run 把他用变量存起来 //然后使用这个变量.访问getBean方法然后选择你导入的类名.class Country country = context.getBean (Country.class); System.out.println(country); @Bean //将方法返回值交给IOC容器管理,成为IOC容器的bean对象 public Resolver resolver(){ return new Resolver(); } } ``` 引入了之后,可以在方法体的参数里面获取yml的内容(@Value) ### 如果需要有条件保证他那边不报错的话可以使用以下注解 SpringBoot提供了设置注册生效条件的注解 @Conditiona | 注解 | 说明 | | :-----------------------: | ---------------------------------------- | | @ConditionalOnProperty | 配置文件中存在对应的属性,才声明该bean | | @Conditional0nclass | 当前环境存在指定的这个类时,才声明该bean | | @ConditionalOnMissingBean | 当不存在当前类型的bean时,才声明该bean | ```java //如果配置文件中配置了指定的信息,则注入,否则不注入 @ConditionalOnProperty(prefix ="country",name ={"name" system"} //如果loc容器中不存在Country,则注入Province,否则不注入 @Bean @Conditional0nMissingBean(Country.class) //如果当前环境中存在DispatcherServlet类,则注入Province,否则不注入 //如果当前引入了web起步依赖,则环境中有DispatcherServlet,否则没有 GConditionalOnClass(name = "org.springframework.web.servlet,DispatcherServlet") ``` ## 自动配置原理 遵循约定大约配置的原则,在boot程序启动后,起步依赖中的一些bean对象会自动注入到ioc容器 ```java //因为我们写代码还要使用@Bean注解还有 在启动类在使用@Import这些操作,所以说不是自动 //@SpringBootApplication里面包含@EnableAutoConfiguration在里面引入了@Import(AutoConfigurationImportSelector.class),并且使用了这个方法string[] selectImports(...)最终导入的是org.springframework.boot.autoconfigure.AutoConfiguration.imports这个文件 这个文件里面有一个.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration这样的类里面使用了注解@AutoConfiguration(标识了这个类是自动配置类)aConditional0nClass(DispatcherServlet.class)设置了Bean注册的条件 ``` 由此说明,其实他并没有实现自动配置,只不过在类里面他封装了一系列的配置,不用使用一步步去xml配bean的操作 ## 自定义starter ### 需求 需求:自定义mybatis的starter ### 步骤 创建 dmybatis-spring-boot-autoconfiqure 模块,提供自动配置功能,并自定义配置文件 META-INF/spring/xxx.imports 创建 dmybatis-spring-boot-starter 模块,在starter中引入自动配置模块 ## Spring Validation Spring 提供的一个参数校验框架,使用预定义的注解完成参数校验 ```Java @Validated public class UserController { public Result register(@Pattern("^\\S{5,16}$")String username,@Pattern("^\\S{5,16}$") String password) { //参数校验失败异常处理 package com.dulong.exception; import ch.qos.logback.core.util.StringUtil; import com.dulong.pojo.Result; import org.springframework.util.StringUtils; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.RestControllerAdvice; /** * @Description: 参数校验失败异常处理 * @Author: dulong * @CreateTime: 2024年11月13日 11:07 */ @RestControllerAdvice public class GlobalExceptionHandler { @ExceptionHandler(Exception.class) public Result handleException(Exception e) { e.printStackTrace(); return Result.error(StringUtils.hasLength(e.getMessage()) ? e.getMessage() : "操作失败"); } } ``` # 令牌就是一段字符串 承载业务数据,减少后续请求查询数据库的次数 防篡改, 保证信息的合法性和有效性 ## JWT 全称:JSON Web Token (https://iwt.io/) 定义了一种简洁的、自包含的格式,用于通信双方以json数据格式安全的传输信息。 ![QQ20241113-112944](E:\电脑内容\网站相关\笔记\Java\图片\QQ20241113-112944.png) ![QQ20241113-113135](E:\电脑内容\网站相关\笔记\Java\图片\QQ20241113-113135.png) 使用拦截器统一验证令牌 登录和注册接口需要放行 ## ThreadLocal 1.用来存取数据: set()/get() 2.使用ThreadLocal存储的数据,线程安全 3.用完记得调用remove方法释放 ### 实体参数校验 实体类的成员变量上添加注解 @NotNull(不能为空) @NotEmpty (非空校验可以校验字符串) @Email(必须是为邮箱格式才通过) @URL(必须是为URL格式才通过) 接口方法的实体参数上添加@Validated注解 ### 自定义校验 自定义注解state message、groups、payload 自定义校验数据的类StateValidation 在需要校验的地方使用自定义注解 ## MybitsXML文件(映射配置文件)