目录
一、Spring简介
二 , Spring相关概念
三,入门案例
3.1. IOC入门案例思路分析
3.2 IOC入门案例代码实现
3.3 DI入门案例思路分析
3.4 入门案例代码实现
四,IOC相关内容
4.1 bean基础配置
4.1.1 bean基础配置(id与class)
4.1.2 bean的别名name
4.1.3 bean作用范围scope配置
4.14 bean基础配置小结
4.2 bean实例化
4.2.1 构造方法实例化(常用)
4.2.2 静态工厂实例化 (了解)
4.2.3 实例工厂与FactoryBean (了解)
4.2.4 FactoryBean的使用 (重要 )
4.2.5 bean实例化小结
4.3 bean的生命周期 (了解即可)
4.3.1 bean生命周期小结
五,DI相关内容
5.1 setter注入
5.2 构造器注入
5.3 依赖自动装配
5.3.1 什么是依赖自动装配?
5.3.2 自动装配方式有哪些?
5.4 集合注入
简化开发 : 降低企业级开发的复杂性
框架整合 : 高效整合其他技术,提高企业级应用开发与运行效率
一 学什么?
Spring框架主要的优势是在简化开发和框架整合上,至于如何实现就是咱们要学习Spring框架的主要内容:
1.Spring的简化操作都是基于这两块内容,所以这也是Spring学习中最为重要的两个知识点。
2.事务处理属于Spring中AOP的具体应用,可以简化项目中的事务管理,也是Spring技术中的一大亮点。
这些框架中,我们目前只学习了MyBatis,所以在Spring框架的学习中,主要是学习如何整合MyBatis。
综上所述,对于Spring的学习,主要学习四块内容:
(1) IOC,
(2) 整合Mybatis(IOC的具体应用),
(3) AOP,
(4) 声明式事务(AOP的具体应用)
二 . 怎么学?
重点学习Spring Framework、SpringBoot和SpringCloud:
系统架构图
(1)核心层
(2)AOP层
(3)数据层
(4)Web层
(5)Test层
学习路线
Spring的学习主要包含四部分内容,分别是:
Spring核心概念
在Spring核心概念这部分内容中主要包含IOC/DI、IOC容器和Bean,那么问题就来了,这些都是什么呢?
目前项目中的问题 要想解答这个问题,就需要先分析下目前咱们代码在编写过程中遇到的问题:
(1)业务层需要调用数据层的方法,就需要在业务层new数据层的对象
(2)如果数据层的实现类发生变化,那么业务层的代码也需要跟着改变,发生变更后,都需要进行编译打包和重部署
(3)所以,现在代码在编写的过程中存在的问题是:耦合度偏高
针对这个问题,该如何解决呢?
我们就想,如果能把框中的内容给去掉,不就可以降低依赖了么,但是又会引入新的问题,去掉以后程序能运行么?
答案肯定是不行,因为bookDao没有赋值为Null,强行运行就会出空指针异常。
所以现在的问题就是,业务层不想new对象,运行的时候又需要这个对象,该咋办呢?
针对这个问题,Spring就提出了一个解决方案:
这种实现思想就是Spring的一个核心概念 IOC
IOC、IOC容器、Bean、DI
(1)什么是控制反转呢?
(2)Spring和IOC之间的关系是什么呢?
(3)IOC容器的作用以及内部存放的是什么?
(4)当IOC容器中创建好service和dao对象后,程序能正确执行么?
像这种在容器中建立对象与对象之间的绑定关系就要用到DI:
(1)什么是依赖注入呢?
(2)IOC容器中哪些bean之间要建立依赖关系呢?
介绍完Spring的IOC和DI的概念后,我们会发现这两个概念的最终目标就是:==充分解耦==,具体实现靠:
核心概念小结
这节比较重要,重点要理解什么是IOC/DI思想、什么是IOC容器和什么是Bean:
(1)什么IOC/DI思想?
(2)什么是IOC容器?
Spring创建了一个容器用来存放所创建的对象,这个容器就叫IOC容器
(3)什么是Bean?
容器中所存放的一个个对象就叫Bean或Bean对象
思考一个问题就是,Spring到底是如何来实现IOC和DI的 ? 通过简单的入门案例,来演示下具体实现过程
(1)Spring是使用容器来管理bean对象的,那么管什么?
(2)如何将被管理的对象告知IOC容器?
(3)被管理的对象交给IOC容器,要想从容器中获取对象,就先得思考如何获取到IOC容器?
(4)IOC容器得到后,如何从容器中获取bean?
(5)使用Spring导入哪些坐标?
主要 第一步 : 添加依赖spring-context 第二步 : 编写spring配置文件 applicationContext.xml 第三步: 从容器中获取对象进行方法调用
需求分析:将BookServiceImpl和BookDaoImpl交给Spring管理,并从容器中获取对应的bean对象进行方法调用。
1.创建Maven的java项目
2.pom.xml添加Spring的依赖jar包
3.创建BookService,BookServiceImpl,BookDao和BookDaoImpl四个类
4.resources下添加spring配置文件,并完成bean的配置
5.使用Spring提供的接口完成IOC容器的创建
6.从容器中获取对象进行方法调用
步骤1:创建Maven项目
步骤2:添加Spring的依赖jar包 pom.xml
步骤3:添加案例中需要的类 : 创建BookService,BookServiceImpl,BookDao和BookDaoImpl四个类
public interface BookDao {
public void save();
}
public class BookDaoImpl implements BookDao {
public void save() {
System.out.println("book dao save ...");
}
}
public interface BookService {
public void save();
}
public class BookServiceImpl implements BookService {
private BookDao bookDao = new BookDaoImpl();
public void save() {
System.out.println("book service save ...");
bookDao.save();
}
}
步骤4:添加spring配置文件 resources下添加spring配置文件applicationContext.xml,并完成bean的配置
步骤5:在配置文件中完成bean的配置 注意事项:bean定义时id属性在同一个上下文中(配置文件)不能重复
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
步骤6:获取IOC容器 使用Spring提供的接口完成IOC容器的创建,创建App类,编写main方法 并从容器中获取对象进行方法调用
public class App {
public static void main(String[] args) {
//获取IOC容器
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
// BookDao bookDao = (BookDao) ctx.getBean("bookDao");
// bookDao.save();
BookService bookService = (BookService) ctx.getBean("bookService");
bookService.save();
}
}
Spring的IOC入门案例已经完成,但是在`BookServiceImpl`的类中依然存在`BookDaoImpl`对象的new操作,它们之间的耦合度还是比较高,该如何解决,就需要用到下面的`DI:依赖注入
(1)要想实现依赖注入,必须要基于IOC管理Bean
(2)Service中使用new形式创建的Dao对象是否保留?
(3)Service中需要的Dao对象如何进入到Service中?
(4)Service与Dao间的关系如何描述?
需求:基于IOC入门案例,在BookServiceImpl类中删除new对象的方式,使用Spring的DI完成Dao层的注入
1.删除业务层中使用new的方式创建的dao对象
2.在业务层提供BookDao的setter方法
3.在配置文件中添加依赖注入的配置
4.运行程序调用方法
步骤1: 去除代码中的new 在BookServiceImpl类中,删除业务层中使用new的方式创建的dao对象
public class BookServiceImpl implements BookService {
//删除业务层中使用new的方式创建的dao对象
private BookDao bookDao;
public void save() {
System.out.println("book service save ...");
bookDao.save();
}
}
步骤2:为属性提供setter方法 在BookServiceImpl类中,为BookDao提供setter方法
public class BookServiceImpl implements BookService {
//删除业务层中使用new的方式创建的dao对象
private BookDao bookDao;
public void save() {
System.out.println("book service save ...");
bookDao.save();
}
//提供对应的set方法
public void setBookDao(BookDao bookDao) {
this.bookDao = bookDao;
}
}
步骤3:修改配置完成注入 在配置文件中添加依赖注入的配置
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
==注意:配置中的两个bookDao的含义是不一样的==
通过前面两个案例,我们已经学习了bean如何定义配置,DI如何定义配置以及容器对象如何获取的内容,接下来主要是把这三块内容展开进行详细的讲解,深入的学习下这三部分的内容,首先是bean基础配置。
对于bean的配置中,主要会讲解bean基础配置,bean的别名配置,bean的作用范围配置==(重点)==,这三部分内容:
对于bean的基础配置,在前面的案例中已经使用过:
其中,bean标签的功能、使用方式以及id和class属性的作用,我们通过一张图来描述下
scope使用后续思考
介绍完scope属性以后,我们来思考几个问题:
对象已经能交给Spring的IOC容器来创建了,但是容器是如何来创建对象的呢?
就需要研究下bean的实例化过程,在这块内容中主要解决两部分内容,分别是
在讲解这三种创建方式之前,我们需要先确认一件事:
bean本质上就是对象,对象在new的时候会使用构造方法完成,那创建bean也是使用构造方法完成的。
Spring容器在创建对象的时候也走的是构造函数, 能访问到类中的私有构造方法,显而易见Spring底层用的是反射 , 类的无参构造方法
基于这个知识点出发,我们来验证spring中bean的三种创建方式,
因为每一个类默认都会提供一个无参构造函数,所以其实真正在使用这种方式的时候,我们什么也不需要做。这也是我们以后比较常用的一种方式。
Spring中的第二种bean的创建方式静态工厂实例化:
class:工厂类的类全名
factory-mehod:具体工厂类中创建对象的方法名
看到这,可能有人会问了,你这种方式在工厂类中不也是直接new对象的,和我自己直接new没什么太大的区别,而且静态工厂的方式反而更复杂,这种方式的意义是什么?
主要的原因是:
public class OrderDaoFactory {
public static OrderDao getOrderDao(){
System.out.println("factory setup....");//模拟必要的业务操作
return new OrderDaoImpl();
}
}
接下来继续来研究Spring的第三种bean的创建方式实例工厂实例化:
实例工厂实例化的方式就已经介绍完了,配置的过程还是比较复杂,所以Spring为了简化这种配置方式就提供了一种叫`FactoryBean`的方式来简化开发。
具体的使用步骤为:
(1)创建一个UserDaoFactoryBean的类,实现FactoryBean接口,重写接口的方法
public class UserDaoFactoryBean implements FactoryBean
//代替原始实例工厂中创建对象的方法
public UserDao getObject() throws Exception {
return new UserDaoImpl();
}
//返回所创建类的Class对象
public Class> getObjectType() {
return UserDao.class;
}
}
(2)在Spring的配置文件中进行配置
(3)AppForInstanceUser运行类不用做任何修改,直接运行
public class AppForInstanceUser {
public static void main(String[] args) {
ApplicationContext ctx = new
ClassPathXmlApplicationContext("applicationContext.xml");
UserDao userDao = (UserDao) ctx.getBean("userDao");
userDao.save();
}
}
这种方式在Spring去整合其他框架的时候会被用到,所以这种方式需要大家理解掌握。
查看源码会发现,FactoryBean接口其实会有三个方法,分别是:
T getObject() throws Exception;
Class> getObjectType();
default boolean isSingleton() {
return true;
}
方法一:getObject(),被重写后,在方法中进行对象的创建并返回
方法二:getObjectType(),被重写后,主要返回的是被创建类的Class对象
方法三:没有被重写,因为它已经给了默认值,从方法名中可以看出其作用是设置对象是否为单例,默认true,是单例的 , 如果想改成非单例 , 改为false就可以
通过这一节的学习,需要掌握:
(1)bean是如何创建的呢?
构造方法
(2)Spring的IOC实例化对象的三种方式分别是:
这些方式中,重点掌握构造方法和FactoryBean即可。
需要注意的一点是,构造方法在类中默认会提供,但是如果重写了构造方法,默认的就会消失,在使用的过程中需要注意,如果需要重写构造方法,最好把默认的构造方法也重写下。
关于bean的相关知识还有最后一个是bean的生命周期,对于生命周期,我们主要围绕着bean生命周期控制来讲解:
现在我们面临的问题是如何在bean的创建之后和销毁之前把我们需要添加的内容添加进去。
BookDao添加生命周期的控制方法,具体的控制有两个阶段:
(1)关于Spring中对bean生命周期控制提供了两种方式:
(2)对于bean的生命周期控制在bean的整个生命周期中所处的位置如下:
(3)关闭容器的两种方式:
前面我们已经完成了bean相关操作的讲解,接下来就进入第二个大的模块DI依赖注入,首先来介绍下Spring中有哪些注入方式?
我们先来思考
Spring就是基于上面这些知识点,为我们提供了两种注入方式,分别是:
依赖注入的方式已经介绍完,接下来挨个学习下:
介绍完两种参数的注入方式,具体我们该如何选择呢?
这节中主要讲解的是Spring的依赖注入的实现方式:
前面花了大量的时间把Spring的注入去学习了下,总结起来就一个字==麻烦==。
问:麻烦在哪?
答:配置文件的编写配置上。
问:有更简单方式么?
答:有,自动配置
什么是自动配置以及如何实现自动配置,就是接下来要学习的内容:
==注意事项:==
一个类型在IOC中有多个对象,还想要注入成功,这个时候就需要按照名称注入,配置方式为:
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">