**依赖与依赖注入:**
传统应用程序设计中所说的依赖一般指“类之间的关系”,那先让我们复习一下类之间的关系:
**泛化:**表示类与类之间的继承关系、接口与接口之间的继承关系;
**实现:**表示类对接口的实现;
**依赖:**当类与类之间有使用关系时就属于依赖关系,不同于关联关系,依赖不具有“拥有关系”,而是一种“相识关系”,只在某个特定地方(比如某个方法体内)才有关系。
**关联:**表示类与类或类与接口之间的依赖关系,表现为“拥有关系”;具体到代码可以用实例变量来表示;
**聚合:**属于是关联的特殊情况,体现部分-整体关系,是一种弱拥有关系;整体和部分可以有不一样的生命周期;是一种弱关联;
**组合:**属于是关联的特殊情况,也体现了体现部分-整体关系,是一种强“拥有关系”;整体与部分有相同的生命周期,是一种强关联;
**Spring IoC容器的依赖有两层含义:Bean依赖容器和容器注入Bean的依赖资源**:
**Bean依赖容器:**也就是说Bean要依赖于容器,这里的依赖是指容器负责创建Bean并管理Bean的生命周期,正是由于由容器来控制创建Bean并注入依赖,也就是控制权被反转了,这也正是IoC名字的由来,此处的有依赖是指Bean和容器之间的依赖关系。
**容器注入Bean的依赖资源:**容器负责注入Bean的依赖资源,依赖资源可以是Bean、外部文件、常量数据等,在Java中都反映为对象,并且由容器负责组装Bean之间的依赖关系,此处的依赖是指Bean之间的依赖关系,可以认为是传统类与类之间的“关联”、“聚合”、“组合”关系。
**为什么要应用依赖注入,应用依赖注入能给我们带来哪些好处呢?**
**动态替换Bean依赖对象,程序更灵活:**替换Bean依赖对象,无需修改源文件:应用依赖注入后,由于可以采用配置文件方式实现,从而能随时动态的替换Bean的依赖对象,无需修改java源文件;
**更好实践面向接口编程,代码更清晰:**在Bean中只需指定依赖对象的接口,接口定义依赖对象完成的功能,通过容器注入依赖实现;
**更好实践优先使用对象组合,而不是类继承:**因为IoC容器采用注入依赖,也就是组合对象,从而更好的实践对象组合。采用对象组合,Bean的功能可能由几个依赖Bean的功能组合而成,其Bean本身可能只提供少许功能或根本无任何功能, 全部委托给依赖Bean,对象组合具有动态性,能更方便的替换掉依赖Bean,从而改变Bean功能;而如果采用类继承,Bean没有依赖Bean,而是采用继承方式添加新功能,,而且功能是在编译时就确定了,不具有动态性,而且采用类继承导致Bean与子Bean之间高度耦合,难以复用。
**增加Bean可复用性:**依赖于对象组合,Bean更可复用且复用更简单;
**降低Bean之间耦合:**由于我们完全采用面向接口编程,在代码中没有直接引用Bean依赖实现,全部引用接口,而且不会出现显示的创建依赖对象代码,而且这些依赖是由容器来注入,很容易替换依赖实现类,从而降低Bean与依赖之间耦合;
**代码结构更清晰:**要应用依赖注入,代码结构要按照规约方式进行书写,从而更好的应用一些最佳实践,因此代码结构更清晰。
**Spring IoC容器注入依赖资源主要有以下两种基本实现方式:**
**构造器注入:**就是容器实例化Bean时注入那些依赖,通过在在Bean定义中指定构造器参数进行注入依赖,包括实例工厂方法参数注入依赖,但静态工厂方法参数不允许注入依赖;
**setter注入:**通过setter方法进行注入依赖;
entity
package org.liang.entity;
import java.util.Arrays;
import java.util.Map;
/**
* Created by rcc on 2018/1/20.
*/
public class StudentName {
private String[] names;
private Map<String,String> address;
private User user;
public StudentName(User user) {
this.user = user;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public StudentName(Map<String, String> address) {
this.address = address;
}
public StudentName(String[] names, Map<String, String> address) {
this.names = names;
this.address = address;
}
public StudentName(String[] names, Map<String, String> address, User user) {
this.names = names;
this.address = address;
this.user = user;
}
public Map<String, String> getAddress() {
return address;
}
public void setAddress(Map<String, String> address) {
this.address = address;
}
public StudentName() {
}
public StudentName(String[] names) {
this.names = names;
}
public String[] getNames() {
return names;
}
public void setNames(String[] names) {
this.names = names;
}
@Override
public String toString() {
return "StudentName{" +
"names=" + Arrays.toString(names) +
", address=" + address +
", user=" + user +
'}';
}
}
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">
<!-- <bean id="user" class="org.liang.entity.User" />-->
<bean id="userService" class="org.liang.service.UserServiceImpl" />
<bean id="persion" class="org.liang.entity.Persion">
<constructor-arg index="0" value="doudou"/>
<constructor-arg name="nickName" value="zhuzhu"/>
<constructor-arg type="java.lang.Integer" value="18"/>
</bean>
<!--静态工厂注入-->
<bean id="userFactory" class="org.liang.factory.BeanFactory" factory-method="newInstance">
<constructor-arg index="0" value="施瓦辛格"/>
<constructor-arg name="gender" value="男"/>
<constructor-arg type="java.lang.Integer" value="50"/>
</bean>
<!--setter注入-->
<bean id="user" class="org.liang.entity.User">
<property name="name" value="张三"/>
<property name="gender" value="男"/>
<property name="age" value="18"/>
</bean>
<!--注入集合、数组、字典(Map)-->
<bean id="students" class="org.liang.entity.StudentName">
<property name="names">
<list value-type="java.lang.String">
<value>张三</value>
<value>李四</value>
<value>王二</value>
</list>
</property>
<property name="address">
<map key-type="java.lang.String" value-type="java.lang.String">
<entry>
<key><value>10010</value></key>
<value>张三</value>
</entry>
<entry>
<key><value>10020</value></key>
<value>李四</value>
</entry>
<entry>
<key><value>10030</value></key>
<value>王二</value>
</entry>
</map>
</property>
<property name="user" ref="user">
</property>
</bean>
</beans>
test
package org.liang.test;
import org.liang.entity.Persion;
import org.liang.entity.StudentName;
import org.liang.entity.User;
import org.liang.factory.BeanFactory;
import org.liang.service.UserServiceImpl;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* Created by rcc on 2018/1/19.
* 测试类
*/
public class TestUser {
public static void main(String [] args){
/*ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
Persion persion = context.getBean("persion", Persion.class);
System.out.print(persion);*/
ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
StudentName students = (StudentName) context.getBean("students");
System.out.println(students);
}
}
以上的示例呢是一个错误的示例,在工作或者学习中需要避免产生这种循环注入的情况,一旦产生这样的情况后果是很严重的,所以,在依赖注入的时候需要避免这样的你中有我我中有你的情况。