第一章:Spring概述
Srping框架是什么
框架怎么学
框架是一个软件,其他人写好的软件
1)知道框架能做什么,mybatis–访问数据库,对表中的数据执行增删改查curd
2)框架的语法,框架要完成一个功能,需要一定的步骤支持的
3)框架的内部实现,框架的内部怎么做,原理是什么
4)通过学习,可以实现一个框架
**spring全家桶:**spring,springmvc,springboot,springcloud
**spring:**出现在2002左右,解决企业级开发的难度,减轻对项目模块之间的管理,类和类之间的管理,帮助开发人员创建对象,管理对象之间的关系,spring核心技术:ioc、aop,实现模块之间、类之间的解耦合
**依赖:**class a中使用class b的属性或者方法,叫做class a依赖class b
Spring优点
(1)轻量
Spring框架使用的jar都比较小,一般在1M以下或者几百kb,Spring核心功能的所需jar总共在3M左右
(2)针对接口编程,解耦合
Spring提供了IOC控制反转,由容器管理对象,对象的依赖关系。原来在程序代码中的对象创建方式,现在由容器完成,对象之间的依赖解耦合
(3)AOP编程的支持
通过Spring提供的AOP功能,方便进行面向切面编程,许多不容易用传统OOP实现的功能可以通过AOP轻松应付
在Spring中,开发人员可以从复杂的事务管理代码中解脱出来,通过声明式方式灵活地进行事务的管理,提高开发效率和质量
(4)方便集成各种优秀框架
Spring不排斥各种优秀的开源框架,相反Spring可以降低各种框架的使用难度,Spring提供了对各种优秀框架(如struts,Hibernate,MyBatis)等的直接支持,简化框架的使用,Spring像插线板一样,其他框架是插头,可以容易的组合到一起,需要使用哪个框架,就把这个插头放入插线板,不需要可以轻易的移除
第二章:IOC控制反转
控制反转(IOC,Inversion Control),是一个概念,是一种思想,指将传统上由程序代码直接操控的对象调用权交给容器,通过容器来实现对象的装配和管理,控制反转就是对对象控制权的转移,从程序代码本身反转到了外部容器,通过容器实现对象的常见,属性赋值,依赖的管理
依赖:class A中含有class B的实例,在class A中调用class B的方法完成功能,即class A对class B有依赖
IOC的实现: 依赖注入:DI(Depndency Injection),程序代码不做定位查询,这些工作由容器自行完成
依赖注入DI是指程序运行过程中,若需要调用另一个对象协助时,无须在代码中创建被调用者,而是依赖于外部容器,由外部容器创建后传递给程序。
Spring的依赖注入对调用者与被调用者几乎没有任何要求,完全支持对象之间依赖关系的管理
Spring框架使用依赖注入(DI)实现IOC
Spring容器是一个超级大工厂,负责创建、管理所有的java对象,这些java对象被称为bean,Spring容器管理着容器中Bean之间的依赖关系,Spring使用“依赖注入”的方式来管理Bean之间的依赖关系,使用IOC实现对象之间的解耦合
**Spring第一个核心功能 ioc:**控制反转,是一个理论、概念、思想
**描述的:**把对象的创建、赋值、管理工作都交给代码之外的容器实现,也就是对象的创建是有其他外部资源完成
**控制:**创建对象,对象的属性赋值,对象之间的关系管理
**反转:**把原来的开发人员管理,创建对象的权限转移给代码之外的容器实现,由容器代替开发人员管理对象,创建对象,给属性赋值
**正转:**由开发人员在代码中,使用new构造方法常见对象,开发人员主动管理对象
public static void main(String args[]){
Student student = new Student();
}
**容器:**是一个服务器软件,是一个框架(Spring)
为什么要使用ioc
目的就是减少对代码的改动,也能实现不同的功能,实现解耦合
java中创建对象的方式:
1)构造方法,new Student()
2)反射
3)序列化
4)克隆
5)ioc:容器创建对象
6)动态代理
ioc的体现
servlet
1:创建类继承HttpServlet
2:在web.xml 注册servelt,使用
<servlet-name>myservlet</servlet-name>
<servelt-class>com.bjpwernode.controller.Myservlet</servelt-class>
3:没有常见servlet对象,没有MyServlet myservlet = new MyServlet();
4:Servlet是Tomcat服务器它给你创建的,Tomcat也称为容器
Tomcat作为容器:里面存放的有Servlet对象,Listener、Filter对象
ioc的技术实现
DI是IOC的技术实现
**DI:依赖注入(dependency Injection):**依赖注入,只需要在程序中提供要使用的对象名称就可以了,至于丢下如何在容器中创建、赋值、查找都由容器内部实现
Spring使用的di实现了ioc功能,spring底层创建对象,使用的是反射机制
Spring是一个容器、管理对象,给属性赋值,底层是反射创建对象
spring创建对象
默认创建对象时间:在创建spring容器时,会创建配置中所有对象
创建对象:默认调用无参构造方法
实现步骤
1)创建maven项目
2)加入maven的依赖
Spring的依赖,版本5.2.5版本、junit依赖
3)创建类(接口和它的实现类)和没有使用框架一样,就是普通类
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1zaKjo0e-1637928209387)(C:\Users\home\AppData\Roaming\Typora\typora-user-images\image-20211125202853792.png)]
4)创建spring需要使用的配置文件,在文件中声明类的信息,这些类由spring创建和管理
5)测试spring创建对象
<bean id="someService"class="com.bjpowernode.service.impl.SomeServiceImpl"/>
告诉spring创建对象 声明bean,就是告诉spring要创建某个类的对象 id:对象的自定义名称 唯一值,spring通过这个名称找到对象 class:类的全限定名称(不能是接口,因为spring是反射机制,反射机制创建对象,必须使用类)
spring就完成SomeService someService = new SomeServiceImpl(); spring是吧创建好的对象放入map中,spring框架有一个map存放对象的 springMap.put(id的值,对象) 例如springMap.puy(“someService” , new someServiceImpl());
一个bean标签声明一个对象
6)Spring配置文件
1、beans:是根标签,spring把java对象成为bean
2、spring-beans.xsd是约束文件,和mybatis指定 和dtd是一样的
7)spring默认创建对象的时间:在创建spring容器时,会创建所有对象
8)获取spring容器中java对象的信息
@Test
public void test03() {
String config = "beans.xml";
ApplicationContext context = new ClassPathXmlApplicationContext(config);
int nums = context.getBeanDefinitionCount();
System.out.println("个数" + nums);
String names[] = context.getBeanDefinitionNames();
for (String name : names) {
System.out.println(name);
}
}
9)spring创建一个非自定义类的对象
@Test
public void test04() {
String config = "beans.xml";
ApplicationContext context = new ClassPathXmlApplicationContext(config);
Date mydate = (Date) context.getBean("mydate");
System.out.println(mydate);
}
基于XML的DI
注入分类
在spring配置文件中,给java对象属性赋值
di:依赖注入,表示创建对象,给属性赋值
di实现的语法有两种: 1.在spring配置文件中,使用标签和属性完成,叫做基于xml的di实现 2.使用spring中的注解,完成属性赋值,叫做基于注解的id实现
di的语法分类: 1.set注入(设值注入):spring调用类的set方法,在set方法中可以实现属性的赋值,80左右都是使用set注入 2.构造注入,spring调用类的有参数构造方法,创建对象,在构造方法中完成赋值
(1)set注入(掌握)
set注入也叫设值注入是指通过setter方法传入被调用者的实例,这种注入方式很简单、直观,因而在spring依赖注入中大量使用
注入:就是赋值的意思 简单类型:spring中规定java基本数据类型和String都是简单类型 di:给属性赋值 1.set注入(设值注入):spring调用类的set方法,你可以在set方法中完成属性赋值 1)简单类型的set注入
<bean id="xx" class="yyy">
<property name="属性名字" value="此属性值"/>
一个property只能给一个属性赋值
<property ......
</bean>
<bean id="myStudent" class="com.bjpowernode.ba01.Student">
<property name="name" value="李四"/>
<property name="age" value="20"/>
</bean>
package com.bjpowernode.ba01;
public class Student {
private String name;
private int age;
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
public void setName(String name) {
System.out.println("setName" + name);
this.name = name;
}
public void setAge(int age) {
System.out.println("setAge" + age);
this.age = age;
}
}
junit
指的是单元测试,一个工具类库,做测试方法用的
单元:指定的是方法一个类中有很多方法,一个方法称为单元
使用单元测试 1.需要加入junit依赖
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
2.创建测试类:叫做测试类 src/test/java 目录中创建
3.创建测试方法 1)public方法 2)没有返回值void 3)方法名称自定义,建议名称test+ 你要测试方法名称 4)方法没有参数 5)方法的上面加入 @Test 注解,这样的方法是被单独执行的,不用使用main方法
设值注入注意事项 必须要有set方法、需要有set方法,没有的话要报错
引用类型属性自动注入
语法规则: spring调用类的set方法
<bean id="xxx" class="yyy">
<property name="属性名称" ref="bean的id(对象的名称)" />
</bean>
<bean id="myStudent" class="com.bjpowernode.ba02.Student">
<property name="name" value="李四"/>
<property name="age" value="20"/>
<property name="school" ref="mySchool"/>
</bean>
<bean id="mySchool" class="com.bjpowernode.ba02.School">
<property name="name" value="北京"/>
<property name="address" value="大学"/>
</bean>
Student类
private String name;
private int age;
private School school;
public void setSchool(School school) {
System.out.println("setSchool:" + school);
this.school = school;
}
public void setName(String name) {
System.out.println("setName:" + name);
this.name = name;
}
public void setAge(int age) {
System.out.println("setAge:" + age);
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
", school=" + school +
'}';
}
School类
private String name;
private String address;
public void setName(String name) {
this.name = name;
}
public void setAddress(String address) {
this.address = address;
}
@Override
public String toString() {
return "School{" +
"name='" + name + '\'' +
", address='" + address + '\'' +
'}';
}
测试类
@Test
public void test02() {
System.out.println("tset02");
Student student = new Student();
student.setName("lisi");
student.setAge(30);
School school = new School();
school.setName("东i");
school.setAddress("北京");
student.setSchool(school);
System.out.println("student==" + student);
}
构造注入 spring调用类的有参数构造方法,在创建对象的同时,在构造方法中给属性赋值 构造注入使用标签(语法)
<constructor-arg>
一个constructor表示构造方法一个参数
<constructor-arg>标签属性:
name:表示构造方法的形参名
index:表示构造方法参数的位置,参数从左往右位置是0、1、2的顺序
value:构造方法的形参类型是简单类型的,使用value
ref:构造方法的形参类型是引用类型的,使用ref
<bean id="myStudent" class="com.bjpowernode.ba03.Student">
<constructor-arg name="myname" value="张三"/>
<constructor-arg name="myage" value="20"/>
<constructor-arg name="mySchool" ref="myXuexiao"/>
</bean>
使用file创建文件
<bean id="myfile" class="java.io.File">
<constructor-arg name="parent" value="D:\Java"/>
<constructor-arg name="child" value="1.txt"/>
</bean>
File myfile = (File) context.getBean("myfile");
System.out.println(myfile.getName());
byName方式自动注入 引用类型的自动注入:spring框架根据某些规则可以给引用类型赋值,不用你在给引用类型赋值了,常用的是byName、byType
byName:按名称注入,java类中引用的属性名和spring容器中(配置文件)bean的id名称都一样,且数据类型是一致的,这样的容器中的beanSpring能够赋值给引用类型
语法规则:
<bean id="xx" class="yy" autowire="byName">
简单类型属性赋值
</bean>
<bean id="myStudent" class="com.bjpowernode.ba04.Student" autowire="byName">
<property name="name" value="张三"/>
<property name="age" value="20"/>
</bean>
<bean id="school" class="com.bjpowernode.ba04.School">
<property name="name" value="清华大学"/>
<property name="address" value="北京"/>
</bean>
@Test
public void test01() {
String config = "ba04/applicationContext.xml";
ApplicationContext context = new ClassPathXmlApplicationContext(config);
Student myStudent = (Student) context.getBean("myStudent");
System.out.println(myStudent);
}
byType方式自动注入 按类型注入:java类中引用类型的数据类型和spring容器中(配置文件)bean的class属性是同源关系的,这样的bean能够赋值给引用类型 同源就是一类的意思: 1、java类中引用类型的数据类型和bean的class的值是一样的 2、java类中引用类型的数据类型和bean的class的值是父子关系的 1)创建一个子类继承School
public class PrimarySchool extends School {
}
School类
private String name;
private String address;
public void setName(String name) {
this.name = name;
}
public void setAddress(String address) {
this.address = address;
}
@Override
public String toString() {
return "School{" +
"name='" + name + '\'' +
", address='" + address + '\'' +
'}';
}
测试
@Test
public void test01() {
String config = "ba05/applicationContext.xml";
ApplicationContext context = new ClassPathXmlApplicationContext(config);
Student myStudent = (Student) context.getBean("myStudent");
System.out.println(myStudent);
}
3、java类中引用类型的数据类型和bean的class的值接口和实现类关系的
在byType中,在xml配置文件中声明bean只能有一个符合条件的,多余一个是错误的
为应用指定多个spring配置文件
为什么要用多配置 优势: 1、每个文件的大小比一个文件要小很多 2、避免多人竞争带来的冲突 如果你的项目有多个模块(相关的功能在一起),一个模块一个配置文件 学生考勤模块一个配置文件,张三 学生成绩模块一个配置文件,李四 3、多文件的分配方式: 1)按功能模块,一个模块一个配置文件 2)按类的功能,数据库相关的配置一个配置文件,做事务的功能一个配置文件
包含关系的配置文件 拿一个配置文件作为主文件:包含其他的配置文件的,主配置文件一般是不定义对象的
语法:import resource = “其他配置文件的路径” 关键字:“classpath:”表示类路径(class文件所在的目录)在spring配置文件中指定其他文件的位置,需要使用classpath,告诉spring到哪去加载读取文件
<import resource="classpath:b05/spring-school.xml"/>
<import resource="classpath:b05/spring-student.xml"/>
使用通配符 注意:主配置文件名称不能包含在通配符的范围内(如spring-*.xml,前面不能包含spring-),因为会读取主配置文件,造成死循环报错
<import resource="classpath:ba05/spring-*.xml"/>
|