第 章 学习目的与学习要求 学习目的:深入了解Spring框架及模块,掌握基本配 置及IoC机制。 学习要求:扎实掌握Spring的核心配置及IoC机制, 熟练搭建Spring环境的流程,学会配置和管理bean。 本章主要内容 本章介绍Spring框架的结构概述,重点讲解SpringIoC 原理、bean的各种配置方式及作用域、使用BeanFactory和 ApplicationContext加载Spring配置和管理bean。 接下来讨论Spring框架,它是连接SpringMVC 与 MyBatis的桥梁,同时很好地处理了业务逻辑层。 3.rng简介 1 Spi Spring框架是一个分层架构,由7个定义好的模块组 成。Spring模块构建在核心容器之上,核心容器定义了创 建、配置和管理bean的方式,如图3-1所示。 组成Spring框架的每个模块(或组件)都可以单独存 在,或者与其他一个或多个模块联合实现。每个模块的功 能如下。 核心容器:提供Spring框架的基本功能。核心容器的 主要组件是BeanFactory,它是工厂模式的实现。 BeanFactory使用IoC模式将应用程序的配置和依赖性规 范与实际的应用程序代码分开。 Spring上下文:是一个配置文件,向Spring框架提供 上下文信息。Spring上下文包括企业服务,如JNDI 、EJB 、 电子邮件、国际化、校验和调度功能。 第3章 Spring技术和SpringIoC 图3-1 Spring 框架的模块 SpringAOP:通过配置管理特性,SpringAOP模块直接将面向方面的编程功能集成 到Spring框架中,所以可以很容易地使Spring框架管理的任何对象支持AOP 。SpringAOP模块为基于Spring的应用程序中的对象提供了事务管理服务。使用SpringAOP,不 依赖EJB组件,就可以将声明性事务管理集成到应用程序中。 SpringDAO:JDBCDAO(DataAcesObject)抽象层提供了有意义的异常层次结 构,可用该结构管理异常处理和不同数据库供应商抛出的错误消息。异常层次结构简化了 错误处理,并且极大地降低了需要编写的异常代码数量。SpringDAO的面向JDBC的异 常遵从通用的DAO异常层次结构。 SpringORM:Spring框架插入了若干个Object/RelationMapping框架,从而提供了 ORM的对象关系映射工具,其中包括JDO 、MyBatis和iBatisSQLMap。所有这些都遵从 Spring的通用事务和DAO异常层次结构。 SpringWeb模块:Web上下文模块建立在应用程序上下文模块之上,为基于Web的 应用程序提供了上下文。所以,Spring框架支持与JakartaSpringMVC的集成。Web模 块还简化了处理大部分请求以及将请求参数绑定到域对象的工作。 SpringMVC框架:MVC框架是一个全功能的构建Web应用程序的MVC实现。通 过策略接口,MVC框架变成高度可配置的,MVC容纳了大量视图技术,其中包括JSP 、 Velocity、Tiles、iText和POI 。 Spring框架的功能可以用在任何的J2EE服务器中,大多数功能也适用于不受管理的 环境。Spring的核心要点是:支持不绑定到特定J2EE服务的可重用业务和数据访问对 象。毫无疑问,这样的对象可以在不同J2EE环境(Web或EJB )、独立应用程序、测试环境 之间重用。 3.rngIoC 2 Spi 首先介绍SpringIoC这个最核心、最重要的概念。 Java高级框架应用开发与项目案例教程———Spring+SpringMVC+MyBatis 40 3.2.1 IoC的原理 IoC,直观地讲,就是由容器控制程序之间的关系,而非传统实现中由程序代码直接操 控。这也就是所谓“控制反转”的概念所在:控制权由应用代码中转到外部容器,控制权的 转移是所谓的反转。IoC还有另外一个名字:“依赖注入(DependencyInjection)”。从名字 上理解,所谓依赖注入,即组件之间的依赖关系由容器在运行期决定,形象地说,即由容器 动态地将某种依赖关系注入组件中。 下面通过一个生动形象的例子介绍IoC。 例如,一个女孩希望找到合适的男朋友,如图3-2所示。 可以有3种方式: (1)青梅竹马; (2)亲友介绍; (3)父母包办。 第一种方式是青梅竹马,如图3-3所示。 图3-2 一个女孩希望找到合适的男朋友 图3-3 青梅竹马 通过代码表示如下: public class Girl { void kiss(){ Boy boy=new Boy(); } } 第二种方式是亲友介绍,如图3-4所示。 图3-4 亲友介绍 通过代码表示如下: public class Girl { void kiss(){ Boy boy=BoyFactory.createBoy(); } } 第 3 章 Spring技术和SpringIoC 41 第三种方式是父母包办,如图3-5所示。 图3-5 父母包办 通过代码表示如下: public class Girl { void kiss(Boy boy){ //kiss boy boy.kiss(); } } 哪种方式为IoC呢? 虽然在现实生活中我们都希望青梅竹马,但在Spring世界里选 择的却是父母包办,它就是IoC,而这里具有控制力的父母就是Spring的所谓的容器概念。 典型的IoC如图3-6所示。 图3-6 典型的IoC IoC的3种依赖注入类型: 第一种是通过接口注射,这种方式要求类必须实现容器给定的一个接口,然后容器会 利用这个接口给这个类注射它所依赖的类。 public class Girl implements Servicable{ Kissable kissable; public void service(ServiceManager mgr) { kissable=(Kissable) mgr.lookup("kissable"); } public void kissYourKissable() { kissable.kiss(); } } Java高级框架应用开发与项目案例教程———Spring+SpringMVC+MyBatis 42 第二种是通过setter()方法注射,这种方式也是Spring推荐的方式。 public class Girl { private Kissable kissable; public void setKissable(Kissable kissable) { this.kissable=kissable; } public void kissYourKissable() { kissable.kiss(); } } 第三种是通过构造方法注射类,这种方式Spring同样给予了实现,它和通过setter() 方法一样,都在类里无任何侵入性,但是不是没有侵入性,只是把侵入性转移了。显然,第 一种方式要求实现特定的接口,侵入性非常强,不方便以后移植。 public class Girl { private Kissable kissable; public Girl(Kissable kissable) { this.kissable=kissable; } public void kissYourKissable() { kissable.kiss(); } } PicoContainer container=new DefaultPicoContainer(); container.registerComponentImplementation(Boy.class); container.registerComponentImplementation(Girl.class); Girl girl=(Girl) container.getComponentInstance(Girl.class); girl.kissYourKissable(); 3.2.2 BeanFactory SpringIoC设计的核心是org.springframework.beans包,它的设计目标是与JavaBean 第 3 章 Spring技术和SpringIoC 43 组件一起使用。这个包通常不是由用户直接使用,而是由服务器将其用作其他多数功能的 底层中介。下一个最高级抽象是BeanFactory接口,它是工厂设计模式的实现,允许通过 名称创建和检索对象。BeanFactory也可以管理对象之间的关系。 BeanFactory支持两个对象模型。 ● 单态模型:它提供了具有特定名称的对象的共享实例,可以在查询时对其进行检 索。Singleton是默认的,也是最常用的对象模型,对于无状态服务对象很理想。 ● 原型模型:它确保每次检索都会创建单独的对象。在每个用户都需要自己的对象 时,原型模型最适合。 bean工厂的概念是Spring作为IoC容器的基础,IoC将处理事情的责任从应用程序 代码转移到框架。Spring框架使用JavaBean属性和配置数据指出必须设置的依赖关系。 1.BeanFactory BeanFactory实际上是实例化、配置和管理众多bean的容器。这些bean通常彼此合 作,因而它们之间会产生依赖。BeanFactory使用的配置数据可以反映这些依赖关系(一些 依赖可能不像配置数据一样可见,而是在运行期作为bean之间程序交互的函数)。 一个BeanFactory可以用接口org.springframework.beans.factory.BeanFactory表示, 这个接口有多个实现。最常使用的简单的BeanFactory 实现是org.springframework. beans.factory.xml.XmlBeanFactory。(这里提醒一下:ApplicationContext是BeanFactory 的子类,所以大多数用户更喜欢使用ApplicationContext的XML形式。) 虽然大多数情况下,几乎所有被BeanFactory 管理的用户代码都不需要知道 BeanFactory,但是BeanFactory还是以某种方式实例化。可以使用下面的代码实例化 BeanFactory: InputStream is=new FileInputStream("beans.xml"); XmlBeanFactory factory=new XmlBeanFactory(is); 或者 ClassPathResource res=new ClassPathResource("beans.xml"); XmlBeanFactory factory=new XmlBeanFactory(res); 或者 ClassPathXmlApplicationContext appContext=new ClassPathXmlApplicationContext( new String[]{"applicationContext.xml", "applicationContext-part2.xml"}); //of course, an ApplicationContext is just a BeanFactory BeanFactory factory=(BeanFactory) appContext; 很多情况下,用户代码不需要实例化BeanFactory,因为Spring框架代码会做这件事。 例如,Web 层提供支持代码,在J2EE Web 应用启动过程中自动载入一个Spring ApplicationContext。这个声明过程在这里描述: 编程操作BeanFactory将会在后面提到,下面集中描述BeanFactory的配置。 一个最基本的BeanFactory配置由一个或多个它所管理的Bean定义组成。在一个 XmlBeanFactory中,根节点Beans中包含一个或多个Bean元素。 Java高级框架应用开发与项目案例教程———Spring+SpringMVC+MyBatis 44 ... ... ... 2.BeanDefinition 一个XmlBeanFactory中的Bean定义包括的内容有: (1)classname,这通常是Bean的真正的实现类。但是,如果一个Bean使用一个静态 工厂方法创建,而不是被普通的构造函数创建,那么这实际上就是工厂类的classname。 (2)Bean 行为配置元素,它声明这个Bean 在容器的行为方式(如prototype 或 singleton,自动装配模式,依赖检查模式,初始化和析构方法)。 构造函数的参数和新创建Bean需要的属性:举一个例子,一个管理连接池的Bean使 用的连接数目(既可以指定为一个属性,也可以作为一个构造函数参数),或者池的大小限 制和这个Bean工作相关的其他Bean:比如它的合作者(同样可以作为属性或者构造函数 的参数)。这也被叫作依赖。 上面列出的概念直接转化为组成Bean定义的一组元素。这些元素(见表3-1)都有更 详细的说明的链接。 表3-1 Bean定义的解释 特 性说 明特 性说 明 class Bean的类自动装配模式自动装配协作对象 id和name Bean的标识符(id与name) 依赖检查模式依赖检查 singleton或prototype Singleton的使用与否初始化模式生命周期接口 构造函数参数设置Bean的属性和合作者析构方法生命周期接口 Bean的属性设置Bean的属性和合作者 注意:Bean定义可以表示为真正的接口org.springframework.beans.factory.config. BeanDefinition以及它的各种子接口和实现。然而,绝大多数的用户代码不需要与 BeanDefinition直接接触。 第 3 章 Spring技术和SpringIoC 45 3.Bean类 class属性通常是强制性的,有两种用法。在绝大多数情况下,BeanFactory直接调用 Bean的构造函数创建一个Bean(相当于调用new的Java代码)。class属性指定了需要创 建的Bean的类。在比较少的情况下,BeanFactory调用某个类的静态的工厂方法创建 Bean。class属性指定了实际包含静态工厂方法的那个类。(至于静态工厂方法返回的 Bean的类型是同一个类,还是完全不同的另一个类,这并不重要。) 1)通过构造函数创建Bean 当使用构造函数创建Bean时,所有普通的类都可以被Spring使用并且和Spring兼 容。这就是说,被创建的类不需要实现任何特定的接口或者按照特定的样式进行编写,仅 指定Bean的类就足够了。然而,根据Bean使用的IoC类型,你可能需要一个默认的(空 的)构造函数。 另外,BeanFactory并不局限于管理真正的JavaBean,它也能管理任何你想让它管理的 类。虽然很多使用Spring的人喜欢在BeanFactory中用真正的JavaBean(仅包含一个默 认的(无参数的)构造函数,在属性后面定义相对应的setter()和getter()方法),但是在 BeanFactory中也可以使用特殊的非Bean样式的类。例如,如果需要使用一个遗留下来的 完全没有遵守JavaBean规范的连接池,不要担心,Spring同样能够管理它。 使用XmlBeanFactory可以像下面这样定义Beanclass: 至于为构造函数提供(可选的)参数,以及在对象实例创建后设置实例属性,将会在后 面叙述。 2)通过静态工厂方法创建Bean 当定义一个使用静态工厂方法创建的Bean,同时使用class属性指定包含静态工厂方 法的类,这时需要factory-method属性指定工厂方法名。Spring调用这个方法(包含一组 可选的参数)并返回一个有效的对象,之后这个对象就完全和构造方法创建的对象一样。 用户可以使用这样的Bean定义在遗留代码中调用静态工厂。 下面是一个Bean定义的例子,声明这个Bean要通过factory-method指定的方法创 建。注意,这个Bean定义并没有指定返回对象的类型,只指定包含工厂方法的类。在这个 例子中,createInstance必须是static()方法。 至于为工厂方法提供(可选的)参数,以及在对象实例被工厂方法创建后设置实例属 性,将会在后面叙述。 3)通过实例工厂方法创建Bean 使用一个实例工厂方法(非静态的)创建Bean和使用静态工厂方法非常类似,调用一 Java高级框架应用开发与项目案例教程———Spring+SpringMVC+MyBatis 46 个已存在的Bean(这个Bean应该是工厂类型)的工厂方法创建新的Bean。 使用这种机制,class属性必须为空,而且factory-bean属性必须指定一个Bean的名 字,这个Bean一定要在当前的Bean工厂或者父Bean工厂中,并包含工厂方法。而工厂方 法本身仍然要通过factory-method属性设置。 下面是一个例子: ... 虽然我们要在后面讨论设置Bean的属性,但是这个方法意味着工厂Bean本身能够被 容器通过依赖注射管理和配置。 4.Bean的标识符(id与name) 每个bean都有一个或多个id(也叫作标识符,或名字;这些名词说的是一回事)。这些 id在管理Bean的BeanFactory或ApplicationContext中必须是唯一的。一个Bean差不多 总是只有一个id,但是如果一个Bean有超过一个的id,那么另外的那些本质上可以认为是 别名。在 一个XmlBeanFactory中(包括ApplicationContext的形式),可以用id或者name 属性指定Bean的id(s),并且在这两个或其中一个属性中至少指定一个id。id属性允许指 定一个id,并且它在XMLDTD(定义文档)中作为一个真正的XML元素的ID 属性被标 记,所以XML解析器能够在其他元素指向它的时候做一些额外的校验。正因如此,用id 属性指定Bean的id是一个比较好的方式。然而,XML规范严格限定了在XMLID 中合 法的字符。通常这并不是真正限制你,但是如果有必要使用这些字符(在ID 中的非法字 符),或者想给Bean增加其他的别名,可以通过name属性指定一个或多个id(用逗号,或 者分号;分隔)。 5.Singleton的使用与否 Beans被定义为两种部署模式中的一种:singleton或non-singleton(后一种也叫作 prototype,尽管这个名词用得不精确)。如果一个Bean是singleton形态的,就只有一个共 享的实例存在,所有和这个Bean定义的id符合的Bean请求都会返回这个唯一的、特定的 实例。如 果Bean以non-singleton、prototype模式部署,对这个Bean的每次请求都会创建一 个新的Bean实例。这对于每个user需要一个独立的user对象这样的情况是非常理想的。 Beans默认被部署为singleton模式,除非有指定。把部署模式变为non-singletion (prototype)后,每次对这个Bean的请求都会导致一个新创建的Bean,而这可能并不是你 第 3 章 Spring技术和SpringIoC 47 真正想要的。所以,仅在绝对需要的时候才把模式改成prototype。 在下面这个例子中,两个Bean中的一个被定义为singleton,另一个被定义为nonsingleton( prototype)。客户端每次向BeanFactory请求都会创建新的exampleBean,而 AnotherExample仅被创建一次;每次对它请求都会返回这个实例的引用。 注意:当部署一个Bean为prototype模式,这个Bean的生命周期就会有稍许改变。 通过定义,Spring无法管理一个non-singleton/prototypeBean的整个生命周期,因为当它 创建之后,它被交给客户端,而且容器根本不再跟踪它了。当说起non-singleton/prototype Bean的时候,可以把Spring的角色想象成new操作符的替代品。之后的任何生命周期方 面的事情都由客户端处理。 3.2.3 ApplicationContext Beans包提供了以编程的方式管理和操控Bean的基本功能,而context包增加了 ApplicationContext,它以一种更加面向框架的方式增强了BeanFactory的功能。多数用户 可以以一种完全的声明式方式使用ApplicationContext,甚至不用手工创建它,但是却依赖像 ContextLoader的支持类,在J2EE的Web应用的启动进程中用它启动ApplicationContext。 当然,这种情况下还是可以以编程的方式创建一个ApplicationContext。 context包的基础是位于org.springframework.context包中的ApplicationContext接 口。它由BeanFactory接口集成而来,提供BeanFactory所有的功能。为了以一种更像面 向框架的方式工作,context包使用分层和有继承关系的上下文类,包括: ● MessageSource,提供对i18n消息的访问。 ● 资源访问,如URL和文件。 ● 事件传递给实现了ApplicationListener接口的Bean。 ● 载入多个(有继承关系)上下文类,使得每个上下文类都专注于一个特定的层次,如 应用的Web层。 因为ApplicationContext 包括BeanFactory 所有的功能,所以通常建议先于 BeanFactory使用,除有限的一些场合(如在一个Applet中,内存的消耗是关键的),每千 字节都很重要。接下来介绍ApplicationContext在BeanFactory的基本能力上增加的 功能。 1.使用MessageSource ApplicationContext接口继承MessageSource接口,所以提供了messaging功能(i18n 或者国际化)。它同NestingMessageSource 一起使用,就能处理分级的信息,这些是 Spring提供的处理信息的基本接口。这里定义的方法有如下3个。 StringgetMessage(Stringcode,Object[]args,Stringdefault,Localeloc):这个方法 是从MessageSource取得信息的基本方法。如果对于指定的locale没有找到信息,则使用 Java高级框架应用开发与项目案例教程———Spring+SpringMVC+MyBatis 48 默认的信息。传入的参数args用来代替信息中的占位符,这是通过Java标准类库的 MessageFormat实现的。 StringgetMessage(Stringcode,Object[]args,Localeloc):本质上和上一个方法一 样,区别只是没有默认值可以指定;如果找不到信息,就会抛出一个NoSuchMessage Exception。 StringgetMessage(MessageSourceResolvableresolvable,Localelocale):上面两个方 法使用的所有属性都封装到一个叫作MessageSourceResolvable的类中,可以通过这个方 法直接使用它。 当ApplicationContext被加载的时候,它会自动查找在context中定义的MessageSource Bean。这个Bean必须叫作messageSource。如果找到了这样一个Bean,所有对上述方法的 调用将会被委托给找到的messagesource。如果没有找到messagesource,ApplicationContext 将会尝试查它的父亲是否包含这个名字的Bean。如果有,它将会把找到的Bean作为 MessageSource。如果它最终没有找到任何信息源,一个空的StaticMessageSource将会被 实例化,使它能够接受上述方法的调用。 Spring目前提供了两个MessageSource的实现,分别是ResourceBundleMessageSource 和StaticMessageSource。两个都实现了NestingMessageSource,以便能够嵌套地解析信 息。StaticMessageSource很少被使用,但是它提供以编程的方式向source增加信息。 ResourceBundleMessageSource用得更多一些,下面是它的一个例子: format exceptions windows 这段配置假定你在classpath有3个resourcebundle,分别为format、exceptions和 windows。使用JDK 通过ResourceBundle解析信息的标准方式,任何解析信息的请求都 会被处理。 2.事件传递 ApplicationContext中的事件处理是通过ApplicationEvent类和ApplicationListener 接口提供的。如果上下文中部署了一个实现了ApplicationListener接口的Bean,每次一个 ApplicationEvent发布到ApplicationContext时,那个Bean就会被通知。实质上,这是标 准的Observer设计模式。Spring提供了3个标准事件,见表3-2。 第 3 章 Spring技术和SpringIoC 49 表3-2 内置事件 事 件解 释 ContextRefreshedEvent 当ApplicationContext已经初始化或刷新后发送的事件。这里的初始化意 味着所有的Bean被装载,singleton被预实例化,以及ApplicationContext 已准备好 ContextClosedEvent 当使用ApplicationContext的close()方法结束上下文的时候发送的事件。 这里的结束意味着singleton被销毁 RequestHandledEvent 一个与Web相关的事件,告诉所有的Bean一个HTTP请求已经被响应了 (这个事件将会在一个请求结束后被发送)。注意,这个事件只能应用于使 用了Spring的DispatcherServlet的Web应用 同样,也可以实现自定义的事件。通过调用ApplicationContext的publishEvent()方 法,并且指定一个参数,这个参数是你自定义的事件类的一个实例。下面看一个例子。 首先是ApplicationContext: black@list.org white@list.org john@doe.org spam@list.org 然后是实际的Bean: public class EmailBean implements ApplicationContextAware { /**the blacklist */ private List blackList; public void setBlackList(List blackList) { this.blackList=blackList; } public void setApplicationContext(ApplicationContext ctx) { this.ctx=ctx; } public void sendEmail(String address, String text) { if (blackList.contains(address)) { Java高级框架应用开发与项目案例教程———Spring+SpringMVC+MyBatis 50 BlackListEventevt=new BlackListEvent(address, text); ctx.publishEvent(evt); return; } //send email } } public class BlackListNotifier implement ApplicationListener{ /**notification address */ private String notificationAddress; public void setNotificationAddress(String notificationAddress) { this.notificationAddress=notificationAddress; } public void onApplicationEvent(ApplicationEvent evt) { if (evtinstanceofBlackListEvent) { //notify appropriate person } } } 3.在Spring中使用资源 很多应用程序都需要访问资源。Spring提供了一个清晰透明的方案,以一种协议无关 的方式访问资源。ApplicationContext接口包含一个方法(getResource(String))负责这项 工作。 Resource类定义了几个方法,见表3-3。这几个方法被所有的Resource实现所共享。 表3-3 资源功能 方 法解 释 getInputStream() 用InputStream 打开资源,并返回这个InputStream exists() 检查资源是否存在,如果不存在,则返回false isOpen() 如果这个资源不能打开多个流将会返回true。常见的资源实现一般返回false getDescription() 返回资源的描述,通常是全限定文件名或者实际的URL Spring提供了几个Resource的实现。它们都需要一个String表示的资源的实际位 置。依据这个String,Spring 将会自动为你选择正确的Resource 实现。当向 ApplicationContext请求一个资源时,Spring首先检查你指定的资源位置,之后寻找任何前 缀。根据不同的ApplicationContext的实现,不同的Resource实现可被使用的Resource 最好使用ResourceEditor配置,如XmlBeanFactory。 接下来看一个SpringIoC实例。 (1)新建Java项目,如图3-7所示。 第 3章 Spring技术和SpringIoC 图3-7 新建Java 项目 在Projectname 中输入Spring_IoC_demo,如图3-8所示。 图3-8 命名项目 Java高级框架应用开发与项目案例教程———Spring+SpringMVC+MyBatis (2)导入Spring项目依赖的jar包,右击Spring_IoC_demo项目,从弹出的快捷菜单中 选择ConfigureFacets→InstalSpringFacet,如图3-9所示。 图3-9 Install Spring Facet 界面1 单击Next按钮,不需修改,直到单击Finish按钮,如图3-10所示。 图3-10 Install Spring Facet 界面2 第 3 章Spring技术和SpringIoC (3)建立包结构。右击src,从弹出的快捷菜单中选择New→Package,如图3-11 所示。 图3-11 新建Package 在Name 处输入com.ascent,之后单击Finish按钮,如图3-12 所示。 图3-12 命名Package Java高级框架应用开发与项目案例教程———Spring+SpringMVC+MyBatis 54 (4)在src目录下编写配置文件applicationContext.xml,内容如下: (5)在com.ascent目录下分别编写Boy、Girl.java、Kissable.java和Test.java,代码 如下: //Boy.java package com.ascent; public class Boy implements Kissable{ public void kiss(){ System.out.println("This is Kiss Boy"); } } //Girl.java package com.ascent; public class Girl { private Kissable kissable; public void setKissable(Kissable kissable) { this.kissable=kissable; } public void kissYourKissable() { kissable.kiss(); } } //Kissable.java package com.ascent; 第 3 章 Spring技术和SpringIoC 55 public interface Kissable { public void kiss(); } //Test.java package com.ascent; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class Test { public static void main(String[]args) { ApplicationContext apc=new ClassPathXmlApplicationContext( "applicationContext.xml"); Girl g=(Girl) apc.getBean("girl"); g.kissYourKissable(); } } (6)右击Test类,从弹出的快捷菜单中选择RunAs→JavaApplication,如图3-13 所示。得 到如下结果: This is Kiss Boy 3.3 项目案例 3.3.1 学习目标 使用Spring框架,为eGov项目提供功能组件对象,并装配功能组件为应用上层提 供封装对象,在实践中学习如何使用ApplicationContext对象,获取Spring配置文件中 声明的功能组件。如果是在Web环境中,请使用WebApplicationContext对象替代 ApplicatiionContext对象。 3.3.2 案例描述 本章案例为eGov中一般用户浏览新闻信息中的两部分内容:头版头条新闻和综合新 闻。其中,头版头条需要取一条新闻数据,而综合新闻则需要按一定条件获取6条新闻 数据。获取头版头条的一条新闻数据和获取综合新闻的6条新闻数据为一个业务功能,用 Java中的一个类的一个方法实现,将两种结果合并到HashMap中。 Java高级框架应用开发与项目案例教程———Spring+SpringMVC+MyBatis 图3-13 运行class 3.3 案例要点 3. 用户输入浏览器的Web项目地址,请求到达SpringMVC 控制器,控制器再转向 index.sp页面。在index.sp中像调用普通Java功能类一样,使用JSTL 标签调用控制器 jj 然后再传给idx.s在 中的相应业务控制方法,获取头条新闻和综合新闻的数据集合, nejp, inejsp中完成头版头条新闻和综合新闻数据的处理。由于没有使用到SprngMVC 和 dx.iMyBatis,所以在这个案例中重点是Spring框架的搭建,以及如何使用SpringDI/IoC的依 赖注入和控制反转配置业务类,使用main() 方法模拟SpringMVC 控制器,借助 ApplicationContext对象获取业务对象,执行业务方法,将执行结果输出到控制台终端。 3.案例实施 3.4 (1)在MyEclipse中新建electroneJavaWeb项目。 (2)导入mysq-onco-aa5.47bn.ar到 lcnetrjv-1.-ij 项目buildpath中,如图3-14 所示。 (3)为项目添加Spring的支持 。 右击工程,从弹出的快捷菜单中选择Spring Tools→AddSpringRuntimeDependencies,如图3-15 所示。图3-14 导入mysql 驱动包 第3章 Spring技术和SpringIoC 图3-15 Add Spring Runtime Dependencies 界面1xSpringVersio1, x 单击Net按钮,无须修改,n为4.再单击Net按钮,如图316 所示。 图3-16 Add Spring Runtime Dependencies 界面2