06ssm_Spring初识Spring框架
目录
一 、Spring介绍
概述
Java SE/EE一站式(full-stack)轻量级开源框架
它最为核心的理念是IoC(控制反转)和AOP(面向切面编程)
IoC支撑着Spring对JavaBean的管理功能,AOP可以在不修改源代码的情况下,为给程序统一添加 功能
基于MVC结构中,Spring在各层的作用
在表现层它提供了Spring MVC框架,并且Spring还可以与Struts框架整合。在业务逻辑层可以管理事务、记录日志等。
在持久层可以整合MyBatis、Hibernate、JdbcTemplate等技术。
优点
Spring作为Java EE的一个全方位应用程序框架,为开发企业级应用提供了一个健壮、高效的解决方案。有如下优点:
**非侵入式设计:**Spring框架的API不会在业务逻辑上出现,即:业务逻辑代码不依赖Spring框架, 可以从该框架快速地移植到其他框架
**降低耦合性:**所有对象的创建和依赖关系的维护都交给Spring容器管理,大大降低了组件之间的耦合性。
**支持AOP编程:**通过AOP将通用任务集中处理切入需要的地方(如:日志),以减少传统OOP方法带来的代码冗余和繁杂。
**支持声明式事务:**直接通过Spring配置文件管理数据库事务,省去了手动编程的繁琐,提高了开发效率。
**方便程序的测试:**Spring提供了对Junit的支持。
**方便集成框架:**Spring是一个基础平台,内部提供了对各种框架的直接支持,如Struts、MyBatis
等优秀框架可以与Spring无缝集成。
降低Java EE API的使用难度:Spring对Java EE开发中的一些API(如JDBC、JavaMail等)都进行了封装,大大降低了这些API的使用难度。
体系结构
- Spring 5的新特性
更新JDK基线:Spring 5代码库运行于JDK 8之上。
修订核心框架:比如,@Nullable和@NotNull注解来表明可为空的参数以及返回值,可以在编译时处理空值而不是在运行时抛出NullPointerExceptions异常。
更新核心容器支持响应式编程
支持函数式Web框架支持Kotlin
提升测试功能
Spring的下载及目录结构
使用Spring之前需要获取它的jar包,并在项目中导入
下载地址:https://repo.spring.io/ui/native/libs-release/org/springframework/spring/
下载版本:5.3.12版本,下载spring-5.3.12-dist.zip文件。
特别提示:Spring的核心容器还需要依赖commons.logging的jar包
下载地址: https://commons.apache.org/proper/commons-logging/download_logging.cgi
Spring目录结构说明
**docs文件夹:**该文件夹下存放Spring的相关文档,包括开发指南、API参考文档。
**libs文件夹:**该文件夹下存放开发所需的jar包和源码。Spring框架由21个模块组成,libs目录 下Spring为每个模块都提供了三个压缩包,该目录下一共有63个jar包。
**schema文件夹:**该文件夹下存放Spring各种配置文件的XML Schema文档。
二 、Spring入门程序
实验环境准备
下载springframework
下载地址:https://repo.spring.io/ui/native/libs-release/org/springframework/spring/
下载版本:5.3.12版本,下载spring-5.3.12-dist.zip文件。
- 下载Spring的核心容器依赖jar包:commons.logging
下载地址:https://commons.apache.org/proper/commons-logging/download_logging.cgi
创建项目及模块
第一步:创建项目ssm_spring,并在此项目下创建lib目录,将下载的JAR包按下图要求复制到lib中。
第二步:设置项目的Libraries
第三步:在ssm_spring项目下建spring-chap06-introduce模块,目录结构如下:
第四步:为项目的模块添加依赖,依赖为第二步中的lib
2.入门程序
在上述环境搭建的基础上,按下述步骤完成。
-
创建com.introduce包
-
创建HelloSpring类**(放com.introduce包中)**
package com.introduce;
public class HelloSpring { private String userName;
public void setUserName(String userName) { this.userName = userName;
}
public void show(){
System.out.println(userName+",欢迎来到Spring...");
}
}
- 创建在spring的配置文件spring-config.xml**(放resources目录中)**
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns=["http://www.springframework.org/schema/beans](http://www.springframework.org/schema/beans)" xmlns:xsi="[http://www.w3.org/2001/XMLSchema-instance](http://www.w3.org/2001/XMLSchema-instance)" xsi:schemaLocation="[http://www.springframework.org/schema/beans](http://www.springframework.org/schema/beans) https://[www.springframework.org/schema/beans/spring-beans.xsd](http://www.springframework.org/schema/beans/spring-beans.xsd)">
<!--配置bean-->
</beans>
说明:
配置文件中<beans>根元素怎么写,要看所在项目依赖的spring框架版本的使用文档! 课堂笔记中的所有spring案例,均是以5.3.12版为基准去写的<beans>根元素。
- 在spring-config.xml中配置HelloSpring的bean
<!–配置HelloSpring类的bean class:为类的全限定名
id:为实例名–>
<bean id="helloSpring" class="com.introduce.HelloSpring">
<!--为userName属性赋值-->
<property name="userName" value="小花"/>
</bean>
- 编写测试类TestHelloSpring**(放test下的java文件夹下)**
import com.introduce.HelloSpring;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class TestHelloSpring {
public static void main(String[] args) {
//初始化spring容器,加载spring的配置文件
ApplicationContext context = new ClassPathXmlApplicationContext("spring- config.xml");
//获取spring容器中的HelloSpring实例。getBean()中是bean的id,严格区分大小写HelloSpring bean = (HelloSpring)context.getBean("helloSpring");
//执行HelloSpring实例的方法bean.show();
}
}
运行结果如下图。
三 、控制反转与依赖注入
什么是控制反转(IoC)
传统面向对象编程中,对象由应用程序创建
控制反转(IoC)指对象由容器创建,对象的控制权由应用程序转向了容器
控制反转(IoC)机制中,当程序需要使用对象时,可以直接从IoC容器中获取控制反转降低了程序代码间的耦合度
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-u74I8BF1-1658489166581)(image/image_5_SQtiY4XYrG.jpeg)]
什么是依赖注入
依赖注入(DI)指由IoC容器在运行期间动态地将某种依赖资源注入对象之中,即:为对象动态设置属性值。例如,将对象B注入(赋值)给对象A的成员变量。
依赖注入基本思想:明确地定义组件接口,独立开发各个组件,然后根据组件的依赖关系组装运 行。
依赖注入的类型
依赖注入指使用Spring框架创建对象时,动态该对象所依赖其它对象注入到Bean组件中。通常有两种实现方式:构造方法注入、属性setter方法注入。
依赖注入本质即为Bean组件的各属性赋值。
- 构造方法注入
Spring容器调用构造方法注入被依赖的实例,前提是类要有相应构造方法的定义
一个**<constructor-arg>元素对应构造方法一个参数值的设置**,该元素有如下属性:
name属性:指定被注入实例的参数名。value属性:指定被注入实例的参数值。
ref属性:指定被注入实例参数值来源于所在容器的另外一bean。type属性:指定被注入实例的参数类型。此属性可以缺省不写!
index属性:指定被注入实例参数的序号。0表示第1个参数,依次类推。此属性与name属性二选一!!
构造方法有多少个参数,则必须有多少个<constructor-arg>元素
【示例】阅读代码,理解构造方法注入依赖的方法。首先,编写用户类User1**(放com.introduce包中)**
package com.introduce;
public class User1 { private int id; private String name;
private String password;
public User1(int id, String name, String password) { this.id = id;
this.name = name; this.password = password;
}
@Override
public String toString() { return "id=" + id +
", name='" + name + '\'' +
", password='" + password + '\'';
}
}
然后,在spring-config.xml配置文件中配置User1的Bean
<!--配置User1的bean-->
<bean id="user1" class="com.introduce.User1">
<!--构造方法注入各属性值。User1构造方法有3个参数,要用3个constructor-arg元素配置--
>
<constructor-arg name="id" value="1"/>
<constructor-arg name="name" value="admin"/>
<constructor-arg name="password" value="123456"/>
</bean>
思考:如果password参数不注入,会怎么样?
最后,编写测试案例
import com.introduce.User1;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class TestUser1 {
public static void main(String[] args) {
//获取容器
ApplicationContext context = new ClassPathXmlApplicationContext("spring- config.xml");
//获取容器
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
//从容器中获取对象
User1 bean = context.getBean(User1.class);
//输出bean的值System.out.println(bean);
}
}
运行结果如下图。
- 属性setter方法注入
Spring容器调用setter方法注入被依赖的实例,前提是类要有相应属性setter方法的定义
一个**<property>元素对应构造方法一个参数值的设置**。该元素属性如下: 只有name、value、ref属性,其含义与个<constructor-arg>元素相同
根据需要确定是否为各属性注入值
【示例】阅读代码,理解构造方法注入依赖的方法。首先,编写用户类User2**(放com.introduce包中)**
package com.introduce;
public class User2 { private int id; private String name;
private String password;
public void setId(int id) { this.id = id;
}
public void setName(String name) { this.name = name;
}
public void setPassword(String password) { this.password = password;
}
@Override
public String toString() { return “id=” + id +
“, name='” + name + ‘\’’ +
“, password='” + password + ‘\’';
}
}
然后,在spring-config.xml配置文件中配置User1的Bean
<!–配置User2的bean–>
<bean id=“user2” class=“com.introduce.User2”>
<!–setter注入各属性值–>
<property name=“id” value=“2”/>
<property name=“name” value=“张小小”/>
<property name=“password” value=“123456”/>
</bean>
思考:如果password参数不注入,会怎么样?
最后,编写测试案例
import com.introduce.User2;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class TestUser2 {
public static void main(String[] args) {
//获取容器
ApplicationContext context = new ClassPathXmlApplicationContext(“spring- config.xml”);
//从容器中获取对象
User2 bean = context.getBean(User2.class);
//输出bean的值System.out.println(bean);
}
}
运行结果如下图。
依赖注入的应用
需求描述
以setter方法注入为例,按MVC三层结构模式,模拟实现简单登录验证。
实现步骤
第一步,编写DAO层(数据持久层)
-
创建dao包**(放com.introduce包中)**
-
创建接口UserDao(放com.introduce.dao包中)
package com.introduce.dao;
public interface UserDao {
boolean login(String name,String password);
}
- 创建UserDaoImpl类,实现UserDao接口**(放com.introduce.dao包中)**
package com.introduce.dao;
public class UserDaoImpl implements UserDao{ @Override
public boolean login(String name, String password) { if(“张三”.equals(name) && “123”.equals(password)){
return true;
}else{
return false;
}
}
}
第二步,编写Service层(业务层)
-
创建service包**(放com.introduce包中)**
-
创建业务类接口UserService**(放com.introduce.service包中)**
package com.introduce.com.introduce.service;
public interface UserService {
boolean login(String name,String password);
}
(2)创建UserServiceImpl类,实现UserService接口**(放com.introduce.service包中)**
package com.introduce.com.introduce.service;
import com.introduce.dao.UserDao;
public class UserServiceImpl implements UserService { public UserDao userDao;
public void setUserDao(UserDao userDao) { this.userDao = userDao;
}
@Override
public boolean login(String name, String password) { return userDao.login(name,password);
}
}
第三步,在配置文件spring-config.xml中配置业务bean
注:因为UserService的bean依赖userDao的bean,因此要先配置userDao的bean。
<!–配置UserDao的bean–>
<bean id=“userDao” class=“com.introduce.dao.UserDaoImpl”/>
<!–配置UserService的bean–>
<bean id=“userService” class=“com.introduce.com.introduce.service.UserServiceImpl”>
<!–注入userDao–>
<property name=“userDao” ref=“userDao”/>
</bean>
第四步,编写测试类
import com.introduce.User2;
import com.introduce.com.introduce.service.UserService; import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class TestUserService {
public static void main(String[] args) {
//获取容器
ApplicationContext context = new ClassPathXmlApplicationContext(“spring- config.xml”);
//从容器中获取对象
UserService bean = context.getBean(UserService.class);
// 输 出 bean 的 值 if(bean.login(“小李”,“123”)){
System.out.println(“登录成功!”);
}else{
System.out.println(“登录失败!”);
}
}
}
运行结果如下图: