Spring4.0实用教程-IOC容器(一)

一、轻量级容器

1、何为容器?

容器:应用代码的运行框架,提供对业务对象的管理。重量级容器EJB,曾经是管理J2EE业务对象最常用的容器。因为Spring的出现,它辉煌不再。J2EE的Web容器是比较特殊的,它用于管理servlet及其相关依赖对象。容器作为程序的运行框架,应该提供生命周期管理,查找服务,配置管理和依赖决策等基础服务,当然还可以提供企业级服务(事务管理等),线程管理,对象池,集群服务,远程服务等增值服务。

2、为何需要容器?

简单地说,使用容器就是为了减少代码量,特别是重复代码量。当然,容器提供的以下特性也是非常重要的。

可接插性:容器可以为各种组件提供可插接性。以Spring来说,通过配置文件XML或注解实现不同业务对象之间的切换,比如数据源等,避免硬编码带来的低灵活性和扩展性。

一致性:容器为用户提供了一致的保证,比如配置管理,服务定位等。Spring中JdbcTemplate,HibernateTemplate等抽象层为用户操作数据库,O/R映射提供一致的操作且简化不必要的,重复的代码。

一条龙服务:找到容器就能使用容器提供的所有服务,不需要为每个对象专门设计单例或工厂,避免Singleton泥潭及工厂类泛滥。

企业级服务:Spring提供的企业级服务足以说明使用容器的必要。

3、轻量级 VS 重量级

轻量级容器代表是Spring,重量级容器代表为EJB。EJB出现的较早,是Spring的前辈,更确切地说,Spring是为了解决EJB开发中的问题而产生的。EJB提供一个一步到位的解决方案,从对业务对象的管理,到为受控对象提供声明式中间件服务。正因为提供这样的解决方案,导致用户单独使用EJB管理业务对象(细粒度)或提供声明式服务成为噩梦。同时由于EJB实现问题,导致EJB代码必须依赖启动缓慢的EJB容器,从而影响测试。EJB部署也是个问题。

与EJB这个重量级容器相比,Spring作为轻量级容器的翘楚具有以下优点:

脱离整体式容器:轻量级容器和商业web服务器组合,不仅可以提供关键的J2EE服务,也能摆脱EJB式的整体式容器。

提高代码复用度:Spring中业务对象不依赖容器APi,可以高度复用。

更好地面向对象:Spring容器中的业务对象可以是POJO,且不用依赖容器API。

提高生产效率:轻量级容器中,应用代码类似于普通的Java代码,不需要像EJB那样依赖容器,所以可以充分利用IDE,提供开发效率。

提高可测试性:轻量级容器允许在容器外完成测试,不需要做特殊设置。

在重量级与轻量级的对抗中,Spring以四两拨千斤的招式重伤了EJB,可谓是长江后浪推前浪,EJB不得不追随后辈而做出改变。

二、控制反转

Spring是如何实现轻量级容器的?答曰:控制反转和面向切面编程。控制反转简称IOC,是一个非常重要的概念,它最著名的形式就是所谓的好莱坞原则(在设计模式初探-模板方法模式中有介绍)。

1、IOC实现策略

依赖查找:容器提供回调接口和上下文环境给组件,组件使用容器提供的API查找资源和协作对象。控制反转仅体现在回调方法上:容器将调用这些回调方法,从而让应用代码获取相关资源。

依赖注入(DI):组件不做定位查询,只提供普通的Java方法让容器去决定依赖关系。容器全权负责组件的装配,它会把符合依赖关系的对象通过JavaBean属性或构造器参数传递给需要的对象。

注:此处组件指的是相互协作的一组对象。

2、两种实现策略的比较

依赖查找:EJB提供的了依赖查找形式的IoC,让容器管理对象的生命周期,受理对象负责查找自己的依赖关系。这种实现方式的缺点是业务对象需要自己查找依赖关系,而有些时候查找还必须依赖特定的环境,比如JNDI。实际上,业务对象应该只负责实现业务逻辑,而不应该处理JNDI的技术细节。

依赖注入:Spring采用了依赖注入形式的IoC,让容器全权负责依赖查询,受管对象只需暴露JavaBean的setter方法或带参数的构造器,使容器可以在初始化时组装对象的依赖关系。此方式不依赖于特定的容器API或接口。业务对象不需负责查找资源或其他协作组件,降低应用代码对容器的依赖。

注:看到这大家要清楚IoC不等于DI

三、Spring的IoC容器

Spring的IOC容器中有两个重要的概念: bean工厂和应用上下文
bean工厂是Spring容器配置,装配JavaBean和POJOs的地方,核心实现位于org.springframework.beans包下。BeanFactory接口提供了一个先进的配置管理机制,可以管理任何类型的对象。Spring提供了多个支持热插拔的bean工厂实现,比如基于XML的XmlBeanFactory。
应用上下文是对bean工厂的扩展,它在bean工厂基础上增加了对信息源和资源加载的支持,并提供接入现有系统的能力,核心实现位于org.springframework.contex包下。ApplicationContext是BeanFactory的子接口,它能够很方便的集成Spring的AOP特性,消息资源处理,事件发布及WebApplicationContext这样的应用层特殊上下文。Spring提供了多个支持热插拔的应用上下文实现,比如基于Xml的ClassPathXmlApplicationContext,FileSystemXmlApplicationContext。
1、配置元数据
配置元数据是开发者用来告诉IoC容器怎样实例化,配置,装配应用程序中对象的一种手段,Spring提供3中方式,分别是基于XML的元数据,基于注解的配置和基于Java代码的配置。
基于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"
    xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="
		http://www.springframework.org/schema/beans 
		http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context-3.0.xsd">
	
	<!--id用于指定 bean一个唯一的bean定义,class定义bean的类型,需使用全限定名-->
    <bean id="mystyle" class="study.spring.container.TextStyle">
    	<!--property对应bean中的一个属性  -->
    	<property name="fontSize" value="12"/>
    	<property name="fontColor" value="red"/>
    	<property name="fontFamily" value="宋体"/>
    </bean>

     <bean id="yourstyle" class="study.spring.container.TextStyle">
    	<property name="fontSize" value="14"/>
    	<property name="fontColor" value="green"/>
    	<property name="fontFamily" value="仿宋"/>
    </bean>

</beans>
2、实例化容器
ApplicationContext ctx = new ClassPathXmlApplicationContext("sample_01.xml");
使用基于Xml且从classpath加载资源文件的应用上下文实现。它会解析sample_01.xml,在使用容器获取相应bean时,会自动装配bean及其依赖。
3、使用容器
ApplicationContext ctx = new ClassPathXmlApplicationContext("sample_01.xml");
TextStyle my = ctx.getBean("mystyle",TextStyle.class);
System.out.println(my.getFontColor());
TextStyle your = ctx.getBean("yourstyle",TextStyle.class);
System.out.println(your.getFontColor());
使用应用上下文可访问从指定配置文件加载的bean。一般不推荐直接使用getBean方法获取bean对象,这样会将应用代码和Spring的API绑定。可以使用Spring的依赖注入功能,比如集成Spring的web框架时可以使用依赖注入管理Controller。

你可能感兴趣的:(AOP,IOC,Spring4.0)