08.SSM框架集~Spring(一)IOC/DI
本文是上一篇文章的后续,详情点击该链接
本章资料 提取码:cpss
关于Spring,我们在第一篇文章的时候,就已经有了介绍,可以回顾一下。 文章链接
Spring
环境搭建:
关于版本. 在spring3之前, spring只提供一个jar, spring.jar; 从spring3之后, 官方对spring做了拆分, 分成了多个jar包(spring-aop, spring-beans, spring-context, spring-expression, spring-core, spring-jdbc, spring-tx, spring-web, spring-webmvc, ...).
Jar包和源码的下载地址(文章最上方也有本人下载好的)
https://github.com/spring-projects/spring-framework/tags
https://repo.spring.io/libs-release-local/org/springframework/spring/
介绍Spring Framework Runtime
Test:
spring-test.jar. Spring提供的测试工具, 可以整合JUnit测试, 简化测试环节.
Core Container
Spring的核心组件, 包含了Spring框架最基本的支撑
Beans, 对应spring-beans.jar. Spring进行对象管理时依赖的jar包
Core, 对应spring-core.jar, Spring核心jar包
Context, 对应spring-context.jar, Spring容器上下文对象
SpEL, 对应spring-expression.jar, Spring表达式语言
AOP
面向切面编程, 对应spring-aop.jar
Data Access
Spring对数据访问层的封装
JDBC, 对应spring-jdbc.jar. Spring对jdbc的封装, 当需要使用spring连接数据库时使用. spring-jdbc.jar需要依赖spring-tx.jar
Transactions, 对应spring-tx.jar. 事务管理
ORM, 对应spring-orm.jar. spring整合第三方orm框架需要使用的jar包, 例如Hibernate框架
Web
Spring对javax下的接口或类做的扩展功能
spring-web.jar, 对Servlet, filter, Listener等做的增强
spring-webmvc.jar, 实际上就是SpringMVC框架. 需要依赖spring环境和spring-web.jar
Spring中的IOC
IOC的使用:
我们使用MVC进行开发的时候,数据在各层之间进行传递,数据在业务上构成一个链条,这个链条称之为责任链
基于责任链开发模式,我们发现代码层和层之间相互调用,造成了层和层的耦合性太高,并且后期的扩展性太低,我们写代码的时候讲究的原则———低耦合,高内聚。
解决方案:
Spring IOC,
基本使用流程:
创建Maven的war项目然后配置web的相关依赖以及项目结构的配置
配置pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.alvin</groupId>
<artifactId>SpringCreate</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<dependencies>
<!-- IOC依赖坐标 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.6.RELEASE</version>
</dependency>
<!-- 日志坐标 -->
<!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-log4j12 -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.25</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
如果仓库里面没有你要导入的jar包,那么点击import就会自动下载
在pom.xml文件中配置SpringIOC的依赖
使用Spring运行第一个程序
创建Service和Controller,以及配置文件applicationContext.xml
Service接口和实现类
public interface AdminService {
//查询用户信息
void FindAll();
}
public class AdminServiceImpl implements AdminService {
private String name;
public AdminServiceImpl(String name){
this.name = name;
}
public AdminServiceImpl(){
System.out.println("构造方法已实现~");
}
public void FindAll() {
System.out.println("查询结果: " + name);
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "AdminServiceImpl{" +
"name='" + name + '\'' +
'}';
}
}
配置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>
<bean id="adminService" class="com.alvin.service.impl.AdminServiceImpl"></bean>
</beans>
</beans>
Controller调用
public class AdminServlet {
public static void main(String[] args) {
//解析applicationContext.xml文件
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
//获得已经创建好的对象
AdminService adminService = applicationContext.getBean("adminService",AdminService.class);
//调用
adminService.FindAll();
}
}
Spring IOC创建对象的三种方式
构造器方式
有参构造
无参构造
刚刚上述方法用的则是无参构造,我们现在就来试试有参构造吧!
有参构造方法
applicationContext:
<!--有参数的构造器
特点:Spring容器对根据配置调用的有参构造器创建一个带有初始化数据的对象
使用:constructor-arg:使用bean的字标签来声明调用的构造器的形参的个数
一个字标签表示一个参数
属性:index:参数的下标
type:参数的类型,全限定路径
name:参数的形参名
value:参数要给的值-->
<beans>
<bean id="adminService2" class="com.alvin.service.impl.AdminServiceImpl">
<constructor-arg index="0" type="java.lang.String" name="name" value="小明"/>
</bean>
</beans>
工厂模式
pom.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">
<bean class="com.alvin.factroy.Factory" id="factory" factory-method="getInstance">
<constructor-arg name="param" value="stu"></constructor-arg>
</bean>
</beans>
public class Test2 {
public static void main(String[] args) {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContextFactory.xml");
Factory student = applicationContext.getBean("factory",Factory.class);
}
}
class Factory {
public People getInstance(String param){
if("student".equals(param)){
return new Student();
}else if("teacher".equals(param)){
return new Teacher();
}
return null;
}
}
interface People {
void Run();
}
class Teacher implements People{
@Override
public void Run() {
System.out.println("老师跑");
}
}
class Student implements People{
@Override
public void Run() {
System.out.println("学生跑");
}
}
Spring中的DI
作用:给创建好的对象中的全局的属性或者对象进行赋值操作
英文全称(Dependency Injection)
中文名称:依赖注入
依赖:一个类在另一个类中作为全局属性时
注入:通过外部给自己属性(或其他内容)进行赋值
类与类之间的关系:
继承(官方名称:泛化)
实现
依赖:类和类之间的关系是偶然的,临时的.在代码层面另一个类当作这个类的方法参数或局部变量
关联:类与类之间存在一定联系,可以是单向联系可以是双向联系.例如:学生和老师. (平时理解关联是一种强依赖),体现在代码层面,另一个类是这个类的全局属性.
聚合:类与类之间是可以单独存在的.但是有存在整体和部分的关系.例如:机箱和CPU.体现在代码层面:另一个类是这个类的全局属性.
组合:类与类之间是整体和部分之间的部分,不可分.例如人和心脏.体现在代码层面:另一个类是这个类的全局属性.
关系强度:组合 > 聚合 > 关联 > 依赖
DI的意义:
解除类与类之间高耦合性.
为什么称DI和IOC是同一个事情.
Spring帮助创建对象的过程叫做IOC,创建对象时给对象中全局对象赋值叫做DI,所以认为IOC和DI是同一个事情.
DI注入的方式:
使用set方法
使用有参构造器
自动注入
使用有参构造器
创建班级类和学生类
public class Student {
private String name;
private String sex;
private int age;
private Clazz clazz;
}
public class Clazz {
private int clazzno;
private String cname;
}
//自行添加get,set
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">
<!-- 有参构造方式进行注入 -->
<bean id="cla" class="spring.alvin.student.Clazz">
<constructor-arg name="cname" value="javaSE"></constructor-arg>
<constructor-arg name="clazzno" value="507"></constructor-arg>
</bean>
<bean id="stu" class="spring.alvin.student.Student">
<constructor-arg name="age" value="18"></constructor-arg>
<constructor-arg name="name" value="张三"></constructor-arg>
<constructor-arg name="sex" value="男"></constructor-arg>
<!-- 将上面创建好的cla引入到下面 -->
<constructor-arg name="clazz" ref="cla"></constructor-arg>
</bean>
</beans>
Test操作
public class Test {
public static void main(String[] args) {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
Student student = applicationContext.getBean("stu",Student.class);
System.out.println(student);
}
}
使用set方法
<bean id="stu" class="spring.alvin.student.Student">
<property name="name" value="李四"></property>
<property name="sex" value="男"></property>
<property name="age" value="20"></property>
<property name="clazz" ref="cla"></property>
</bean>
看起来好像差不多,实际上前者是用构造器,后者是用set
value和ref的使用场景:
value: 如果注入的属性类型是基本数据类型(包含String)使用value
ref: 如果注入的属性类型是对象,这个时候使用ref
使用自动注入:
底层走的是Set方法;
byName: 这个时候就会在当前的XML中寻找bean的id名称和需要注入的属性名一致进行匹配。
案例:
<!-- 有参构造方式进行注入 -->
<bean id="clazz" class="spring.alvin.student.Clazz">
<constructor-arg name="cname" value="javaSE"></constructor-arg>
<constructor-arg name="clazzno" value="507"></constructor-arg>
</bean>
<bean id="stu" class="spring.alvin.student.Student" autowire="byName"></bean>
此时id = clazz是存在的对象,所以可以找到。如果不存在,就无法找到
byType: 这个时候就会在当前xml中寻找[bean标签的类型]和需要注入实体中的[属性名]一致,进行匹配注入
<bean id="stu" class="spring.alvin.student.Student" autowire="byType"></bean>
constructor: 这个时候首先会根据名称进行查找,如果名称没有一致再根据类型进行查找。 {底层走的是构造器}
<bean id="stu" class="spring.alvin.student.Student" autowire="constructor"></bean>
注意: 必须要有有参构造器才能执行!
DI其他类型值的注入:
数组,List,Set,Map
User类
public class User {
private String[]arr;
private List<String> li;
private Set<String> set;
private Map<String,String>map;
}
//get set自行添加
给数组,List,Set,Map添加
<bean id="us" class="spring.alvin.student.User">
<!-- 数组 -->
<property name="arr">
<array>
<value>A</value>
<value>B</value>
<value>C</value>
</array>
</property>
<!-- list -->
<property name="li">
<list>
<value>D</value>
<value>E</value>
<value>F</value>
</list>
</property>
<!-- Set -->
<property name="set">
<set>
<value>G</value>
<value>H</value>
<value>I</value>
</set>
</property>
<!-- Map -->
<property name="map">
<map>
<entry>
<key><value>1</value></key>
<value>小明</value>
</entry>
<entry>
<key><value>2</value></key>
<value>小海</value>
</entry>
</map>
</property>
</bean>