官网:spring.io

applicationContext.xml

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:schemaLocation="http://www.springframework.org/schema/beans
  5. http://www.springframework.org/schema/beans/spring-beans.xsd">
  6. </beans>

IoC理论

set注入

//在service层
public class CarServiceImpl implements CarService{
    private CarDao carDao;   
    public void setCarDao(CarDao carDao){
        this.carDao = carDao;
    }
}
public class CarServiceImpl implements CarService{
    private CarDao carDao = new CarDaoImpl;   
}

这两者表面上看起来没什么区别,但是本质上有很大的区别。
首先,当我们的实现类改变的时候,上面的代码不需要程序员来修改源代码,而下面的代码则需要修改,在很多地方都用到new的时候修改量很大,修改一次成本过高。
其次,上面的代码使用set注入后,程序不再具有主动性,变成了被动的接收对象,而下面的是程序主动创建对象,耦合性高。
这样就可以不用管理对象的创建,大大的降低了耦合性,可以更加专注于业务层的实现。

IoC本质

控制反转IoC(Inversion of Control),是一种设计思想,DI(依赖注入)是实现IoC的一种方法,也有人认为DI只是IoC的另一种说法。没有IoC的程序中 , 我们使用面向对象编程 , 对象的创建与对象间的依赖关系完全硬编码在程序中,对象的创建由程序自己控制,控制反转后将对象的创建转移给第三方,个人认为所谓控制反转就是:获得依赖对象的方式反转了

Spring IOC - 图1

IoC是Spring框架的核心内容,使用多种方式完美的实现了IoC,可以使用XML配置,也可以使用注解,新版本的Spring也可以零配置实现IoC

Spring容器在初始化时先读取配置文件,根据配置文件或元数据创建与组织对象存入容器中,程序使用时再从Ioc容器中取出需要的对象。

控制反转是一种通过描述(XML或注解)并通过第三方去生产或获取特定对象的方式。在Spring中实现控制反转的是IoC容器,其实现方法是依赖注入(Dependency Injection,DI)。

IOC创建对象方式

1.通过无参构造方法来创建

<bean id="singer2" class="com.test3.Singer">
  <property name="name" value="李四"></property>
  <property name="age" value="24"></property>
  <property name="mi" ref="piano"></property>
</bean>

在这段代码里面,实际上是通过无参构造方法创建对象,property就是调用set方法。

2.通过有参构造方法来创建

<bean id="singer1" class="com.test3.Singer">
  <constructor-arg name="mi" ref="guitar"></constructor-arg>
  <constructor-arg name="name" value="张三"></constructor-arg>
  <constructor-arg name="age">
    <value>20</value>
  </constructor-arg>
</bean>

也可以把name换成index。下标按照构造函数的参数列表从0开始。

依赖注入(DI)

构造器注入

* set方式注入

set

<property name="accNames">
  <!-- 使用set标签注入简单set集合属性 --> 
  <set>
    <value>小刘</value>
    <value>小王</value>
  </set>
</property>

  <!-- set标签注入引用类型属性 --> 
  <set><ref bean="account1"/>
    <ref bean="account2"/> 
  </set>

map

//redis节点配置类
public class RedisNode{
    private String host;
    private int port;
    //省略setter和getter
}
//redis集群配置类
public class RedisClusterConfig{
    private String clusterName;//集群名称
    private Map<String,RedisNode> nodes; //reids节点集合 key为节点的名称,value为节点配置对象
    //省略setter和getter
    public void showInfo(){//输出所有节点信息}
}
<bean id="redisNode" class="com.test1.RedisNode">
  <property name="host" value="111.222.3.88"></property>
  <property name="port"><value>8585</value></property>
</bean>
<bean id="clusterConfig" class="com.test1.RedisClusterConfig">
  <property name="clusterName" value="服务器集群"></property>
  <property name="nodes">
    <map>
      <entry key="001" value-ref="redisNode"></entry>
    </map>
  </property>
</bean>

list

<!--集合里面放引用类型 -->
<bean class="com.test2.PathMappingConfig" id="mappingConfig">
  <property name="pathMappings">
    <list>
      <ref bean="pathMapping1"></ref>
      <ref bean="pathMapping2"></ref>
    </list>
  </property>
</bean>

<!--集合里面放简单类型 -->
<list>
  <value>小刘</value>
  <value>小王</value>
</list>


properties

public class Group { 
    private Properties accNames; 
    public void setAccNames(Properties accNames) {
        this.accNames = accNames;
    }
}
<bean id="group" class="com.boxuewa.dk.demo2.beans.Group">
  <property name="accNames">
    <props> 
      <prop key="9527">卡卡西</prop>
      <prop key="9528">佐助</prop>
      <prop key="9529">鸣人</prop> 
    </props>
  </property>
</bean>

注:以上方法同样适合构造方法注入

自动装配

我们使用spring,对象的属性,需要手动的编写配置注入,实际上spring提供了自动注入的方式。
spring可以帮我们的bean注入属性。比如给userService注入userDAO属性。我们可以通过property属性配置,也可以通过Autowire让spring自动注入。

ByName

<bean id="bookDao" class="com.test3.dao.impl.BookDAOImpl"></bean>
<!--使用byname的时候保证bean id的唯一。这个bean需要和自动注入的属性的set方法一致-->
<bean autowire="byName" class="com.test3.service.impl.BookServiceImpl"></bean>

也就是说通过byname需要属性的名字和这个bean的id名一致,不然无法找到会报空指针异常

ByType

<bean class="com.test3.dao.impl.BookDAOImpl"></bean>
<!--使用byname的时候保证bean class的唯一。这个bean需要和自动注入的属性类型一致-->
<bean autowire="byName" class="com.test3.service.impl.BookServiceImpl"></bean>

通过bytype需要属性的类型和这个bean的class一致,可以不需要id。

使用注解实现自动装配

使用注解的前提:
1.导入约束
2.配置注解的支持

<!-- 在容器中加上下面的内容 -->
xmlns:context="http://www.springframework.org/schema/context"

http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd

3.开启属性注解支持

<context:annotation-config/>


@Autowired
要在每一个需要自动注入的属性前加上这个注解。

public class BookServiceImpl implements BookService {
    @Autowired
    private BookDAO bookDao;

//    public void setBookDao(BookDAO bookDao) {
//       this.bookDao = bookDao;
//    }
}

加上这个注解之后,可以不需要set方法。
注意:加入注解后需要在spring容器中存在且符合名字。