Spring之IoC(依赖注入、控制反转)

原创 2020-05-19 09:25

Spring 是分层的 Java SE/EE 应用 full-stack 轻量级开源框架,以 IoC(Inverse Of Control:
反转控制)和 AOP(Aspect Oriented Programming:面向切面编程)为内核。

Spring概述

一、Spring是什么?

Spring 是分层的 Java SE/EE 应用 full-stack 轻量级开源框架,以 IoC(Inverse Of Control:
反转控制)和 AOP(Aspect Oriented Programming:面向切面编程)为内核,提供了展现层 Spring
MVC 和持久层 Spring JDBC 以及业务层事务管理等众多的企业级应用技术,还能整合开源世界众多
著名的第三方框架和类库,逐渐成为使用最多的 Java EE 企业应用开源框架。

二、Spring的优势?

方便解耦,简单开发

通过 Spring 提供的 IoC 容器,可以将对象间的依赖关系交由 Spring 进行控制,避免硬编码所造成的过度程序耦合。用户也不必再为单例模式类、属性文件解析等这些很底层的需求编写代码,可以更专注于上层的应用。

AOP编程的支持

通过Spring的AOP功能,方便进行切面编程,许多传统的oop实现的功能可以通过AOP轻松应对。

方便程序测试

可以用非容器依赖的编程方式进行几乎所有的测试工作,测试不再是昂贵的操作,而是随手可做的事情。

方便集成各种优秀框架

Spring 可以降低各种框架的使用难度,提供了对各种优秀框架(Struts、Hibernate、Hessian、Quartz等)的直接支持。

三、Spring的体系结构

spring

IoC依赖注入

IoC就是来解决程序之间的依赖关系,减少程序的耦合。Java程序解耦合(点击查看)

一、项目构建

使用Spring-IoC,首先要进行Spring的jar导入,创建Maven项目后首先要在pom.xml导入spring-context jar包。

1
2
3
4
5
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.1.2.RELEASE</version>
</dependency>

二、spring中工厂的类结构图

1、spring中工厂的类图结构


2、BeanFactory 和 ApplicationContext 的区别

  1. BeanFactory才是Spring容器中的顶层接口。
  2. ApplicationContext是它的子接口。BeanFactory和
  3. ApplicationContext的区别:创建对象的时间点不一样。
  4. ApplicationContext:只要一读取配置文件,默认情况下就会创建对象。
  5. BeanFactory:什么使用什么时候创建对象。

3、ApplicationContext 接口的实现类

  1. ClassPathXmlApplicationContext:它是从类的根路径下加载配置文件推荐使用这种
  2. FileSystemXmlApplicationContext:它是从磁盘路径上加载配置文件,配置文件可以在磁盘的任意位置。
  3. AnnotationConfigApplicationContext:当我们使用注解配置容器对象时,需要使用此类来创建spring容器。它用来读取注解。

三、用XML配置文件进行依赖注入

依赖注入:Dependency Injection。它是 spring 框架核心 ioc 的具体实现。
我们的程序在编写时,通过控制反转,把对象的创建交给了 spring,但是代码中不可能出现没有依赖的情况。
ioc 解耦只是降低他们的依赖关系,但不会消除。例如:我们的业务层仍会调用持久层的方法。
那这种业务层和持久层的依赖关系,在使用 spring 之后,就让 spring 来维护了。
简单的说,就是坐等框架把持久层对象传入业务层,而不用我们自己去获取。

四、构造函数注入

就是使用类中的构造函数,给成员变量赋值。注意,赋值的操作不是我们自己做的,而是通过配置的方式,让spring框架来为我们注入。
StudentBean

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
package Bean;

import java.util.Date;

public class Student {
/**
* sid : 001
* sname : xiaoming
* sex : 男
*/
private int sid;
private String sname;
private String sex;
private Date birthday;
// 构造函数
public Student(int sid, String sname, String sex, Date birthday) {


this.sid = sid;
this.sname = sname;
this.sex = sex;
this.birthday = birthday;
}
// toString()方法
@Override
public String toString() {
return "Student{" +
"sid=" + sid +
", sname='" + sname + '\'' +
", sex='" + sex + '\'' +
", birthday=" + birthday +
'}';
}

}
~~
配置文件代码:
~~~xml
<!--构造函数注入:
使用的标签:constructor-arg
标签出现的位置:bean标签的内部
标签中的属性
type:用于指定要注入的数据的数据类型,该数据类型也是构造函数中某个或某些参数的类型
index:用于指定要注入的数据给构造函数中指定索引位置的参数赋值。索引的位置是从0开始
name:用于指定给构造函数中指定名称的参数赋值 常用的
=============以上三个用于指定给构造函数中哪个参数赋值===============================
value:用于提供基本类型和String类型的数据
ref:用于指定其他的bean类型数据。它指的就是在spring的Ioc核心容器中出现过的bean对象

优势:
在获取bean对象时,注入数据是必须的操作,否则对象无法创建成功。
弊端:
改变了bean对象的实例化方式,使我们在创建对象时,如果用不到这些数据,也必须提供。
-->

<!--Student-Bean配置 -->
<bean id="student" class="Bean.Student">
<constructor-arg name="sid" value="001"></constructor-arg>
<constructor-arg name="sname" value="zhangsan"></constructor-arg>
<constructor-arg name="sex" value="男"></constructor-arg>
<constructor-arg name="birthday" ref="now"></constructor-arg>
</bean>
<!-- Date birthday -->
<bean id="now" class="java.util.Date"></bean>

Test测试

1
2
3
4
5
6
7
8
9
10
11
public static void main(String[] args) {

// 获取核心容器对象
ApplicationContext student = new ClassPathXmlApplicationContext("beans.xml");
// 获取student对象
Student student1 = (Student) student.getBean("student");
// 调用tostring方法
String S=student1.toString();
// 打印
System.out.println(S);
}

五、Set方法注入

Techer.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
public class Teacher {
/**
* tid : 3333
* tname : 张三
* tsex : 男
*/

private int tid;
private String tname;
private String tsex;

@Override
public String toString() {
return "Teacher{"+"id="+this.tid+"naem"+this.tname+"sex"+this.tsex+"}";
}
// set方法
public void setTid(int tid) {
this.tid = tid;
}
public void setTname(String tname) {
this.tname = tname;
}
public void setTsex(String tsex) {
this.tsex = tsex;
}
}

XML配置文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
 <!-- set方法注入                更常用的方式
涉及的标签:property
出现的位置:bean标签的内部
标签的属性
name:用于指定注入时所调用的set方法名称
value:用于提供基本类型和String类型的数据
ref:用于指定其他的bean类型数据。它指的就是在spring的Ioc核心容器中出现过的bean对象
优势:
创建对象时没有明确的限制,可以直接使用默认构造函数
弊端:
如果有某个成员必须有值,则获取对象是有可能set方法没有执行。-->
<!-- set注入 -->
<bean id="teacher" class="Bean.Teacher">
<property name="tid" value="001"></property>
<property name="tname" value="李四"></property>
<property name="tsex" value="男"></property>
</bean>

调用打印

1
2
3
4
5
6
public static void main(String[] args) {
ApplicationContext teacher= new ClassPathXmlApplicationContext("beans.xml");
Teacher teacher1 = (Teacher) teacher.getBean("teacher");
String T = teacher1.toString();
System.out.println(T);
}

六、注入集合属性

就是给类中的集合成员传值,它用的也是set方法注入的方式,只不过变量的数据类型都是集合。我们这里介绍注入数组,List,Set,Map,Properties。
bean

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
public class Testfuhe {
private String [] myStrs;
private List<String> lists;
private Set<String> sets;
private Map<String,Object> map;

public void setMap(Map<String, Object> map) {
this.map = map;
}

private Properties properties;

public void setMyStrs(String[] myStrs) {
this.myStrs = myStrs;
}

public void setLists(List<String> lists) {
this.lists = lists;
}

public void setSets(Set<String> sets) {
this.sets = sets;
}

public void setProperties(Properties properties) {
this.properties = properties;
}
public void show(){
System.out.println(myStrs.toString());
System.out.println(lists);
System.out.println(sets);
System.out.println(properties);
}
}

XML文件进行赋值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
<!-- 复杂类型的注入/集合类型的注入
用于给List结构集合注入的标签:
list array set
用于个Map结构集合注入的标签:
map props
结构相同,标签可以互换
-->
<!-- 复杂数据类型复制-->
<bean id="testfuhe" class="Bean.Testfuhe">
<property name="myStrs">
<array>
<value>array1</value>
<value>array2</value>
<value>array3</value>
</array>
</property>
<property name="lists">
<list>
<value>lsit1</value>
<value>list2</value>
<value>list3</value>
</list>
</property>
<property name="sets">
<set>
<value>sets1</value>
<value>sets2</value>
<value>sets3</value>
</set>
</property>
<property name="map">
<map >
<entry key="naem" value="xiaoming"></entry>
<entry key="sex" value="nan"></entry>

</map>
</property>
<property name="properties">
<props>
<prop key="prop1">bean.xml</prop>
</props>
</property>
</bean>
能力有限,若有疏漏,或总结有误,欢迎指教!

评论

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×