diff --git "a/\345\217\266\344\277\212\346\235\260/20241226 springmvc\345\237\272\347\241\200\344\275\277\347\224\250.md/03 Spring 12.26.md" "b/\345\217\266\344\277\212\346\235\260/20241226 springmvc\345\237\272\347\241\200\344\275\277\347\224\250.md/03 Spring 12.26.md" new file mode 100644 index 0000000000000000000000000000000000000000..7bfbbae677710c3d290c552a319fe6f9f4a890b0 --- /dev/null +++ "b/\345\217\266\344\277\212\346\235\260/20241226 springmvc\345\237\272\347\241\200\344\275\277\347\224\250.md/03 Spring 12.26.md" @@ -0,0 +1,883 @@ +## 一、初体验 +1. 官网:https://spring.io/ +2. Spring要和,JDK版本对应得上,否则会报错信息类似:Failed to read candidate component class,也就是注解扫描不了,这是版本兼容问题引起的,根据Spring官网Spring Framework与JDK版本对应表: + +| Spring Framework版本 | JDK版本 | +| -------------------- | --------- | +| 6.0.x | JDK 17-21 | +| 5.3.x | JDK 8-19 | +| 5.2.x | JDK 8-15 | +| 5.1.x | JDK 8-12 | +| 5.0.x | JDK 8-10 | +| 4.3.x | JDK 6-8 | +3. Spring Framework的特点 + 1. 控制反转:IoC,反转资源获取方向;把自己创建的资源、向环境索取资源变为环境将资源准备好,我们享受资源注入。 + 2. 面向切面编程:AOP,在不修改源代码的基础上增强代码功能。 + 3. 容器:Spring IoC是一个容器,因为它包含并管理组件对象的生命周期;组件享受到了容器化的管理,替程序员屏蔽了组件创建过程中的大量细节,极大降低了使用门槛,大幅度提高了开发效率。 + 4. 一站式:在IOC和AOP的基础上可以整合各种企业应用的开源框架和优秀的第三方库,而且在Spring旗下的项目已经覆盖了广泛领域,很多方面的功能性需求可以在Spring Framework 的基础上全部使用Spring来实现。 +4. 入门案例 + 1. 环境要求: + - JDK : 1.8 + - Spring : 5.3.39 + 2. 构建工程项目 + 3. pom.xml中引入相关依赖,并 刷新maven +-------------------------- +```xml + + + org.springframework + spring-context + 5.3.39 + + + junit + junit + 4.13.2 + test + + +``` +------------------------- + 4. 创建软件包 + ![image.png](https://gitee.com/onesheet/images_backup/raw/master/images/20241215222659.png) + 5. 创建用于测试的实体类Teacher + ![image.png](https://gitee.com/onesheet/images_backup/raw/master/images/20241215222947.png) + 6. **创建spring配置文件:resources目录下创建bean.xml** +![image.png](https://gitee.com/onesheet/images_backup/raw/master/images/20241215223246.png) +![image.png](https://gitee.com/onesheet/images_backup/raw/master/images/202412191016646.png) +![image.png](https://gitee.com/onesheet/images_backup/raw/master/images/202412191016805.png) +![image.png](https://gitee.com/onesheet/images_backup/raw/master/images/20241215223436.png) + 7. **在bean.xml中用标签完成对象创建** +------------------- +```xml + + + + + +``` +---------------------------- + 8. **创建测试类com.md.test.TestTeacher进行测试** +------------ +```java +public class TestTeacher { + @Test + public void t1() { + // 1.加载spring配置文件,得到IOC容器context + ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml"); + // 2.从IOC容器获取spring创建好的对象 + Teacher teacher = (Teacher) context.getBean("teacher"); + // 3.使用对象调用方法测试 + System.out.println("teacher = " + teacher); + teacher.teach(); + } +} +``` +![image.png](https://gitee.com/onesheet/images_backup/raw/master/images/20241215224418.png) + +----------------------- +## 二、一些术语概念 +### 1. IoC容器 +1. IoC 是 Inversion of Control 的简写,译为 控制反转。 +2. IoC容器 + 1. 管理着所有的Java对象的实例化和初始化, + 2. 控制着对象与对象之间的依赖关系。 + 3. IoC容器管理的Java对象称为 Spring Bean, + 4. 它与使用关键字 new 创建的Java对象没有任何区别。 +3. IoC容器是Spring框架中最重要的核心组件之一,它贯穿了Spring从诞生到成长的整个过程。 + +### 2. 控制反转( IoC ) +> 控制反转是一种思想 + +1. 将对象的创建权利交出去,交给第三方容器(IOC容器)负责 +2. 将对象和对象之间的关系维护权交出去,交给第三方容器负责 + +>如何实现控制反转 + +- 通过依赖注入DI的方式实现 + +### 3. 依赖注入( DI ) +DI (Dependency Injection):依赖注入,依赖注入实现了控制反转的思想,是指Spring创建对象的过程中,将对象依赖属性通过配置进行注入。 + +>依赖注入常见的实现方式有两种: + +1. set注入 ,常用 +2. 构造器注入 + +>结论: IoC 是一种控制反转的思想,而 DI 是对IoC的一种具体实现。 + +Bean管理:指对IOC容器中的Bean对象的创建,以及Bean对象中属性的赋值(或Bean对象之间关系的维护) + +### 4. IoC容器的实现 +>Spring中的IoC容器就是IoC思想的一个落地产品实现。IoC容器中管理的组件也叫做bean。在创建bean之前,首先需要创建IoC容器,Spring提供了IoC容器的两种实现方式 + +① BeanFactory + +这是IoC容器的基本实现,是Spring内部使用的接口。面向Spring本身,不提供给开发人员使用。 + +② ApplicationContext + +BeanFactory的子接口,提供了更多高级特性,面向Spring的使用者,几乎所有场合都使用 ApplicationContext,而不是底层的BeanFactory + +③ ApplicationContext的主要实现类 +![image.png](https://gitee.com/onesheet/images_backup/raw/master/images/20241215230030.png) + +--------------- +| 类型 | 说明 | 路径示例 | +| ------------------------------ | -------------------------------------------------- | -------------------------------------------- | +| ClassPathXmlApplicationContext | 通过读取类路径下的xml格式配置文件创建IoC容器对象 | appcontext.xml | +| FileSystemApplicationContext | 通过文件系统路径读取xml格式配置文件创建IoC容器对象 | file:F:/workspace/example/src/appcontext.xml | +--------------- + +## 三、如何通过XML管理Bean + +1. 还是 com.mdd.entity.Teacher 为例,来演示 +2. 获取bean方式 + 1. 根据id获取: + 1. id属性是bean的唯一标识,所以根据bean标签的id属性可以精确获取到一个组件对象。 + 2. ![](https://gitee.com/onesheet/images_backup/raw/master/images/202412191016571.png) + 2. 根据类型获取 + 1. ![image.png](https://gitee.com/onesheet/images_backup/raw/master/images/202412191016728.png) + + 3. 根据id和类型获取 + 1. ![image.png](https://gitee.com/onesheet/images_backup/raw/master/images/20241215231631.png) + + + +>注意: 当根据类型获取bean时,要求IoC容器中指定类型的bean只能有一个,当配置两个时会抛出异常 + + +### * 依赖注入的两种常见方式 +>类是有属性的,创建对象过程中,如何向属性注入具体的值? + +1. 方式1:使用set方法完成(使用xml中的标签实现) +2. 方式2:基于构造器完成 + + +1. 使用set方法完成 + 1. 类中补充setter toString + 1. ![image.png](https://gitee.com/onesheet/images_backup/raw/master/images/202412191016811.png) + + 2. 修改bean.xml,进行属性值注入 + 1. ![image.png](https://gitee.com/onesheet/images_backup/raw/master/images/20241215232345.png) + 2. 测试: + 1. ![image.png](https://gitee.com/onesheet/images_backup/raw/master/images/20241215232424.png) + + +3. 基于构造器依赖注入 + 1. 补全类中的构造器 + 1. ![image.png](https://gitee.com/onesheet/images_backup/raw/master/images/202412191016440.png) + + 2. 修改bean.xml + 1. ![image.png](https://gitee.com/onesheet/images_backup/raw/master/images/202412191016644.png) + + 3. 测试 + 1. !![image.png](https://gitee.com/onesheet/images_backup/raw/master/images/202412191016926.png)[image.png](https://gitee.com/onesheet/images_backup/raw/master/images/20241215232915.png) + + +4. 不同类型的属性有不同的表示方式 + 1. 简单类型 : value + 2. 对象引用类型 : ref + 3. 数组 \value或ref\ + 4. 集合\value或ref\ + 5. 空值 \\ + + + +5. 练习 + 1. 使用spring框架完成以下操作 + 2. 分别创建老师,课程,学生三个类,每个类要有三个属性,做成javabean + 3. 配置bean.xml进入Bean管理,分别创建老师,课程,学生的bean + 4. 老师有:姓名,多门课程(数组),多个学生(集合) + 5. 课程有:课程名称,学分 + 6. 学生有:姓名,年龄,一个任课老师。 + 7. 编写测试类,对每种bean进行测试。 + + +## 进阶一: +1. 使用lombok 快速创建javabean的类 +2. 特殊类型的注入,实体符< > +3. ]]> +4. 4. druid数据源 https://zhuanlan.zhihu.com/p/690241776 +5. 外部属性文件的引入, +6. 自动装配 +7. 三层架构:dao,service,controller + 1. 详解三层架构 是什么? 为什么? 怎么做? + 2. ![image.png](https://gitee.com/onesheet/images_backup/raw/master/images/20241219150430.png) + + 3. https://blog.csdn.net/S_yyuan/article/details/121554927 + 5. 步骤 + 1. 创建好各个软件包:entity->dao->service->controller + 2. 创建实体类 User(用来封装数据),(相当于做菜品材料) + 3. 创建数据访问层 (采购员) + 1. UserDao 接口 ,相当于采购员岗位,接口中的方法。相当于岗位职责 + 2. UserDao 接口的实现类UserDaoImpl,相当于聘请的具体采购员,要符合岗位职责,所以要实现所有方法 + 3. 在UserDaoImpl实现类中,写操作数据库的具体逻辑(具体的采购办法) + 4. 创建业务逻辑层 (厨师) + 1. UserService 接口,明确厨师的岗位职责,编写业务层要实现的功能方法 + 2. UserService 接口的实现类UserServiceImpl,相当于根据厨师岗位职责招聘来的厨师,所有要具备厨师岗位所有技巧,即实现接口的所有方法 + 3. 在UserServiceImpl实现类中,厨师做菜,要有材料,所以依赖于采购员,把采购员UserDao做为一个类属性注入进来 + 4. 在UserServiceImpl实现类中,对UserDao传过来的数据,做进一步处理。相当于加工材料做成菜。 + 1. 厨师做菜的材料,是依赖采购员来采购的。所以 + 2. 在UserServiceImpl实现类中要定义一个UserDao的属性 + 3. 在Bean中将UserDao对象入注入进来 + 5. 创建表示层 (服务员) + 1. UserController 类, + 1. 负责接收用户请求,并转发给UserServiceImpl:相当于服务员接收顾客点菜后,将菜单订单转发给厨师,厨师会根据这个订单开始做菜 + 2. 负责接收UserServiceImpl的响应,将转发给用户:相当于服务员将厨师做好的菜。端给前面点菜的顾客。 + 3. 因为厨师做好了菜之后,服务员才能将菜端给顾客,所以服务员的工作是依赖于厨师的。 + 1. controller 类中要定义一个 UserService的属性 + 2. 在Bean中将UserServicec对象注入进来 + 6. 总结 + 1. Controller依赖Service,Service依赖Dao + 2. 所以controller的bean要注入Service,Service的bean要注入Dao +8. ### **注解开发** + 1. 项目结构如bean.xml时一样 + 2. 新建config包,并创建SpringConfig类,里面改写bean.xml的配置 + 3. SpringConfig 配置 + 1. 声明自己是一个配置类 @Configuration + 2. 扫描自定久类Bean所在的包@ComponentScan("com.pdd") + 3. 为了方便管理,将jdbc和mybatis的配置单独成一个子配置文件 + 1. JdbcConfig + 1. @Component 声明自己是组件一部分 + 2. @PropertySource("classpath:jdbc.properties") 加载外部的属性文件 + 3. 以@Value注解,注入四个属性变量@Value("${jdbc.driver}") + 4. 以自定义方法的形式,public DruidDataSource getDruidDataSource(){ 返回一个DataSource对象 + 5. 不要忘记在这个方法上加上@Bean注解 + + 2. MybatisConfig + 1. @Component 声明自己是组件一部分 + 2. @MapperScan("com.pdd.mapper") 扫描mapper代理接口所在的包 + 3. 以自定义方式的形式, 返回一个SqlSessionFactoryBean的对象 + 4. 不要忘记在这个方法上加上@Bean注解 + 4. @Import({JdbcConfig.class, MyBatisConfig.class}) 将刚才创建的两个子配置文件导入进来 + 5. 新建测试类 + 1. 手动方式 ApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class); 得到IOC容器。由xml转为从配置类中获取容器。 + 2. 依赖注入的方式 + 1. @RunWith(SpringJUnit4ClassRunner.class) 测试类上方加这个注解 + 2. @ContextConfiguration(classes = SpringConfig.class) 测试类上方加这个注解 + 3. 直接将需要的对象,以属性自动装配的方式注入 @Autowired private DeptController deptController; + 4. 直接使用这个注入的对象 Dept dept = deptController.selectOneById(3); + + +Spring 常用注解 +组件定义与依赖注入 + +在Spring中,可以使用以下注解来定义组件并注入依赖: + +- _@Component_:通用组件,不指定角色。 + +- _@Service_:用于业务逻辑层(Service层)。 + +- _@Repository_:用于数据访问层(DAO层)。 + +- _@Controller_:用于表示层(Controller层)。 + +- _@Autowired_:自动注入Spring容器管理的bean。引用类型,对象 +- @Value : 自动注入简单的值String ,int + +- @PropertySource 加载外部属性文件 + + +配置与作用域 + +- _@Configuration_:声明一个类为配置类,相当于XML形式的Spring配置。 +- _@Bean_:用于在配置类中声明一个bean。一般用于第三方对象的new出来的对象 +- @ComponentScan({"com.pdd.controller","com.pdd.service"}) 将自己建的类,要生成bean所在的包 +- @Import({JdbcConfig.class, MyBatisConfig.class}) 导入子配置文件 +- @MapperScan mybatis提供的,扫描接口的注解,为了的给所有接口生成对应的实现类的bean + + + + + + + +## 注解重构项目,步骤分解 +1. 导入POM.xml文件各种坐标 +2. 补全各处包 entity,mapper,service,controller,config +3. 在entity实体类包下,根据表结构创建对应的实体类Video + + ```java + // Video.java + @Data // 相当于写了get,set,toString + @AllArgsConstructor //全参 + @NoArgsConstructor //无参 + public class Video { + // 做成javaBean标准类的形式, + // 属性全私有,get,set,toString ,全参和无参构造器 + private int videoId; + private String videoName; } + ``` + + + + 4. 在mapper包下,创建sql语句的代理接口,VideoMapper (dao层),在方法上方编写SQL语句,不用创建它的实现类。因为mybatis自动代理会实现所有的mapper接口的接口 +```java +// VideoMapper +public interface VideoMapper { + // 就是对表的,CRUD是CREATE、READ、UPDATE和DELETE的首字母缩写 +// 定义五个方法,分别表示查询所有,根据编号查询某行,根据编号删除某行,添加,修改 +// 查询所有,返回所有行的集合 List List