sprinng---IOC

来源:互联网 发布:电子商务模式价值网络 编辑:程序博客网 时间:2024/06/05 17:51

What:什么是IOC控制反转

Why:为什么IOC

When :什么时候使用IOC

How:怎么用?


1.先来看控制反转:

    控制反转(Inversion of Control),是一个重要的面向对象编程法则来削减计算机程序的耦合问题,也是轻量级的Spring框架的核心beans

  理解一:将组件对象的控制权从代码本身转移到外部容器()

  理解二:IOC控制反转:说的是创建对象实例的控制权从代码控制剥离到IOC容器(spring容器)控制,实际就是你在xml文件控制,侧重于原理

IOC原理:

在业务代码中不使用我们之前司空见惯的关键字new来构建一个业务实例,而是在配置文件中。通过xml节点来告知容器如何对内存中构建的对应类型的对象名称做命名


 2.再来看:DI依赖注入(Dependency Injection)

  DI依赖注入:说的是创建对象实例时,为这个对象注入属性值其它对象实例,侧重于实现。

  两者关系它们是spring核心思想的不同方面的描述。 (重点)


 3.DI 和 IOC 详细阐述
    首先,DI和IOC是差不多的概念。 一个重要特征是接口依赖,是把对象关系推迟到运行时去确定. 
    DI是一个初始化实例的过程,分为三种1.setter based 2.constructor based 3.interface based,spring 中就是应用前两种;但又不仅仅是初始化实例,而且是运用接口的概念去实现这种注入依赖。静态地看,只是依赖一个接口,但实际运行起来,是依赖一个实现了该接口的具体类。

 
IOC就是面向接口编程的应用 
1).一个通常的做法(非面向接口编程的方法),对象A依赖对象B,B会作为A的属性,可以理解为A直接控制B; 
2).IOC的做法,对象A依赖于接口C,而不直接依赖于实现了接口C的B,也就是A不能直接控制是哪个具体实现了C的B去做相应的事情,而是由我们控制可以由哪个实现了接口C的B去处理,也就是控制反过来了,是由B来决定了,而不是由A,实现就是面向接口编程。

 

4.IoC能做什么

IoC不是一种技术只是一种思想,一个重要的面向对象编程的法则,它能指导我们如何设计出松耦合更优良的程序。传统应用程序都是由我们在类内部主动创建依赖对象,从而导致类与类之间高耦合,难于测试;有了IoC容器后,把创建和查找依赖对象的控制权交给了容器,由容器进行注入组合对象,所以对象与对象之间是松散耦合,这样也方便测试,利于功能复用,更重要的是使得程序的整个体系结构变得非常灵活。

其实IoC对编程带来的最大改变不是从代码上,而是从思想上,发生了主从换位”的变化。应用程序原本是老大,要获取什么资源都是主动出击,但是在IoC/DI思想中,应用程序就变成被动的了,被动的等待IoC容器来创建并注入它所需要的资源了。

IoC很好的体现了面向对象设计法则之一—— 好莱坞法则:“别找我们,我们找你”;即由IoC容器帮对象找相应的依赖对象并注入而不是由对象主动去找 


IoC和DI由什么关 系呢?其实它们是同一个概念的不同角度描述,由于控制反转概念比较含糊(可能只是理解为容器控制对象这一个层面,很难让人想到谁来维护对象关系),所以 2004年大师级人物Martin Fowler又给出了一个新的名字:“依赖注入”,相对IoC 而言,“依赖注入”明确描述了“被注入对象依赖IoC容器配置依赖对象”。


5.(依赖注入的实现方式)怎么用?


 1)、Interface Injection(接口注入):容器运行时,目标对象实现特定的接口,然后容器通过接口将关联对象注入到目标对象中。这种方式Spring框架不支持,所以了解。


 2)、Setter Injection(设值方法注入):容器运行时,通过类属性的set方法将关联对象注入到目标对象中。Spring框架支持,而且是我们开发经常使用的,非常重要。


3)、Constructor Injection(构造方法注入):容器运行时,通过类的构造方法将关联对象注入到对象中。Spring框架也支持,没有set用的普遍。


设值注入:


private String name;private int age;private Car cars; //Car对象  域属性

1.普通属性直接property,引用类型用ref 如:Car对象


 <bean id="car1" class="cn.spring01.Car">     <property name="brand" value="宝宝"></property>    </bean>  <bean id="student" class="cn.spring01.Student">        <property name="name" value="小小"></property>        <property name="age" value="18"></property>        <property name="cars" ref="car1"></property>    </bean>

2.p命名空间注入


xmlns:p="http://www.springframework.org/schema/p"

  <bean id="car" class="cn.spring01.Car" p:color="red">        <property name="brand" value="宝宝"></property>    </bean>    <bean id="student" class="cn.spring01.Student" p:name="熊熊" p:age="13" p:cars-ref="car">    </bean>


3.集合注入:List、Map、Set、Properties
private List<String> list;private Set<String> set;private Map<String,String> map;private Properties properties;
 <!-- List属性注入-->    <bean id="collection" class="cn.spring02collection.MyCollection">        <property name="list">            <list>                <value>xx</value>                <value>cc</value>                <value>vv</value>            </list>        </property>    </bean>


 <!-- Set属性注入-->    <bean id="collection" class="cn.spring02collection.MyCollection">        <property name="set">            <set>                <value>xx</value>                <value>cc</value>                <value>yy</value>            </set>        </property>    </bean>


 <!-- Map属性注入-->    <bean id="collection" class="cn.spring02collection.MyCollection">        <property name="map">            <map>                <entry key="001">                    <value>沫沫</value>                </entry>                <entry key="002" >                    <value>妮妮</value>                </entry>                <entry key="003" >                    <value>扣扣</value>                </entry>            </map>        </property>    </bean>

 <bean id="collections" class="cn.spring02collection.MyCollection">        <property name="properties">            <props>                <prop key="001">安安</prop>                <prop key="002">妮妮</prop>            </props>        </property>    </bean>

构造注入:

如果参数只有一个,可以只用一个value属性,如果有多个无参构造方法,里边参数可能不同,顺序可能不同等,可以用index属性指定所定义的值


  <!--2.构造注入-->    <bean id="car" class="cn.spring01.Car">        <property name="brand" value="宝宝"></property>    </bean>    <bean id="student" class="cn.spring01.Student">        <constructor-arg index="0" value="小明"></constructor-arg>        <constructor-arg index="1" value="18"></constructor-arg>        <constructor-arg index="2" ref="car"></constructor-arg>    </bean>

6.自动装配   利用autowire标签来实现

          1byName(根据名称),从Spring环境中获取目标对象时,目标对象中的属性会根据名称在整个Spring环境中查找<bean>标签的id属性值:

<bean id="loginAction"class="com.ljh.struts2.action.LoginAction"autowire="byName" ></bean>

 

           2、byType(根据类型),从Spring环境中获取目标对象时,目标对象中的属性会根据类型在整个spring环境中查找<bean>标签的class属性值:

<bean id="userService"class="com.ljh.struts2.service.UserService"autowire="byType" ></bean>

 

           3、constructor:使用构造方法完成对象注入,其实也是根据构造方法的参数类型进行对象查找,相当于采用byType的方式。

 

           4、autodetect(自动选择):如果对象没有无参数的构造方法,那么自动选择constructor的自动装配方式进行构造注入。      如果对象含有无参数的构造方法,那么自动选择byType的自动装配方式进行setter注入。

 

          5、no:表示不支持自动装配功能;

 

          6default:表示默认采用上一级标签的自动装配的取值。<beans>标签中的default-autowire属性。如果存在多个配置文件的话,那么每一个配置文件的自动装配方式都是独立的。


总结:自动装配就是为了弥补手动装配,如果两者都使用,优先选择手动的。由于自动装配需要在Spring全局环境中搜索,所以性能上会低一些,而且可阅读性较差,所以还是推荐大家使用手动装配功能。

原创粉丝点击