Spring 简介和配置#
学习目标#
【应用】能够独立完成 springIOC 的快速入门
【应用】能够掌握 spring 的 bean 标签的配置
【应用】能够独立完成 bean 的对象属性注入
【应用】能够独立完成 bean 的普通属性注入
【理解】能够独立完成 bean 的集合属性注入
1、Spring 概述#
1.1 spring 是什么#
Spring 是分层的 Java SE/EE 应用 full-stack 轻量级开源框架,以 IoC(Inverse Of Control:反转控制)和 AOP(Aspect Oriented Programming:面向切面编程)为内核。
提供了表现层 SpringMVC 和持久层 Spring JDBCTemplate 以及业务层事务管理等众多的企业级应用技术,还能整合开源世界众多著名的第三方框架和类库,逐渐成为使用最多的 Java EE 企业应用开源框架。
1.2 Spring 发展历程#
1997 年, IBM 提出了 EJB 的思想
1998 年,SUN 制定开发标准规范 EJB1.0
1999 年,EJB1.1 发布
2001 年,EJB2.0 发布
2003 年,EJB2.1 发布
2006 年,EJB3.0 发布
Rod Johnson 罗宾・约翰逊( Spring 之父)
Expert One-to-One J2EE Design and Development (2002) 阐述了 J2EE 使用 EJB 开发设计的优点及解决方案
Expert One-to-One J2EE Development without EJB (2004) 阐述了 J2EE 开发不使用 EJB 的解决方式(Spring 雏
形)
2021 年 7 月份发布了 Spring 的最新版本 Spring 5.3.9 通用版(正式发布的版本)
1.3 Spring 的优势 (理解)#
\1. 方便解耦,简化开发#
Spring 就是一个大工厂(IoC 容器),可以将所有对象的创建和依赖关系的维护工作都交给 Spring 容器管理,大大地降低了组件之间的耦合性。
\2. AOP 编程的支持#
通过 Spring 的 AOP 功能,方便进行面向切面编程,许多不容易用传统 OOP 实现的功能可以通过 AOP 轻松实现。
如 实现对程序进行权限拦截、运行监控等功能
\3. 声明式事务的支持#
可以将我们从单调烦闷的事务管理代码中解脱出来,通过声明式方式灵活的进行事务管理,提高开发效率和质量。
\4. 方便程序的测试#
Spring 对 Junit4 支持,可以通过注解方便的测试 Spring 程序,测试不再是昂贵的操作,而是随手可做的事情。
\5. 方便集成各种优秀框架#
Spring 不排斥各种优秀的开源框架,其内部提供了对各种优秀框架(如:Struts、Hibernate、MyBatis、Quartz 等)的直接支持。
\6. 降低 JavaEE API 的使用难度#
Spring 对 JavaEE 开发中非常难用的一些 API(JDBC、JavaMail、远程调用等),都提供了封装,使这些 API 应用难度大大降低。
\7. Java 源码是经典学习范例#
Spring 的源代码设计精妙、结构清晰、匠心独用,处处体现着大师对 Java 设计模式灵活运用以及对 Java 技术的高深造诣。它的源代码无意是 Java 技术的最佳实践的范例。
1.4 Spring 的体系结构(了解)#
2、Spring IoC 快速入门#
2.1 IoC 的概念和作用#
IoC:控制反转 (Inversion Of Control) ,就是应用本身不负责依赖对象的创建及维护,依赖对象的创建及维护是由外部容器负责的。这样控制权就由应用转移到了外部容器,控制权的转移就是所谓反转。
简单理解:把对象的创建、初始化、销毁等工作交给 spring 容器来做。由 spring 容器控制对象的生命周期。
明确 IoC 的作用:削减计算机程序的耦合 (解除我们代码中的依赖关系)。
原来:我们在获取对象时,都是采用 new 的方式。 是主动的。
现在:我们获取对象时,跟 spring 容器要,有 spring 为我们查找或者创建对象。 是被动的。
2.2 Spring IoC 程序开发步骤#
①导入 Spring 开发的基本包坐标
②编写 Dao 接口和实现类
③创建 Spring 核心配置文件
④在 Spring 配置文件中配置 UserDaoImpl
⑤使用 Spring 的 API 获得 Bean 实例
2.3 导入 Spring 开发的基本包坐标#
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring‐context</artifactId>
<version>5.2.8.RELEASE</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
</dependencies>
2.4 编写 Dao 接口和实现类#
package com.summer.dao;
public interface UserDao {
public void save();
}
package com.summer.dao.impl;
import com.summer.dao.UserDao;
public class UserDaoImpl implements UserDao {
public void save() {
System.out.println("用户添加~~~~~");
}
}
2.5 创建 Spring 核心配置文件#
在类路径 classpath 下(resources)创建 applicationContext.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">
</beans>
2.6 在 Spring 配置文件中配置 UserDaoImpl#
<?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">
<!‐‐ 实现IoC将对象的创建 交给spring容器
UserDao userDao = new UserDaoImpl();
‐‐>
<bean id="userDao" class="com.bailiban.dao.impl.UserDaoImpl"></bean>
</beans>
2.7 使用 Spring 的 API 获得 Bean 实例#
public class TestIoC{
public static void main(String[] args) {
// 创建spring容器实例
ApplicationContext context = new
ClassPathXmlApplicationContext("applicationContext.xml");
//从容器中获取 bean 根据 唯一标识id获取
UserDao userDao = (UserDao) context.getBean("userDao");
userDao.save();
}
}
在类路径下寻找配置文件来实例化容器
Spring 快速入门代码巩固练习
练习下通过 springIoC 的 XML 配置方式来进行对象的实例化
\1. 导入坐标
\2. 创建 Bean
\3. 创建配置文件 applicationContext.xml
\4. 在配置文件中进行配置
\5. 创建 ApplicationContext 对象 getBean
3、 Bean 的依赖注入入门#
① 编写 Dao,Service 接口和实现类
public interface UserDao {
public void save();
}
public class UserDaoImpl implements UserDao {
public void save() {
System.out.println("用户添加~~~~~");
}
}
public interface UserService {
public void save();
}
public class UserServiceImpl implements UserService {
public void save() {
//TODO
}
}
②将 UserDaoImpl 、 UserServiceImpl 的创建权交给 Spring
<
!‐‐ spring IoC 将对象的创建权交给spring‐‐>
<bean id="userDao" class="com.bailiban.dao.impl.UserDaoImpl"></bean>
<bean id="userService" class="com.bailiban.service.impl.UserServiceImpl"></bean>
UserService 内部再调用 UserDao 的 save () 方法
public class UserServiceImpl implements UserService {
public void save() {
//创建spring容器实例
ApplicationContext context = new ClassPathXmlApplicationContext();
//根据id获取dao对象
UserDao userDao = (UserDao) context.getBean("userDao");
//调用方法
userDao.save();
}
}
③从 Spring 容器中获得 UserService 进行操作
public class TestDI {
//测试 DI快速入门
@Test
public void test1() {
//创建spring容器实例
ApplicationContext context = new
ClassPathXmlApplicationContext("applicationContext.xml");
//根据id获取dao对象
UserService userService = (UserService) context.getBean("userService");
//调用方法
userService.save();
}
}
3.1 Bean 的依赖注入分析#
目前 UserService 实例和 UserDao 实例都存在与 Spring 容器中,当前的做法是在容器外部获得 UserService 实例和 UserDao 实例,然后在程序中进行结合。
因为 UserService 和 UserDao 都在 Spring 容器中,而最终程序直接使用的是 UserService,所以可以在 Spring 容器中,将 UserDao 设置到 UserService 内部。
3.2 Bean 的依赖注入概念#
DI : Dependency Injection 依赖注入,需要有 IoC 的环境,Spring 创建对象的过程中,Spring 将对象依赖的属性注入到对象。
在编写程序时,通过控制反转,把对象的创建交给了 Spring,但是代码中不可能出现没有依赖的情况。
IoC 解耦只是降低他们的依赖关系,但不会消除。例如:业务层仍会调用持久层的方法。
那这种业务层和持久层的依赖关系,在使用 Spring 之后,就让 Spring 来维护了。
简单的说,就是坐等框架把持久层对象传入业务层,而不用我们自己去获取。
3.3 Bean 的依赖注入方式#
怎么将 UserDao 怎样注入到 UserService 内部呢?
3.3.2 set 方法#
在 UserServiceImpl 中添加 setUserDao 方法
public class UserServiceImpl implements UserService {
// 定义dao成员变量
private UserDao userDao;
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
public void save() {
// //创建spring容器实例
// ApplicationContext context = new
ClassPathXmlApplicationContext("applicationContext.xml");
// //根据id获取dao对象
// UserDao userDao = (UserDao) context.getBean("userDao");
// //调用方法
userDao.save();
}
}
配置 Spring 容器调用 set 方法进行注入
<bean id="userDao" class="com.bailiban.dao.impl.UserDaoImpl"></bean>
<bean id="userService" class="com.bailiban.service.impl.UserServiceImpl">
<!‐‐使用set方法注入
name: set方法去掉set后 首字母小写
‐‐>
<property name="userDao" ref="userDao"></property>
</bean>
set 方法
命名空间注入P 命名空间注入本质也是 set 方法注入,但比起上述的 set 方法注入更加方便,主要体现在配置文件中,如下:
首先,需要引入 P 命名空间:
xmlns:p="http://www.springframework.org/schema/p"
其次,需要修改注入方式
<bean id="userService" class="com.bailiban.service.impl.UserServiceImpl" p:userDao‐
ref="userDao">
3.4 Bean 的依赖注入的数据类型#
上面的操作,都是注入的引用 Bean,除了对象的引用可以注入,普通数据类型 等都可以在容器中进行注入。
注入数据的二种数据类型
1. 普通数据类型
2. 引用数据类型
其中引用数据类型,此处就不再赘述了,之前的操作都是对 UserDao 对象的引用进行注入的,下面将以 set 方法注入为例,演示普通数据类型的注入。
Bean 的依赖注入的数据类型
(1)普通数据类型的注入
练习:
public class UserDaoImpl implements UserDao {
//普通数据类型的注入
private String name;
private int age;
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
public void save() {
System.out.println(name+"‐‐‐"+age);
System.out.println("用户添加~~~~~");
}
}
<bean id="userDao" class="com.bailiban.dao.impl.UserDaoImpl">
<!‐‐ 普通数据的注入 ‐‐>
<property name="name" value="旺财"></property>
<property name="age" value="18"></property>
</bean>