`

Spring的基础操作、IOC(控制反转)以及DI(依赖注入)的原理

    博客分类:
  • SSH
阅读更多

大名鼎鼎的Spring 大家都听过, spring 是一个开源框架, Spring 为简化企业级应用开发而生。使用 Spring 可以使简单的 JavaBean 实现以前只有 EJB 才能实现的功能。 Spring 是一个 DI (依赖注入)和 AOP (面向切面编程)容器框架。

 

Spring具体应用细节,以及与 struts hibernater 的整合。我们还没有学习到,今天算是 Spring 的基础操作和实现 IOC (控制反转)以及 DI (依赖注入)的原理。

 

 

一、spring 框架

Spring 框架是一个分层架构,由 7 个定义良好的模块组成。 Spring 模块构建在核心容器之上,核心容器定义了 创建、配置和管理 bean 的 方式,如图 1 所示。

wps_clip_image-22635

Spring框架概述

组成 Spring 框架的每个模块(或组件)都可以单独存 在,或者与其他一个或多个模块联合实现。每个模块的功能如下:

· 核心容器 核心容器提供 Spring 框架的基本功能。核心容器的主要组件是 BeanFactory ,它是工厂模式的实现。 BeanFactory 使用控制反转 ( IOC ) 模式将应用程序的配置和依赖性规范与实际的应用程序代码分开。

· Spring 上下文 Spring 上下文是一个配置文件,向 Spring 框架提供上下文信息。 Spring 上下文包括企业服务,例如 JNDI EJB 、电子邮件、国际化、校验和调度功能。

· Spring AOP 通过配置管理特性,Spring AOP 模块直接将面向方面的编程功能集 成到了 Spring 框架 中。所以,可以很容易地使 Spring 框架管理的任何对象支持 AOP Spring AOP 模块为基于 Spring 的应用程序中的对象提供了事务管理服务。通过使用 Spring AOP ,不用依赖 EJB 组件,就可以将声明性事务管理集成到应用程序中。

· Spring DAO JDBC DAO 抽象层提供了有意义的异常层次结构,可用该结构来管理异常处理和不同数据库供应商抛出的错误消息。异常层次结构简化了错误处理,并且 极大地降低了需要编写的异常代码数量(例如打开和关闭连接)。 Spring DAO 的面向 JDBC 的异常遵从通用的 DAO 异常层次结构。

· Spring ORM Spring 框架插入了若干个 ORM 框架,从而提供了 ORM 的对象关系工具,其中包括 JDO Hibernate iBatis SQL Map 。所有这些都遵从 Spring 的通用事务和 DAO 异常层次结构。

· Spring Web 模 块 Web 上下文模块建立在应用程序上下文模块之上,为基于 Web 的应用程序提供了上下文。所以, Spring 框架支持与 Jakarta Struts 的集成。 Web 模块还简化了处理多部分请求以及将请求参数绑 定到域对象的工作。

· Spring MVC 框架 MVC 框架是一个全功能的构建 Web 应用程序的 MVC 实现。通过策略接口, MVC 框架变成为高度可配置的, MVC 容纳了大量视图技术,其中包括 JSP Velocity Tiles iText POI

Spring 框架的功能可以用在任何 J2EE 服务器中,大多数功能也适用于不受管理的环境。 Spring 的核心要点是:支持不绑定到特定 J2EE 服务的可重用业务和数据访问对象。毫无疑问,这样的对象可以在不同 J2EE 环境 ( Web EJB )、独立应用程序、测试环境之间重用。

 

我们今天的重点内容是—— 核心容器。

 

二、HelloSpring

这个“HelloWorld! ”的经典程序,还要引领多长时 间?可能会一直下去吧。我们现在就开始编写一个 Spring HelloWorld! 程序,来学习一下 Spring 环境的搭建。

 

1. 安装Spring Eclipse 插件。

2. 新建立一个Java 工程,在工 程上右键 ->Spring Tools->Add Spring Project Nature

3. 导入“spring-framework-2.5.6.SEC01\dist\spring.jar ”和“ spring-framework-2.5.6.SEC01\lib\jakarta-commons\commons-logging.jar ”。我们使用的 Spring 的版本是 2.5 3.0 刚 刚出来。但 3.0 2.5 的区别不是很大。

4. 在工程中添加“HelloSpring.java ”:

package  cn.itcast.cc.spring;


public   class HelloSpring {

private String message ;

// 构造函数

public HelloSpring() {

System. out .println( "HelloSpring,Construct!" );

}

// Spring通过此方法注入属性值

public   void setMessage(String message) {

this . message = message;

}

// 打印消息

public   void hello() {

System. out .println( "Hello:" + this . message );

}

} 
 

5. 在“src ”目录下,新建一个“ applicationContext.xml ”文件。(在“ src ”目录上右键 ->New->Other->Spring->Spring Bean Definition ):

<? xml   version = "1.0"   encoding = "UTF-8" ?>


< beans   xmlns = "http://www.springframework.org/schema/beans"

xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation = "http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd" >

<!-- 描述一个Bean,name指定Bean的名称,class指定Bean类名 -->

< bean   name = "helloSpring"   class = "cn.itcast.cc.spring.HelloSpring" >

<!-- property设置属性值,name指定名称,value指定属性值 -->

< property   name = "message" value = "**Spring**"   />

</ bean >

</ beans > 
 

6. 添加测试类:

package  cn.itcast.cc.spring;


import org.springframework.context.ApplicationContext;

import org.springframework.context.support.ClassPathXmlApplicationContext;


public   class App {

public   static   void main(String[] args) {

// 创建应用程序环境

ApplicationContext appCon = new ClassPathXmlApplicationContext( "applicationContext.xml" );

// 获取名称为helloSpring的Bean

HelloSpring hs = (HelloSpring) appCon.getBean( "helloSpring" );

// 调用Bean的方法

hs.hello();

}

} 
 

7. 控制台输出:

 

指定Bean 的名称,可以使用 name ,也可以使用 id 。一般情况下建议使用 id ,因为 id XML 文件中是一个特殊的属性, XML 会自动校验 ID 的唯一性。

 

可能通过属性的setter 方法或着 Bean 的构造函数设置属性的值,但 setter 是比较常用的。使用构造函数设置属性的 值,使用“ < constructor-arg   value = "**Spring**" /> ”替换“ property ”元素。注意一定要有与之对应的构造方法。

 

从刚开始的Dao 接口到工厂模式再到 Spring 框架,都是为了实现更好的解耦。

三、Spring 的配置文件

1.引用 Bean

在应用中经常会遇见一个Bean 实体,将另一个 Bean 实体做为自己的属性。那么这个属性值我们在 XML 文件中应该如何指定呢? Property 有一个 ref 属性, ref 属性的值设置为指定 Bean 元素的名称即可。

 

2.内部 Bean

当一个Bean 实体只被用作另一个 Bean 的属性时。我们可以将这个 Bean 声明为内部 Bean 。内部 Bean 无须设置它的 id name 值,它被做为子元素嵌入在对应 property 元素中。

 

3.继承式 Bean

bean元素中“ depends-on ”属性用来指定父类。

Spring 允许将通用的 Bean 配置抽象出来, 组成一个父 Bean 。 继承这个父 Bean Bean 称为子 Bean

Bean 从父 Bean 中继承配置, 包括 Bean 的属性和在 <bean> 元素里的属性。

Bean 也可以覆盖从父 Bean 继承过来的配置。

Bean 可以作为配置模板, 也可以作为 Bean 实例。 若只想把父 Bean 作为模板, 可以设置 <bean> abstract 属性为 true , 这样 Spring 将不会实例化这个 Bean

并不是 <bean> 元素里的所有属性都会被继 承。 比如: autowire dependency-check abstract 等。

也可以忽略父 Bean class 属性, 让子 Bean 指定自己的类, 而共享相同的属性配置。 但此时 abstract 必须设为 true

 

4.设置集合属性

经常见到Bean 具有集合属性,在 hibernate XML 文件中也可以设置集合属性的值。

Spring 中可以通过一组内置的 xml 标签 ( 例如: <list> <set> <map>) 来配置集合属性。

需求: 序列号生成器需要使用多个后缀。 这些后缀使用 “- ” 作为分割, 附加在序列号后边。 这些后缀可以是任意的数据类型, 在拼接时将它们转换为字符串。

也可以使用“utility scheme ”工具,定义可重用的集合 设置,引时 xml 文件需要引 入特定的标签库,参照下面的内容。

 

5.检查属性

设置Bean 的“ dependency-check = "objects" ”属性,检查bean 中的所有属性是否通过 setter 方法注入了值。如果是通过构造方法注入,或没有注入都会抛异常。 Dependency-check 不检查属性值是否合法。

bean 中设置“ dependency-check = "objects" ”属性,它会检查所有属性。如果我们想要检查某一个属性怎么办?首先添加一个:

HelloSpring,Construct!

Hello:**Spring**

使用“ < context:annotation-config   /> ”时,beans 的元素属性内容为:

<bean class="org.springframework.beans.factory.annotation.RequiredAnnotationBeanPostProcessor" />

<context:annotation-config />

<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"

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

xsi:schemaLocation="http://www.springframework.org/schema/beans

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

http://www.springframework.org/schema/context

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

http://www.springframework.org/schema/util

http://www.springframework.org/schema/util/spring-util-2.5.xsd ">
 

然后在Bean setter 方法上添加“ @Required ”注解,这样 Spring 将检查被标“ @Required ”注解的属性。

如果使用的是JRE1.5 需要添加“ spring-framework-2.5.6.SEC01\lib\j2ee\common-annotations.jar jar

 

6.Bean 自动装配

Spring IOC 容器可以帮助自动装配 Bean 。需要做的仅仅是在 <bean> autowire 属性里指定自动装配的模式。

byType(根据类型自动 装配 ) : 若 IOC 容器中有多个与目标 Bean 类型一致的 Bean 。在这种情况下, Spring 将无法判定哪个 Bean 最合适该属性,所以不能执行自动装配。

byName(根据名称自动装配 ) : 必须将目标 Bean 的名称和属性名设置的完全相同。

constructor(通 过构造器自动装配 ) : 当 Bean 中存在多个构造器时, 此种自动装配方式将会很复杂。 不推荐使用。

 

四、Spring 的注解

通过Xml 文件配置应用程序是之前流行的方式,但不够直观和 便利。现在流行使用注解了。在 Spring2.5 (包括 2.5 )之后就开始支持注解了。

 

使用注解时,我们只需要将Spring 的配置文件内容设置为:

<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"

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

xsi:schemaLocation="http://www.springframework.org/schema/beans

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

http://www.springframework.org/schema/context

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

http://www.springframework.org/schema/util

http://www.springframework.org/schema/util/spring-util-2.5.xsd ">

     <context:annotation-config />

</beans>
 

 

 

@Component ”: 基本注解, 标识了一个受 Spring 管理的组件。

@Respository ”: 标识持久层组件。

@Service ”: 标识服务层(业务层)组件。

@Controller ”: 标识表现层组件。

 

@Autowired ”自动装配具有兼容类型的单个 Bean 属性。默认情况下, 所有使用 @Authwired 注解的属性都需要被设置。 当 Spring 找不到匹配 的 Bean 装配属性时, 会抛出异常, 若某一属性允许不被设置, 可以设置 @Authwired 注解的 required 属性为 false

构造器, 普通字段( 即使是非 public) , 一切具有参数的方法都可以应用 @Authwired 注解。

它可以应用在数组类型的属性上, 此时 Spring 将会把所有匹配的 Bean 进行自动装配。

它可以应用在集合属性上, 此时 Spring 读取该集合的类型信 息, 然后自动装配所有与之兼容的 Bean

它用在 java util Map 上 时, 若该 Map 的键值 为 String , 那么 Spring 将自动装配与之 Map 值类型兼容的 Bean , 此时 Bean 的名称作为键值。

默认情况下, 当 IOC 容器里存在多个类型兼容的 Bean 时, 通过类型的自动装配将无法工作。 此时可以在 @Qualifier 注解里提供 Bean 的名称。但该注解只能用于修饰字段, 不能用于修饰方法

 

@Resource ”通过名称自动装配 Bean 属性,若没有名称一致的装配类型一致的。

构造器, 普通字段( 即使是非 public) , 一切具有参数的方法都可以应用 @ Resource 注解。

默认情况下,Spring 将试着找出和属性名称相同的 Bean 。也可以在 @Resource 注解的 name 属性里指定 Bean 的名称。

 

五、Spring 高级特性

1.Bean的作用域

如果不为指定Bean 的作用域, Spring 默认( scope="singleton" )只维护一个 Bean 实例,所有调用同一 getBean(name) 的位置都返回同一实例。设 置 Bean 的作用域为“ scope="property" Spring 都返回一个对应 Bean 的新的实例。

 

2.Bean的初始化和销毁过程

在企业开发中,组件在使用之前往往需要执行一些特定类型的初始 化任务,其中包括打开文件,打开网络/ 数据 库连接,分配内存等。同样,当组件结束其生命周期时,也需要执行与之对应的销毁任务。

 

设置Bean 的初始化和销毁过程。“ @PostConstruct ”调用Bean 的初始化过程,当 Bean 创建后并设置属性值后会调标注了此注解的方法。“ @PreDestroy ”调用Bean 的销毁过程,当 Bean 被销前会调用标注了此注解的方法。

 

注意:当Spring 只维护一个 Bean 实例时, Bean 被销前会调用标注了“ @PreDestroy ”注解的方法,否则不会调用。

 

3.Bean 后置处理器

Bean后置处理器允许在调用初始化方法前后对 Bean 进行额外的处理。

Bean后置处理器对 IOC 容器里的所有 Bean 实例逐一处理,而非单一实例。其典型应用是:检 查 Bean 属性的正确性或根 据特定的标准更改 Bean 的 属性。

Bean 后置处理器而言,需要实现接口“ BeanPostProcessor ”。在初始化方法被调用前后,Spring 将把每个 Bean 实例分别传递给上述接口的以下两个方法:

postProcessAfterInitialization ”和 postProcessBeforeInitialization ”。

 

SpringIOC容器对 Bean 的生命周期进行管理的过程:

1).通过构造器或工厂方法 创建 Bean 实例

2). Bean 的属性设置值和对其他 Bean 的引用

3). Bean 实例传递给 Bean 后置处理器的 postProcessBeforeInitialization 方法

4).调用 Bean 的初始化方法

5). Bean 实例传递给 Bean 后置处理器的 postProcessAfterInitialization 方法

6).Bean可以使用了

7).当容器关闭时,调用 Bean 的销毁方法

 

注册Bean 后置处理器,只需要在配置文件里声明声明一个该 处理器的实例, ApplicationContext 会探测到实现了 BeanPostProcessor 接口的 Bean 并进行注册。

若初始化和销毁方法是通过添加生命周期注解@PostConstructor @PreDestory 实现的,则自定义的 Bean 后置处理器将无法工作。其原因是 CommonAnnotationBeanPostProcessor 的优先级比自定义的 Bean 后置处理器的优先级高。结果在对路径检查之前初始化方法已经被调用。

要定义Bean 后置处理器的处理顺序,需要让 Bean 后置处理器的实例实现 Ordered 或者 PriorityOrdered 接口,在 getOrder() 方法中返回顺序值。该方法返回的 数值越低优先级越高。另: PriorityOrdered 接口返回的顺序值总优先于 Ordered 接口返回的顺序值,而 CommonAnnotationBeanPostProcessor 实现了 PriorityOrdered 接口。

4.外部化 Bean 的配置

在配置文件里配置Bean 时,有时需要在 Bean 的配置里混入系统部署的细节信息 ( 例如:文件路径,数据源配置信息等 ) 。而这些部署细节实际上需要和 Bean 配置相分离。

 

Spring提供了一个 PropertyPlaceholderConfigurer BeanFactory 后置处理器,这个处理器允许用户将 Bean 配置的部分内容外移到属性文件中。可以在 Bean 配置文件里使用形式为 ${var} 的变量, PropertyPlaceholderConfigurer 从属性文件里加载属性,并使用这些属性来替换变量。

 

Spring2.0 中注册 PropertyPlaceholderConfigurer

<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">

<property name="location" value="c3p0.properties" />

</bean> 

 

Spring2.5 中可通过 <context:property-placeholder> ,简化注册 PropertyPlaceholderConfigurer

<context:property-placeholder location="classpath:c3p0.properties"/>

此时beans 的属性内容为:

<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.xsd

http://www.springframework.org/schema/context

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

 

1
0
分享到:
评论

相关推荐

    IOC控制反转&DI依赖注入

    该项目实现了简单的IOC技术思想和DI依赖注入

    Spring——IOC(控制反转)与DI(依赖注入).docx

    IOC与DI的理解及使用 控制反转IOC(Inversion of Control)是一种设计思想,DI(依赖注入)是实现IOC的一种方法 。... 在Spring中实现控制反转的是IOC容器 ,其 实现方法是依赖注入 (Dependency Injection,DI)

    Spring框架控制反转IOC和依赖注入DI详解

    本文介绍了Spring框架中的控制反转IOC和依赖注入DI,欢迎阅读,共同学习,一起进步。 Spring框架基础参考:深入学习Spring基础 文章目录一.入门程序和IOC简介二.IOC-控制反转三.DI-依赖注入四. IOC和DI五.Spring...

    基于框架的Web开发-IoC(控制反转)和DI(依赖注入)入门.doc

    1.2 IoC(控制反转)和DI(依赖注入)入门 1 传统的Java类 在工程下创建包ioc,在ioc包中创建类Test。(为了看起来清楚,将三个类写在了同一个Java文件中,其中唯一的public类为Test)。类的含义和关系如下: Car类...

    springioc和spring aop

    其中最常见的方式叫做依赖注入(Dependency Injection,简称DI),还有一种方式叫“依赖查找”(Dependency Lookup)。通过控制反转,对象在被创建的时候,由一个调控系统内所有对象的外界实体,将其所依赖的对象的...

    spring-zwz.zip

    spring一篇入门博文的配套资源,包含了第一个spring程序、IOC控制反转、DI依赖注入、静态代理、动态代理、AOP面向切面编程等源代码

    Spring_01_入门篇_依赖注入(控制反转)_XML

    此文档仅供初学者学习,包括Spring的依赖注入(控制反转)的详细实例。以三层贯穿实例(持久层、业务层、控制层),由MAIN方法直接调用测试用例。

    控制反转(IoC)与依赖注入(DI)1

    1. 软件系统在没有引IOC容器之前,如图1所示,对象A依赖于对象B,那么对象A在初始化或者 2. 软件系统在引IOC容器之后,这种情形就完全改变了,如图2所示

    我的Pro Spring 学习笔记 之二 控制反转(IoC)和依赖注入(DI), Spring初步

    源代码 博文链接:https://danielkwo.iteye.com/blog/40945

    Spring IOC的快速入门案例

    Spring IOC的快速入门案例 &gt;下载Spring的开发包 ...&gt;理解IOC控制反转和DI依赖注入 &gt;编写Spring核心配置文件 &gt;在程序中读取Spring配置文件,通过Spring框架获得Bean,完成相应操作 Spring 4.x的目录结构  

    Spring中依赖注入与容器

    依赖注入、IoC/DI Spring 框架(核心)IoC 容器 IoC:控制反转  DI:依赖注入  什么是依赖?一个组件(对象)的运行需要用到另一个组件(对象),称这种关系为依赖关系  举例:鱼依赖水,生命依赖空气、阳光、水...

    SSM框架的学习与应用-Java EE企业级应用开发学习记录-(第六天)初识Spring框架

    Spring框架简介:对Spring框架的基本概念进行介绍,包括依赖注入(DI)和面向切面编程(AOP)等核心特性,以及Spring的优点和在Java EE开发中的作用。 Spring IoC的控制反转实例:通过一个示例演示了使用Spring的...

    简单谈谈Spring Ioc原理解析

    学习过Spring框架的人一定都会听过Spring的IoC(控制反转) 、DI(依赖注入)这两个概念,对于初学Spring的人来说,总觉得IoC 、DI这两个概念是模糊不清的,是很难理解的,今天和大家分享网上的一些技术大牛们对Spring...

    spring.net依赖注入Demo

    spring.net是为.net开发者提供的一个控制反转操作框架也称作依赖注入。 此demo仅提供参考spring.net mvc+三层

    golang不到30行代码实现依赖注入的方法

    用java的人对于spring框架一定不会陌生,spring核心就是一个IoC(控制反转/依赖注入)容器,带来一个很大的优势是解耦。一般只依赖容器,而不依赖具体的类,当你的类有修改时,最多需要改动一下容器相关代码,业务代码...

    Spring 框架的IoC

    控制反转(IoC = Inversion of Control)

    spring第一天笔记

    包括spring的基本基础,如DI依赖注入,IOC控制反转,适合初学者

Global site tag (gtag.js) - Google Analytics