文章目录
控制反转和依赖注入
经多方查阅资料和自己的理解,我认为 控制反转IOC 和 依赖注入DI 并不是完全相同的概念。
所以用这篇文章记录以下我对控制反转和依赖注入的理解。先阅读下面的有助于理解本文!!
依赖关系
依赖关系:指对象之间的引用依赖关系,比如 对象A 中的 私有成员b 是一个B对象,就是一种依赖关系。
A依赖于B:A的功能依赖于B的支持
Class B{
}
Class A{
private B b;
public void afunction(){
……
b.doSomething();
……
}
}
理解控制反转IOC
反转前:程序(类代码)中蕴含了对象之间的依赖关系(程序负责维护对象间依赖关系)
反转后:程序中不再包含对象之间的依赖关系,而是将对象之间的依赖关系剥离出来,蕴含到配置文件(xml或注解)当中。
当程序中要使用对象时,直接向第三方框架(Spring)索要对象,第三方框架(Spring)通过配置文件中记录的对象间的依赖关系生成相应对象(通过反射)。
理解依赖注入DI
第三方框架(Spring)通过配置文件(xml或注解)中记录的对象间的依赖关系生成相应对象的过程为依赖注入。
即:将配置文件中的依赖关系注入到相互独立的对象之中,并将注入了依赖关系的对象返回给程序使用。
依赖注入DI
Spring中的依赖注入不仅包含对象之间的关系,还包括对象中属性的关系,其实依据万物皆对象的思想:每个对象的每个属性都是一个对象,也就是说再Spring中,每个对象的每个属性的赋值(无论是基本类型还是引用类型)都属于依赖注入!
下面用一个例子来实现各种依赖注入:
// 要实现依赖注入的类Student (此处略去Get,Set,toString方法)
public class Student {
private String name ; //直接赋值
private Address address; //引用对象 定义在下面
private String[] books; //数组
private List<String> hobbies; //List
private Map<String,String> card; //Map
private Set<String> games; //Set
private Properties info; //properties
private String lover; //null
}
public class Address {
private String address;
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
@Override
public String toString() {
return "Address{" +
"address='" + address + '\'' +
'}';
}
}
配置xml文件-实现依赖注入
接下来,为Student中的每个成员注入依赖!!
<?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">
<!--注册Address类-->
<bean id="address" class="com.yy.pojo.Address">
<property name="address" value="黑龙山白水沟一棵松树旁"></property>
</bean>
<!--注册Student类-->
<bean id="student" class="com.yy.pojo.Student">
<!--使用property标签对应一个属性,name对应属性名,使用value直接为其赋值~~!!-->
<property name="name" value="大头儿子!"></property>
<!--使用ref引用其他注册的bean(对象)~~!!-->
<property name="address" ref="address"></property>
<!--使用array为数组赋值~~!!-->
<property name="books">
<array>
<value>三国演义</value>
<value>红楼梦</value>
<value>龙族</value>
<value>三体</value>
</array>
</property>
<!--使用list为list赋值~~!!-->
<property name="hobbies">
<list>
<value>听歌</value>
<value>敲代码</value>
<value>吃小孩</value>
</list>
</property>
<!--使用map\entry为map赋值~~!!-->
<property name="card">
<map>
<entry key="身份证" value="123456456123"></entry>
<entry key="银行卡" value="88888888"></entry>
</map>
</property>
<!--使用set为set赋值~~!!-->
<property name="games">
<set>
<value>DOTA2</value>
<value>LOL</value>
<value>炉石传说</value>
</set>
</property>
<!--赋null值-->
<property name="lover">
<null></null>
</property>
<!--使用property为Properties赋值-->
<property name="info">
<props>
<prop key="性别">男</prop>
<prop key="性取向">女</prop>
<prop key="性格">大聪明</prop>
</props>
</property>
</bean>
</beans>
在测试类中调用:
public class MyTest04 {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
Student student = (Student) context.getBean("student");
System.out.println(student.toString());
}
}
输出结果:
有参构造函数注入
当类中含有有参构造函数,也可通过有参构造函数注入!!
三种注入方式!
public class User {
private String name;
public User(String name) {
this.name = name;
}
}
<!-- 第一种根据index参数下标设置 -->
<bean id="user" class="com.yy.pojo.User">
<!-- index指构造方法参数序号 , 下标从0开始 -->
<constructor-arg index="0" value="大头!"/>
</bean>
<!-- 第二种根据参数名字设置 -->
<bean id="user" class="com.yy.pojo.User">
<!-- name指参数名 -->
<constructor-arg name="name" value="大头!"/>
</bean>
<!-- 第三种根据参数类型设置 -->
<bean id="user" class="com.yy.pojo.User">
<constructor-arg type="java.lang.String" value="大头!"/>
</bean>
命名空间依赖注入(简化xml)
p命名:简化属性依赖注入
p命名空间注入 : 需要在头文件中加入约束文件
导入约束 :xmlns:p="http://www.springframework.org/schema/p"
<?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" 引入p约束
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="user" class="com.yy.pojo.User" p:name="p-name" p:sex="p-sex"/>
一句 -- 等价于下四行
<bean id="user" class="com.yy.pojo.User">
<property name="name" value="p-name"></property>
<property name="sex" value="p-sex"></property>
</bean>
</beans>
c命名:简化构造函数依赖注入
c 命名空间注入 : 需要在头文件中加入约束文件
导入约束 :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:c="http://www.springframework.org/schema/c" 引入c约束
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="user" class="com.yy.pojo.User" c:name="c-name!!" c:sex="c--sex!!"></bean>
上面一句 等价于下面四句
<bean id="user" class="com.yy.pojo.User">
<constructor-arg name="name" value="c-name"></constructor-arg>
<constructor-arg name="sex" value="c-sex"></constructor-arg>
</bean>
</beans>