1 了解spring系统架构
spring指的是Spring Framework,那么它其中都包含哪些内容和学习这个框架
1.1 架构图
(1)核心层
-
Core Container:核心容器,这个模块是Spring最核心的模块,其他的都需要依赖该模块
(2)AOP层
-
AOP:面向切面编程,它依赖核心层容器,目的是==在不改变原有代码的前提下对其进行功能增强==
-
Aspects:AOP是思想,Aspects是对AOP思想的具体实现
(3)数据层
-
Data Access:数据访问,Spring全家桶中有对数据访问的具体实现技术
-
Data Integration:数据集成,Spring支持整合其他的数据层解决方案,比如Mybatis
-
Transactions:事务,Spring中事务管理是Spring AOP的一个具体实现,也是后期学习的重点内容
(4)Web层
-
这一层的内容将在SpringMVC框架具体学习
(5)Test层
-
Spring主要整合了Junit来完成单元测试和集成测试
1.2 学习核心层(Core Container)
我们的项目中,我们在业务层需要一个对象就new一个对象,但是数据层的代码发生变化业务层也需要改变,有着高耦合。
1.2.1 常见问题
我们直接在业务层new一个对象,这样会让代码的耦合度高,我们使用spring就是可以减低耦合度。
然后不new一个对象出来是否可以呢,答案肯定是不行,因为bookDao没有赋值为Null,强行运行就会出空指针异常。所以现在的问题就是,业务层不想new对象,运行的时候又需要这个对象,该咋办呢?
spring给出了一个解决方案程序中不要主动使用new产生对象,转换为由==外部==提供对象,所以提出来了一个核心概念,IOC(Inversion of Control)控制反转。
1. 2.2 IOC(Inversion of Control)控制反转
(1)什么是控制反转
核心思想是将对象的创建和依赖管理交给外部容器或框架,而不是由对象自身控制。传统方式中,对象自行创建和管理依赖,而IOC将这一过程反转,由外部容器负责对象的创建和依赖注入。
其实就是之前是自己new的,现在是通过外部获取对象。
(2)Spring和IOC之间的关系是什么呢?
Spring IOC容器:Spring的核心模块,负责创建、配置和管理对象(Bean)。
依赖注入:Spring通过XML配置、注解或Java代码实现依赖注入。
(3)IOC容器的作用以及内部存放的是什么?
IOC容器负责对象的创建、初始化等一系列工作,其中包含了数据层和业务层的类对象
被创建或被管理的对象在IOC容器中统称为==Bean==
IOC容器中放的就是一个个的Bean对象
(4)当IOC容器中创建好service和dao对象后,程序能正确执行么?
不行,因为service运行需要依赖dao对象
IOC容器中虽然有service和dao对象
但是service对象和dao对象没有任何关系
需要把dao对象交给service,也就是说要绑定service和dao对象之间的关系,这个叫做依赖注入
1.2.3 依赖注入(DI)
(1)什么是依赖注入
把一个bean放入容器中,建立bean和bean依赖关系的整个过程,称为依赖注入。
在业务层不自己new一个对象,依靠外部获得。
(2)IOC容器中哪些bean依赖关系
需要我们提前根据自己的需求建立关系,我们会发现这两个概念的最终目标就是:充分解耦,具体实现靠:
1、使用IoC容器管理bean对象
2、在IoC容器中依赖关系进行绑定
3、使用对象可以在IoC容器中获取
1.2.4 小结
(1)什么是IoC:Spring创建了一个容器用来存放所创建的对象,这个容器就叫IOC容器
(2)什么是bean:容器中存放的对象就是bean
2 基本使用
2.1 IOC的基本使用
需求分析:将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.从容器中获取对象进行方法调用
2.1.1 导入jar包
1、在pom.xml文件值导入jar包
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.10.RELEASE</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
</dependencies>
2、创建需要的类
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();
}
}
3、resources下添加spring配置文件applicationContext.xml,并完成bean的配置
<?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">
<bean id="bookDao" class="com.example.dao.Impl.BookDaoImpl"/>
<bean id="bookService" class="com.example.service.Impl.BookServiceImpl"/>
</beans>
2.1.2 运行程序
为什么可以接口代替实现类,ai给出的解释
2.1.3 减低耦合
刚刚我们使用的还是传统的new的方法,我们应该减低耦合。这个时候,Spring的DI完成Dao层的注入。
1、业务层
package com.example.service.Impl;
import com.example.dao.BookDao;
import com.example.service.BookService;
public class BookServiceImpl implements BookService {
private BookDao bookDao1 ;
public void save() {
System.out.println("book service save ...");
bookDao1.save();
}
public void setBookDao222(BookDao bookDao) {
this.bookDao1 = bookDao;
}
}
2、配置文件
<?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">
<bean id="bookDao" class="com.example.dao.Impl.BookDaoImpl"/>
<bean id="bookService" class="com.example.service.Impl.BookServiceImpl">
<property name="bookDao222" ref="bookDao"/>
</bean>
</beans>
这里我们可以发现配置文件的
name:表示的是set方法的“setBookDao222”去掉set以后的首字母小写以后
ref="bookDao"中bookDao
的作用是让Spring能在IOC容器中找到id为bookDao
的Bean对象给bookService
进行注入
3、运行结果
运行结果一样,说明是new取消成功。
2.1.4 验证IOC容器中对象是否为单例
直接运行我们可以看见地址是一样的,所以通过IOC中获取对象的是单例,如果我们需要创建多个对象需要在bean中,加入这个 scope="prototype"
prototype:非单例
singleton:单例(默认)
加入后
<bean id="bookService" class="com.example.service.Impl.BookServiceImpl" scope="prototype" > <property name="bookDao222" ref="bookDao"/> </bean>