1. 了解Spring
1.1 spring是什么?
- Spring官网
- 容器框架
Spring 是分层的javaee/javase应用,轻量级开源框架,以IOC(控制反转)和AOP(面向切面编程)为内核
1. 怎么使用spring
spring也是一个容器,里面存放java对象
- 让容器完成对象的创建,对象之间关系的管理(属性赋值)
-
2. 什么样的对象放到容器中
dao类,service类,controller类,工具类e
spring对象默认都是单例的(在容器中叫这个名称的对象就只有一个)
3. 不放入到spring容器中的对象
-
4. Spring的优势
方便解耦合,简化开发
- AOP编程的支持
- 声明式事务的支持
- 方便程序的测试
- 方便集成各种优秀的框架
- 降低javaee api的使用难度
-
1.2 Spring Maven依赖
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.0.5.RELEASE</version>
</dependency>
spring核心技术
-
1.3 Spring对”依赖”的理解
在spring中有一个词叫做依赖:
Class A 中使用了Class B的属性或者方法,叫做Class A 依赖 Class B
1.4 耦合
什么是耦合?
- 简单的来说就是程序之间的依赖性
- 都有什么耦合?
- 类之间的依赖
- 方法之间的依赖
- 解耦合
- 将低的程序间的依赖关系
- 解耦的思路
- 第一步:使用反射机制创建对象,而不是new关键字
- 第二步:通过读取配置文件来获取要创建的对象的全限定类名
2. IOC控制反转
2.1 IOC是什么?
- 英文:Inversion of control
- 描述的是:把对象的创建,赋值,管理工作都交给代码之外的容器实现,也就是对象的创建是有其他的外部资源来完成的
- 控制: 创建对象,对象属性赋值,对象之间的关系管理
- 反转:把原来的开发人员管理,创建对象的权限转移给代码之外的容器实现,由容器代替开发人员管理、创建、赋值。
- 正转:由开发人员在代码中使用new构造方法创建对象,开发人员主动管理对象
- 控制反转:在这个容器里面,这个容器代替了开发人员创建对象,赋值,管理的工作
容器:spring 管理所有的组件,主动的new 变成被动的 获取
2.2 为什么使用IOC?
对象的管理更加松散
- 解耦合
-
2.3 在之前的学习中IOC的体现
servlet中体现出来了
所有的对象不需要你去创建,直接在web.xml中配置一下tomcat自动就会帮你创建
tomcat作为容器:里面它存放了 Listener对象,Filter对象,Servlet对象2.4 IOC的技术实现DI
DI是IOC的技术实现
- DI翻译过来是 依赖注入
- Dependency Injection
- 我们只需要在程序中提供要使用的对象的名称就可以了,对象如何在容器中创建,赋值,查找都由容器内部实现。
- spring是使用了DI实现了IOC的功能,spring底层创建对象使用的是反射。
- spring是一个容器,管理对象,给属性赋值,底层是反射机制创建对象
3. Spring第一个程序
- 使用maven快速创建一个java项目
添加maven依赖
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.5.RELEASE</version>
</dependency>
创建类 (接口和他的实现类 随意创建)
- 创建spring需要的配置文件
大家公认的配置文件的名字为 application.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--告诉spring创建对象
声明bean,告诉spring要创建哪个类的对象
id:对象的自定义名称,自己给对象起个名
class:类的全限定名称(不能是接口)
-->
<!-- 一个Bean 声明一个对象 -->
<bean id="test" class="com.yixuexi.service.impl.DoServiceImpl"></bean>
<bean id="myDate" class="java.util.Date"></bean>
<bean id="myString" class="java.lang.String"></bean>
</beans>
- 使用Spring容器
创建ClassPathXmlApplicationContext 对象
@Test
public void doSomeSpringTest(){
//使用spring容器创建的对象
//1.指定spring配置文件
String config = "Test.xml";
//2.创建表示spring容器的对象,ApplicationContext(是个接口)
//ApplicationContext就是表示Spring的容器,通过容器能获取到对象
//ClassPathXmlApplicationContext表示从类路径中加载配置文件
ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext(config);
//得到对象 通过之前在配置文件中写的id得到,通过key得到value
//在进行强转一下,向下转型
DoService do1 = (DoService)ac.getBean("test");
}
3.1 spring 创建对象的时机
- 通过测试,发现在spring读取配置文件之后会立马创建出配置文件中已经配置了的对象信息
- 也就是说,在这行代码执行时 new ClassPathXmlApplicationContext(config); 所有以配置的对象都创建完毕
- 默认创建对象的时间是 在创建spring容器时,会创建配置文件中所有的对象
- spring创建对象默认调用的是对象的无参构造
1. 获取容器中定义好的对象的数量 容器就是ApplicationContext
int count = ac.getBeanDefinitionCount();
2. 获取容器中每个定义的对象的名称 也就是id 【key是什么】
```java // 返回一个String数组 String[] names = ac.getBeanDefinitionNames(); // 遍历数组 for (String name : names) { System.out.println(name); }
<a name="dZiZW"></a>
### 3. 创建一个非自定义类的对象,也就是说创建一个 Date类 String 类….
```xml
<bean id="myDate" class="java.util.Date"></bean>
<bean id="myString" class="java.lang.String"></bean>
4. XML注入/${}
4.1. 在spring配置文件中给java对象赋值
DI:依赖注入(创建对象,并给属性赋值 注入就是赋值的意思)
1. DI的实现方式有两种
- set注入(设值注入) :spring调用类的set方法,在set方法可以实现属性的赋值【很多人用 80%】
- 构造注入:spring调用类的有参构造方法,创建对象,在构造中完成赋值
3. spring中对数据类型的定义
- 简单数据类型:spring中规定了java中的基本数据类型和String都是简单类型(包装类也是简单类)
- 引用数据类型:Object及子类
4.2 set注入
set注入 【xml方式】:通过set注入进行对里面属性的赋值(也叫设值注入)
简单数据类型的set注入(本质上是调用的是set方法)
<bean id="自己起一个id名" class="全限定类名">
<properties name="属性名" value="此属性的值" />
<properties name="属性名" value="此属性的值" />
</bean>
引用数据类型的set注入:
<bean id="school02" class="com.yixuexi.test02.School">
<property name="name" value="北京市第一小学"></property>
<property name="id" value="2222"></property>
</bean>
<bean id="student02" class="com.yixuexi.test02.Student">
<property name="id" value="999"></property>
<property name="name" value="张三"></property>
<!-- value改ref 写school的id -->
<property name="school" ref="school02"></property>
</bean>
把value换成ref,然后后面跟 对应类型对象的id(也就是bean的id)
1. set注入注意事项:
- 类中必须要有set方法
- 不管是什么值 在value=”都必须在引号内”
比如student类中有一个 setAddress()方法,但是并没有这个address属性,那么在配置文件中这么写
他也会执行,并不会报错,spring找的就是类中的方法,他根据address判断出setAddress() 然后根据他的判断,他去找setAddress()这个方法,然后执行,不管有没有address属性。(只要有set方法 他就能用) 4.3 构造注入
spring调用类的有参数构造方法,在创建对象的同时,在构造方法中给属性赋值
使用 标签 :一个constructor-arg标签表示构造方法中的一个参数name:构造方法的形参名(切记 这是是形参名,一般的形参名都和属性名一致)
- index:构造方法参数的位置,参数从左往右 , 0 1 2 3
- value:简单类型的使用value
- ref:构造方法中的形参类型是引用类型的 放引用数据类型的id名
<!--通过构造方式注入来给对象属性赋值-->
<bean id="student03" class="com.yixuexi.test03.Student">
<constructor-arg name="id" value="10"></constructor-arg>
<constructor-arg name="name" value="张三"></constructor-arg>
<constructor-arg name="school" ref="school02"></constructor-arg>
</bean>
4.4 在配置文件中也支持${}写法
- 在类路径下添加一个properties的配置文件
- 然后在里面写好值 key=value
- 然后在xml文件中写
- 然后在对象value的地方进行 ${}
5. 自动注入
5.1 引用类型的自动注入
- 引用类型的自动注入:spring框架根据某些规则可以给引用类型赋值
-
1. byName
byName: (按名称注入) java类中引用类型的属性名和spring容器中(配置文件中)
的id一样 - 并且数据类型是一致的,这样的容器中的bean spring能够赋值给引用类型
```xml
> 设置 autowire="byName"
> 并且 在student这个类中的school属性名 和 上面这个school bean的id一致 才行
<a name="txDAu"></a>
### 2. byType
byType:(按类型注入,了解即可) java类中引用类型的数据类型和spring容器中(配置文件中) <bean> 的class属性是同源关系的,这样的bean能够赋值给引用类型<br />**同源:**
1. java类中的引用类型的数据类型和bean的class值是一样的
1. java类中引用类型的数据类型和bean是class的值父子类关系的
1. java类中引用类型的数据类型和bean的class的值是接口或者实现类关系的
设置 autowire="byType"
- 注意:在byType中,在xml配置文件中声明bean 只能有一个符合条件的,多余一个是错误的
- 下图表示的是byType注入,其中两个类都在同一个包下,所以符合同源的第一条,所以可以自动注入成功
![未命名图片.png](https://cdn.nlark.com/yuque/0/2021/png/12374561/1616426501146-d0fcd736-e437-4773-a79e-6982043273b2.png#height=395&id=fAHnI&margin=%5Bobject%20Object%5D&name=%E6%9C%AA%E5%91%BD%E5%90%8D%E5%9B%BE%E7%89%87.png&originHeight=395&originWidth=1185&originalType=binary&ratio=1&size=306348&status=done&style=none&width=1185)
<a name="mrFvL"></a>
# 6. 使用使用多个配置文件的优势
1. 分担了一个文件的大小
1. 避免多人编写带来的冲突
- 多文件的分配方式
- 按功能模块分类,一个模块一个配置文件(学生成绩,学生选课)
- 按类的功能,数据库相关的配置一个配置文件,事务的功能一个配置文件
<a name="MNozT"></a>
## 6.1 包含关系的配置文件
- 有三个配置文件,分别是spring-student.xml ,spring-school.xml,
- 还有一个主配置文件spring-total.xml
- 主配置文件一般都不定义对象,而是用来包含其他配置文件
<a name="PTxUP"></a>
##### 语法:
```xml
<import resource="其他配置文件的路径"/>
关键字 "classpath:" 表示类路径的(class文件所在的目录)
在spring中如果需要指定别的文件的话 需要classpath:
【idea中指的是 tagert目录下的路径】
<import resource="classpath:spring-student.xml"/>
<import resource="classpath:spring-school.xml"/>
- 当在spring-total.xml文件中集成了这些文件之后,当读取这一个文件的时候这里面的被继承文件也都读取到了
- 并且也可以支持引用类型的注入
- Spring-student.xml里面需要一个school类型的属性而spring-school.xml里面有,这样的话,就算隔着一个文件也可以引用注入