DI (Dependency Injection 依赖注入)
介绍
当某个角色(可能是一个Java实例,调用者)需要另一个角色(另一个Java实例,被调用者)的协助时,在 传统的程序设计过程中,通常由调用者来创建被调用者的实例(即new对象)。但在Spring里,创建被调用者的工作不再由调用者来完成,因此称为控制反转;创建被调用者 实例的工作通常由Spring容器来完成,然后注入调用者,因此也称为依赖注入。
总结:对象中的属性,应该由Spring容器动态赋值
XML方式实现
set注入
- 构建POJO属性
package ink.pingdu.pojo;
public class User {
//为常规属性赋值
private Integer id;
private String name;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public User(){}
public User(Integer id, String name) {
this.id = id;
this.name = name;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", name='" + name + '\'' +
'}';
}
}
- 编辑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">
<!--管理user对象-->
<bean id="user" class="ink.pingdu.pojo.User">
<!--调用对象的set方法实现赋值 set方法必须添加-->
<property name="id" value="101"></property>
<property name="name" value="李元芳"></property>
</bean>
</beans>
- 测试案例
package ink.pingdu;
import ink.pingdu.pojo.User;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class TestSpringDi {
@Test
public void testDi(){
ApplicationContext context = new ClassPathXmlApplicationContext("application.xml");
User user = context.getBean(User.class);
System.out.println(user.toString());
}
}
依赖注入成功:
构造注入
- 构建POJO属性(内容同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 = "user" class = "ink.pingdu.pojo.User">
<constructor-arg name="id" value="102"></constructor-arg>
<constructor-arg name="name" value="兰陵王"></constructor-arg>
</bean>
</beans>
- 测试案例(内容同set注入)
属性注入高级用法
- 编辑POJO属性
- 编辑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">
<!-- 管理user对象-->
<bean id = "user" class = "ink.pingdu.pojo.User">
<!--调用对象的set方法实现赋值 set方法必须添加-->
<property name="id" value="101"></property>
<property name="name" value="李元芳"></property>
<property name="list">
<list>
<value>张三</value>
<value>王五</value>
<value>老王</value>
</list>
</property>
<property name="set">
<set>
<value>1</value>
<value>2</value>
<value>3</value>
</set>
</property>
<property name="map">
<map>
<entry key="id" value="1000"></entry>
<entry key="name" value="tomcat猫"></entry>
</map>
</property>
<property name="properties">
<props>
<prop key="proId">110</prop>
<prop key="proName">米老鼠</prop>
</props>
</property>
</bean>
</beans>
- 测试案例(内容同set注入)
结果:
注意:其中 map 、properties 的值好像并没有像我们自己输入时的顺序,是因为程序内部通过 Hash值的规则来显示。
抽取集合类型
说明:如果在一个xml配置中,同样的集合要赋值给多个Bean时,为了避免重复代码,就可以把该集合定义为公共标签。下面以map为例:
- 编辑头标签
<!-- 添加util依赖(xmlns:util),为抽取集合类型,定义公共map标签
同时也得为util指定位置:在 xsi:schemaLocation 添加如下-->
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:util="http://www.springframework.org/schema/util"
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
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">
</beans>
- 实现对象引用
首先
<!--定义公共的map标签-->
<util:map id="map">
<entry key="id" value="1000"></entry>
<entry key="name" value="tomcat猫"></entry>
</util:map>
然后
<!--需要将同一个map进行赋值操作-->
<bean id="person" class="ink.pingdu.pojo.Person">
<property name="map" ref="map"></property>
</bean>
- 测试案例
package ink.pingdu;
import ink.pingdu.pojo.Person;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class TestSpringDi {
@Test
public void testDi2(){
ApplicationContext context = new ClassPathXmlApplicationContext("application.xml");
Person person = (Person) context.getBean("person");
System.out.println(person.toString());
}
}