控制反转(Inversion of Control,缩写为IoC),是面向对象编程中的一种设计原则,可以用来减低计算机代码之间的耦合度。
其中最常见的方式叫做依赖注入(Dependency Injection,简称DI),还有一种方式叫“依赖查找”(Dependency Lookup)。
通过控制反转,对象在被创建的时候,由一个调控系统内所有对象的外界实体将其所依赖的对象的引用传递给它。也可以说,依赖被注入到对象中。
1、构造器注入
前面学习用的都是构造器注入
构造器创建对象的同时注入属性
2、set方式注入(重点)
构造器创建完对象后,才注入属性
依赖注入 :set注入
依赖:bean对象的创建依赖于容器
注入:bean对象中的所有属性由容器注入
依赖注入就是在容器中创建对象并且注入属性,而spring就是容器的一种
说白set注入就是set注入属性
【环境搭建】
1、复杂类型
public class Address {
private String address;
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}
2、测试对象
这个类还引用了上面的类
public class Student {
//一个复杂的类,涵盖多种数据类型(引用类型+基本类型(太简单没用上))
//对应都是set注入的常用的类型 bean|ref|idref|list|set|map|props|value|null
private String name;//bean
private Address address;//ref地址
private String[] books;//idref数组
private List<String> hobbies;//list集合(=容器)
private Map<String,String> card;//map集合(=容器)
private Set<String> games;//set集合(=容器)
private Properties info;//props配置信息
private String wife;//null空指针
//后面都是上面这些属性的get/set方法,太多就不放了
}
3、 beans.xml 【测试】普通值注入 value
<?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="student" class="com.ming.pojo.Student">
<property name="name" value="明哥"/>
</bean>
</beans>
4、【测试】方法
public class MyTest {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
Student student = (Student) context.getBean("student");
System.out.println(student.getName());//其它还没写依赖注入(bean),直接返回空指针
}
}
完善注入信息
<bean id="address" class="com.ming.pojo.Address">
<property name="address" value="西安"/>
</bean>
<bean id="student" class="com.ming.pojo.Student">
<!--1、普通值注入,value-->
<property name="name" value="明哥"/>
<!--2、bean注入,ref-->
<property name="address" ref="address"/>
<!--3、数组注入,array-->
<property name="books" >
<array>
<value>红楼梦</value>
<value>西游记</value>
<value>水浒传</value>
<value>三国演义</value>
</array>
</property>
<!--4、list-->
<property name="hobbies">
<list>
<value>音乐</value>
<value>敲代码</value>
<value>看电影</value>
</list>
</property>
<!--5、map-->
<property name="card">
<map>
<entry key="身份证" value="213131561"/>
<entry key="银行卡" value="131654165"/>
</map>
</property>
<!--6、set-->
<property name="games">
<set>
<value>英雄联盟</value>
</set>
</property>
<!--7、props(Properties)-->
<property name="info">
<props>
<prop key="driver">13213</prop>
<prop key="url">男</prop>
<prop key="username">root</prop>
<prop key="password">123456</prop>
</props>
</property>
<!--8、null-->
<property name="wife">
<null></null>
</property>
</bean>
测试结果及分析
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
Student student = (Student) context.getBean("student");
System.out.println(student.toString());//其它还没写依赖注入(bean),直接返回空指针
/*打印属性分析:
Student{
name='明哥',
address=Address{
address='西安'
},
books=[红楼梦, 西游记, 水浒传, 三国演义],
hobbies=[音乐, 敲代码, 看电影],
card={
身份证=213131561,
银行卡=131654165
},
games=[英雄联盟],
info={
password=123456,
url=男,
driver=13213,
username=root
},
wife='null'
}
*/
3、其它方式
1、 p命名空间注入(对应set注入),可以直接注入属性的值:property
注意:先导入xml约束(xmlns属性
<!-- xmlns属性声明 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"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="user" class="com.ming.pojo.User" p:name="张三" p:age="18"/>
</beans>
2、c命名空间注入(对应构造器注入)
注意:先导入xml约束(xmlns属性)
xmlns:c="http://www.springframework.org/schema/c"
<!-- p命名空间注入,使用构造器注入,constructor-arg 构造器参数)
细节:发现只有引用类型参数才有ref这个元素可以用,int等基本类型根本不需要
-->
<bean id="user2" class="com.ming.pojo.User" c:age="17" c:name="李四"/>
官方文档位置:
3、 测试:
@Test
public void Test(){
ApplicationContext context = new ClassPathXmlApplicationContext("userBeans.xml");
//显式声明user的class类,就不用强转getBean获取的对象为User了
User user = context.getBean("user2",User.class);
System.out.println(user);
}