什么是IoC与DI
IoC(控制反转):抽象来说是一种思想,我们开发过程中所有的对象都可以交给Spring进行管理,我们直接获取即可,不需要自己动手创建,即对象管理权的反转。具体来说IoC在Spring中是一个容器,一个管理对象的容器。
DI(依赖注入):Spring创建对象过程中,对对象所依赖的属性进行赋值,这个步骤就是依赖注入。
基于XML配置文件的方式实现
1. 基本使用
1.1 添加依赖
创建Maven项目并添加Spring核心依赖
<dependencies>
<!-- Spring核心依赖 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.1.17.RELEASE</version>
</dependency>
<!-- 添加junit方便测试 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
</dependencies>
1.2 添加Spring配置文件
在resources目录下添加spring-config.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>
1.3 注册Bean
将需要被Spring管理的对象通过bean标签进行注册
<?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标签注册 -->
<bean id="userBean" class="com.wxw.pojo.UserBean" />
</beans>
1.4 获取Bean
创建测试类中Spring容器中获取已经注册的Bean
@Test
public void test01(){
// 加载IoC容器
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-config.xml");
// 从容器中获取Bean对象
UserBean userBean = applicationContext.getBean(UserBean.class);
System.out.println(userBean);
}
2. 获取Bean的方式
2.1 根据ID
ID只能声明一个
<?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.gupaoedu.pojo.UserBean" id="userBean"/>
</beans>
2.2 根据name
name可以声明多个,name=“u1,u2,u3” 表示会被拆分为3个name属性【拆分会根据 ‘,’ ‘;’ ’ ’ 空格 】
<?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.gupaoedu.pojo.UserBean" id="user1,user2,user3" name="u1,u2,u3"/>
</beans>
2.3 根据类型
通过类型获取时,如果容器中该类型有多个对象,则会报错。有两种解决方式:
- 通过组合条件获取
@Test
public void fun6(){
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
// UserBean bean = ac.getBean(UserBean.class);
UserBean bean = ac.getBean("u1",UserBean.class);
bean.say();
}
- 通过设置primary属性,优先获取primary属性为true的对象。
3. 注入方式(DI)
3.1 构造注入
通过构造方法注入,首先得提供对应的构造方法,既可以通过name 也可以通过index 来指定要赋值的参数。
<?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.gupaoedu.pojo.UserBean" id="user">
<!-- 构造注入 -->
<!-- name
<constructor-arg name="id" value="666"/>
<constructor-arg name="userName" value="bobo"/>
-->
<!-- index -->
<constructor-arg index="0" value="999" />
<constructor-arg index="1" value="gp" />
</bean>
</beans>
3.2 设值注入
设值注入的属性必须提供对应的setter方法
<bean class="com.gupaoedu.pojo.UserBean" id="user1">
<!-- 设值注入 -->
<property name="id" value="1"/>
<property name="userName" value="张三"/>
</bean>
3.2.1 不同类型的设值注入
// 对象
private Cat cat;
// 数组
private String[] favorites;
// List集合
private List<Cat> cats;
// Map集合
private Map<String,Object> map;
// 配置文件
private Properties props;
<?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">
<!-- 注册一个Cat对象-->
<bean class="com.gupaoedu.pojo.Cat" id="cat" p:nick="花花" p:color="黑色"/>
<bean class="com.gupaoedu.pojo.UserBean" id="user">
<!-- 对象注入 -->
<property name="cat" ref="cat">
<!--<bean class="com.gupaoedu.pojo.Cat" />-->
</property>
<!-- 数组注入 -->
<property name="favorites">
<array>
<value>篮球</value>
<value>爬山</value>
<value>逛街</value>
</array>
</property>
<!-- List注入 -->
<property name="cats">
<list>
<bean class="com.gupaoedu.pojo.Cat" p:nick="小花1" p:color="红色"/>
<bean class="com.gupaoedu.pojo.Cat" p:nick="小花2" p:color="绿色"/>
<bean class="com.gupaoedu.pojo.Cat" p:nick="小花3" p:color="黄色"/>
</list>
</property>
<!-- Map注入 -->
<property name="map" >
<map>
<entry key="name1" value="张三1"/>
<entry key="name2" value="张三2"/>
<entry key="name3" value="张三3"/>
</map>
</property>
<!-- 属性文件注入 -->
<property name="props">
<props>
<prop key="username">root</prop>
<prop key="password">123</prop>
</props>
</property>
</bean>
</beans>
3.3 简化构造注入与设值注入
在Spring配置文件中引入对应的名称空间
xmlns:p="http://www.springframework.org/schema/p"
xmlns:c="http://www.springframework.org/schema/c"
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:c="http://www.springframework.org/schema/c"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- 构造注入 -->
<bean class="com.gupaoedu.pojo.UserBean" id="user" c:_0="111" c:_1="lisi">
<!--
<constructor-arg index="0" value="999" />
<constructor-arg index="1" value="gp" />
-->
</bean>
<!-- 设值注入 -->
<bean class="com.gupaoedu.pojo.UserBean" id="user1" p:id="222" p:userName="wangwu">
<!--
<property name="id" value="1"/>
<property name="userName" value="张三"/>
-->
</bean>
</beans>
3.4 工厂注入
3.4.1 静态工厂注入
package com.gupaoedu.factory;
import com.gupaoedu.pojo.UserBean;
import java.util.HashMap;
import java.util.Map;
public class StaticFactoryDemo {
public static Map<String,UserBean> hashMap ;
static {
hashMap = new HashMap<String, UserBean>();
hashMap.put("a1",new UserBean());
hashMap.put("a2",new UserBean());
hashMap.put("a3",new UserBean());
}
/**
* 静态工厂提供的方法
* @return
*/
public static UserBean getInstance(){
return hashMap.get("a1");
}
}
<?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.gupaoedu.factory.StaticFactoryDemo" factory-method="getInstance" id="user"></bean>
</beans>
3.4.1 动态工厂注入
package com.gupaoedu.factory;
import com.gupaoedu.pojo.UserBean;
/**
* 让每一个人的职业生涯不留遗憾
*
* @author 波波老师【咕泡学院】
*/
public class DynamicFactoryDemo {
public UserBean getInstance(){
return new UserBean();
}
}
<?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.gupaoedu.factory.DynamicFactoryDemo" id="dynamicFactoryDemo" ></bean>
<!-- 从工厂对象中获取 需要的对象-->
<bean id="user2" factory-bean="dynamicFactoryDemo" factory-method="getInstance"/>
</beans>