学习Spring知识之前,A类中需要使用到B类的对象,我们会怎么办呢?
当A类需要使用到B类的资源的话,会直接在A类中创建B类的对象
学习Spring知识之后,A类中需要使用到B类的对象,我们会怎么办呢?
当A类需要使用到B类的资源的话,IOC/DI容器会先去获得B类的实例(①)
IOC/DI容器再将B类的实例注入到A类中(②)
我们已经看到了容器存在的意义,就是先将程序内所有会使用到的资源全部获取到,谁需要就再给谁!
这里又提到了IOC和DI,那么二者之间又有什么区别呢?
什么是IOC?
IOC(Inversion Of Control):控制反转,意思就是将获取资源的权利由应用程序转变为了Spring容器
什么是DI?
DI( Dependency Injection):依赖注入,意思就是Spring容器获取资源并将资源注入到应用程序中
二者的区别
二者是对同一件事情的不同描述,只是描述时所站的角度不同罢了
下面会介绍下依赖注入的几种类型!
一.案例展示
1.测试准备
项目工程
2.代码展示
***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.howie</groupId>
<artifactId>springIOC_injection</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<!--导入Spring-context的jar包-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.0.2.RELEASE</version>
</dependency>
</dependencies>
</project>
***ComplexTypeInject.java
package com.howie.pojo;
import java.util.*;
/**
* @Author weihuanwen
* @Date 2019/8/14 23:49
* @Version 1.0
*/
public class ComplexTypeInject {
private String[] myStrs;
private List<String> myList;
private Set<String> mySet;
private Map<String,String> myMap;
private Properties myProps;
public String[] getMyStrs() {
return myStrs;
}
public void setMyStrs(String[] myStrs) {
this.myStrs = myStrs;
}
public List<String> getMyList() {
return myList;
}
public void setMyList(List<String> myList) {
this.myList = myList;
}
public Set<String> getMySet() {
return mySet;
}
public void setMySet(Set<String> mySet) {
this.mySet = mySet;
}
public Map<String, String> getMyMap() {
return myMap;
}
public void setMyMap(Map<String, String> myMap) {
this.myMap = myMap;
}
public Properties getMyProps() {
return myProps;
}
public void setMyProps(Properties myProps) {
this.myProps = myProps;
}
@Override
public String toString() {
return "ComplexTypeInject{" +
"myStrs=" + Arrays.toString(myStrs) +
", myList=" + myList +
", mySet=" + mySet +
", myMap=" + myMap +
", myProps=" + myProps +
'}';
}
}
***UserByConstructorInject.java
package com.howie.pojo;
/**
* @Author weihuanwen
* @Date 2019/8/14 23:48
* @Version 1.0
*/
public class UserByConstructorInject {
private String name;
private Integer age;
public UserByConstructorInject(String name, Integer age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "UserByConstructorInject{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
***UserBySetInject.java
package com.howie.pojo;
/**
* @Author weihuanwen
* @Date 2019/8/14 23:45
* @Version 1.0
*/
public class UserBySetInject {
private String name;
private Integer age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "UserBySetInject{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
***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">
<!--通过实体类的setter方法实现属性值注入-->
<bean id="UserBySetInject" class="com.howie.pojo.UserBySetInject">
<!--使用property标签完成实体类的set()操作-->
<property name="name" value="Jhon" />
<property name="age" value="28" />
</bean>
<!--通过构造方法实现属性值注入-->
<bean id="UserByConstructorInject" class="com.howie.pojo.UserByConstructorInject">
<!--使用constructor标签完成实体类构造方法属性注入-->
<constructor-arg name="name" value="Lily" />
<constructor-arg name="age" value="30" />
</bean>
<!--实现复杂类型注入的配置-->
<bean id="ComplexTypeInject" class="com.howie.pojo.ComplexTypeInject">
<!--String[] myStrs-->
<property name="myStrs">
<array>
<value>孙悟空</value>
<value>菩提祖</value>
<value>红孩儿</value>
</array>
</property>
<!--List<String> myList;-->
<property name="myList">
<list>
<value>浮夸</value>
<value>十年</value>
<value>背包</value>
</list>
</property>
<!--Set<String> mySet;-->
<property name="mySet">
<set>
<value>若需</value>
<value>若即</value>
<value>若离</value>
</set>
</property>
<!--Map<String,String> myMap;-->
<property name="myMap">
<map>
<entry key="天" value="地" />
<entry key="雨" value="风" />
<entry key="大陆" value="长空" />
</map>
</property>
<!--Properties myProps;-->
<property name="myProps">
<props>
<prop key="1">未来</prop>
<prop key="2">现在</prop>
</props>
</property>
</bean>
</beans>
***MyTest.java
package com.howie;
import com.howie.pojo.ComplexTypeInject;
import com.howie.pojo.UserByConstructorInject;
import com.howie.pojo.UserBySetInject;
import org.junit.Before;
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* @Author weihuanwen
* @Date 2019/8/14 23:52
* @Version 1.0
*/
public class MyTest {
private ClassPathXmlApplicationContext cpxax;
@Before
public void execBefore(){
cpxax = new ClassPathXmlApplicationContext("ApplicationContext.xml");
}
@Test
public void testSetInject(){
UserBySetInject user = cpxax.getBean("UserBySetInject", UserBySetInject.class);
System.out.println(user);
}
@Test
public void testConstructorInject(){
UserByConstructorInject user = cpxax.getBean("UserByConstructorInject", UserByConstructorInject.class);
System.out.println(user);
}
@Test
public void testComplexInject(){
ComplexTypeInject cti = cpxax.getBean("ComplexTypeInject", ComplexTypeInject.class);
System.out.println(cti);
}
}
3.测试
①执行testSetInject()控制台输出
UserBySetInject{name='Jhon', age=28}
②执行testConstructorInject()控制台输出
UserByConstructorInject{name='Lily', age=30}
③执行testComplexInject()控制台输出
ComplexTypeInject{myStrs=[孙悟空, 菩提祖, 红孩儿], myList=[浮夸, 十年, 背包], mySet=[若需, 若即, 若离], myMap={天=地, 雨=风, 大陆=长空}, myProps={2=现在, 1=未来}}
二.总结
1.通过上面的案例,可以了解到如何实现下面的注入
- set注入
- 构造注入
- 复杂类型注入
2.为什么要是用Spring呢?
在一个大型的应用程序中必然包含很多的组件,组件之间互相调用,但是在运行时并非所有的组件都必须创建.在没有Spring技术之前,A组件需要调用B组件时,就需要采取new或者getInstance的方式获取B组件的实例,这样就产生了组件A同组件B之间的耦合.随着工程规模的扩大, N多组件间的耦合度越来越高,后期维护成本相当高.为了减少这种耦合,Spring诞生了!
Spring框架基于BeanFactory,将模块的配置信息(模块根据需求创建)同模块的配置参数(模块不必读取参数,Spring统一加载)统一管理.加入依赖注入(DI),Spring负责将模块依赖度的其他模块(push)推送进来,而不是自己去拉取(pull),所以是一个"控制反转"(IOC)