Spring学习笔记(二)——Spring Ioc反转控制

Gof曾提出,针对接口编程,而不是实现。
通常情况下,开发者将业务对象抽象为Java接口,然后将各个业务共性的内容实现为抽象类,并继承于Java接口。继而,再依据具体的业务操作类型,实现业务对象,并继承于抽象类。其明显含义是:子类只能添加或者重载操作,而不能隐藏父类的操作。最终,实现了抽象类的具体业务实现类能够响应抽象类继承的接口发送的请求操作。
1.[b]背景[/b]
Ioc设计模式,重点关注组件的依赖性、配置以及生命周期。Ioc也适用于简单类,而不只是组件。昵称Dependency Injection(依赖注入)。
Ioc将创建对象实例的任务交给Ioc容器或者框架(注,实现了Ioc设计模式的框架,有时候也称之为Ioc容器),使得应用程序代码只需要直接使用实例,这就是Ioc。
使用Ioc,能提供如下几方面的优势:
1)应用组件不需要在运行时寻找其协作者,更易于开发和编写应用。在许多Ioc容器中,借助于设置方式能够在运行时将组件依赖的其他组件注入进来。
2)由于借助Ioc容器管理组件的依赖关系,更有利于单元测试和集成测试。
3)通常,在借助于Ioc容器管理业务对象的前提下,很少需要使用具体Ioc容器提供的API。这使得集成现有的遗留系统成为可能。
因此,通过使用Ioc能够降低组件之间的耦合度。最终,能够提高类的重用性,更利于测试,而且整个产品或系统更利于集成和配置。

2.[b]Spring Ioc[/b]
Spring Ioc容器实现了Ioc设计模式。为实现对Spring Ioc容器的访问,代码可通过如下两个接口实现:
1)BeanFactory:位于org.springframework.beans.factory包中。开发者借助于配置文件(比如,XML或属性文件),能够实现对JavaBean的配置与管理。主要用开发java应用,比如Applet应用。
2)ApplicationContext:位于org.springframework.context包中。ApplicationContext构建在BeanFactory的基础上,即继承于它。除了具有BeanFactory的功能外,还添加了大量功能,比如Spring Ioc集成、(为实现国际化而)处理消息资源、(为应用对象发布和注册通知事件而)添加了事件、声明(非)容器提供的服务等。主要用于J2EE开发,是Spring推荐的接口。

3.[b]BeanFactory[/b]
[color=blue](在spring-beans.jar包中,org.springframework.beans.factory.BeanFactory)[/color]
Spring BeanFactory是非常轻量的,它处于Spring框架的核心。可用于Applet应用和单独的Swing/SWT应用中。对于EJB应用而言也同样适用。在整个Spring框架中都存在BeanFactory的概念,即统一使用BeanFactory访问Spring Ioc容器。开发者通过使用BeanFactory能够定义和提供良好的业务对象层,从技术架构角度考虑,这是很合理的。
当应用创建BeanFactory实例时,实际上是完成了JavaBean的实例化、配置以及管理,即BeanFactory在访问和操作Ioc容器的初期充当了Ioc容器的作用。其中,BeanFactory具体使用的Spring配置文件定义了各个JavaBean之间的关系。
Spring提供了org.springframework.beans.factory.BeanFactory接口的若干实现。对于应用需要实例化BeanFactory实例的场合,XmlBeanFactory使用尤为广泛。
Spring配置文件(appcontext.xml)必须遵循spring-beans.dtd定义的内容模型。其中,spring-beans.dtd为javabean命名空间提供了一种简单、一致的定义方式,供BeanFactory配置使用。大部分Spring框架提供的功能都需要使用到它,包括基于BeanFactory的web应用上下文。
为了配置Spring application.xml文件,开发者需要告诉XmlBeanFactory构建器,即appcontext.xml文件。下述应用使用了Spring框架中org.springframework.core.io提供的实用类ClassPathResource:
Resource resource = new ClassPathResource("appcontext.xml");
BeanFactory factory = new XmlBeanFactory(resource);
HelloWorld hw = (HelloWorld) factory.getBean("fileHelloWorld");
还存在两种方式:
其一,基于文件找到appcontext.xml,如下:
InputStream ins = new FileInputStream("src/appcontext.xml");
BeanFactory factory = new XmlBeanFactory(ins);
HelloWorld hw = (HelloWorld) factory.getBean("fileHelloWorld");
其二,基于ApplicationContext实现类找到appcontext.xml文件。如下:
ClassPathXmlApplicationContext appContext = new ClassPathXmlApplicationContext(new String[]{"appcontext.xml"});
BeanFactory factory = (BeanFactory)appContext;
HelloWorld hw = (HelloWorld) factory.getBean("fileHelloWorld");

多数情况下,并不需要显示的实例化BeanFactory实例,因为Spring框架完成了这部分工作。当J2EE Web应用部署并启动时,Spring ApplicationContext将会自动被实例化。
为了获得appcontext.xml中定义的JavaBean,应用代码只需要调用BeanFactory的getBean方法,并转换为JavaBean所属类型。

3.1)Bean的生命周期
借助Ioc容器,即BeanFactory能实现对javabean的控制反转。Ioc容器定义了Spring配置文件中Javabean应遵循的规则。Ioc控制下的javabean的生命周期存在4个阶段:
a)实例化Javabean;
b)javabean实例的初始化,即通过Ioc注入其依赖性;
c)基于Spring应用对javabean实例的使用;
d)Ioc容器销毁javabean实例。

3.2)Bean创建。
借助于构建器创建javabean最常见,推荐尽量使用无参数构建器创建javabean实例。
Spring配置文件中<ref>提供如下几个方面的属性:
a)bean:在当前Spring XML配置文件中,或者在同一BeanFactory(AapplicationContext)中的其他javaBean中。
b)local:其依赖的JavaBean必须存在于当前Spring XML配置文件中。借助于Spring IDE,在编译期会对依赖的javabean进行验证。
c)用于指定其依赖的父javabean定义。

3.3)初始化JavaBean
3.4)使用javabean
借助于getBean方法,在应用中能够应用到它。
3.5)销毁javaBean

4.[b]ApplicationContext[/b]
BeanFactory提供了管理和操作JavaBean的基本功能,而且是通过应用嗲吗显式的实例化BeanFactory来完成的。为加强功能,Spring框架引入了ApplicationContext接口,不需手动创建ApplicationContext实例,以声明方式便可使用它。
org.springframework.web.context.ContextLoaderListener
或者
org.springframework.web.context.ContextLoaderServlet
能够在web应用启动的时候自动实例化ApplicationContext对象。
注意:对于Spring BeanFactory而言,如果用户没有调用getBean方法,则使用到的JavaBean实例不会被创建。因此,在BeanFactory中使用了延迟装载机制,这和BeanFactory的应用场合(内存和其他资源受限)有关系。对于Spring ApplicationContext而言,一旦ContextLoaderListener或ContextLoaderServlet初始化成功,所有的javabean实例将被创建(除非改变AapplicationContext的默认行为,比如显式设置延迟装在行为)
4.1)web应用中创建applicationContext
通过ContextLoaderListener或ContextLoaderServlet能够自动创建ApplicationContext实例。也可以手动创建。
对于实现了servlet2.4规范的web容器,可同时使用ContextLoaderListener和ContextLoaderServlet。web应用启动时,将自动初始化监听器,如ContextLoaderListener
<!-- Listener contextConfigLocation -->
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>

对于实现规范servlet2.2的web容器,只能使用ContextLoaderServlet
4.2)ApplicationContextAware
在Spring应用中,有时需要将Spring应用中的ApplicationContext实例注入到JavaBean实例中。例如:为了在某Javabean实例中动态获得ApplicationContext创建的某单例JavaBean,但是该单例JavaBean并没有显式的使用(在Spring配置文件中没有显式地给出对单例JavaBean的引用)到它。这种情况下,借助ApplicationContextAware能实现开发要求。如:
org.springframework.context.ApplicationContextAware
其中定义了如下方法:
void setApplicationContext(ApplicationContext applicationContext)
throws BeansException
比如在Spring配置中定义了两个JavaBean:bean1和bean2,如果bean2需要使用到bean1,但是bean2的Spring配置中,没有显式的配置对bean1的引用(没有<ref>)。此时,借助ApplicationContextAware,让bean2实现ApplicationContextAware接口,定义私有的applicationContext变量,并提供相应的setter方法。通过调用applicationContext的getBean方法就可以获取需要的bean1。
这同BeanFactoryAware 类似。
4.3)ApplicationContext接口实现
基于ApplicationContext接口,Spring框架提供了若干实现。
a)ClassPathXmlApplicationContext:在web应用中,开发者可以从classpath中,即WEB-INF/classes或WEB-INF/lib的jar中装载Spring配置文件。单元测试中常用到。
b)FileSystemXmlApplicationContext:开发者可以从文件系统中装载Spring配置文件。单元测试常用。
c)XmlWebApplicationContext:供ContextLoaderListener或ContextLoaderServlet内部装载Spring配置文件使用。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值