`
zwh910621
  • 浏览: 147289 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Spring IOC(二)

阅读更多

 

Spring bean 的封装机制

Spring 从核心而言,是一个 DI 容器,其设计哲学是提供一种无侵入式的高扩展性框架。即无需代码中涉及 Spring 专有类,即可将其纳入 Spring 容器进行管理。

作为对比, EJB 则是一种高度侵入性的框架规范,它制定了众多的接口和编码规范,要求实现者必须遵从。侵入性的后果就是,一旦系统基于侵入性框架设计开发,那么之后任何脱离这个框架的企图都将付出极大的代价。

为了避免这种情况,实现无侵入性的目标。 Spring 大量引入了 Java Reflection 机制,通过动态调用的方式避免硬编码方式的约束,并在此基础上建立了其核心组件 BeanFactory ,以此作为其依赖注入机制的实现基础。

org.springframework.beans 包中包括了这些核心组件的实现类,核心中的核心为 BeanWrapper BeanFactory 类。这两个类从技术角度而言并不复杂,但对于 Spring 框架而言,却是关键所在,如果有时间,建议对其源码进行研读,必有所获。

(1)BeanWrapper

Spring 中的核心接口:通过配置文件中的设定, java Bean 就可以在运行期动态创建对象并设定其属性 ( 依赖关系 )

(2)BeanFactory

Bean Factory ,顾名思义,负责创建并维护 Bean 实例

Bean Factory 负责根据配置文件创建 Bean 实例,可以配置的项目有:

<1> Bean 属性值及依赖关系(对其他 Bean 的引用)

<2> Bean 创建模式(是否 Singleton 模式,即是否只针对指定类维持全局唯一的实例)

<3> Bean 初始化和销毁方法

<4> Bean 的依赖关系

 

联合上面关于 BeanWrapper 的内容,我们可以看到, BeanWrapper 实现了针对单个 Bean 的属性设定操作。而 BeanFactory 则是针对多个 Bean 的管理容器,根据给定的配置文件, BeanFactory 从中读取类名、属性名 / 值,然后通过 Reflection 机制进行 Bean 加载和属性设定。

 

Spring 中, BeanFactory IOC 容器的核心接口。它的职责包括:实例化、定位、配置应用程序中的对象及建立这些对象间的依赖。

(3)ApplicationContext

BeanFactory 提供了针对 Java Bean 的管理功能,而 ApplicationContext 提供了一个更为框架化的实现(从上面的示例中可以看出, BeanFactory 的使用方式更加类似一个 API ,而非 Framework style )。 ApplicationContext 覆盖了 BeanFactory 的所有功能,并提供了更多的特性。此外, ApplicationContext 为与现有应用框架相整合,提供了更为开放式的实现(如对于 Web 应用,我们可以在 web.xml 中对 ApplicationContext 进行配置)。相对 BeanFactory 而言, ApplicationContext 提供了以下扩展功能:

<1> 国际化支持

我们可以在 Beans.xml 文件中,对程序中的语言信息(如提示信息)进行定义,将程序

中的提示信息抽取到配置文件中加以定义,为我们进行应用的各语言版本转换提供了极

大的灵活性。

<2> 资源访问

支持对文件和 URL 的访问。

<3> 事件传播

事件传播特性为系统中状态改变时的检测提供了良好支持。

<4> 多实例加载

可以在同一个应用中加载多个 Context 实例。

(4)Web Context

对于 Web 应用, Spring 提供了可配置的 Application Context 加载机制。

加载器目前有两种选择: ContextLoaderListener ContextLoaderServlet 。这两者在功能上完全等同,只是一个是基于 Servlet2.3 版本中新引入的 Listener 接口实现,而另一个基于 Servlet 接口实现。

开发中可根据目标 Web 容器的实际情况进行选择。

 

配置非常简单,在 web.xml 中增加:

<listener>

       <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>

</listener>

或:

<servlet>

       <servlet-name>context</servlet-name>

       <servlet-class>org.springframework.web.context.ContextLoaderServlet</servlet-class>

       <load-on-startup>1</load-on-startup>

</servlet>

 

通过以上配置, Web 容器会自动加载 /WEB-INF/applicationContext.xml 初始化 Application Context 实例,如果需要指定配置文件位置,可通过 context-param 加以指定:

<context-param>

       <param-name>contextConfigLocation</param-name>

       <param-value>/WEB-INF/myApplicationContext.xml</param-value>

</context-param>

 

配置完成之后,即可通过 WebApplicationContextUtils.getWebApplicationContext 方法在 Web 应用中获取 ApplicationContext 引用。

 

注入参数 (Injection Parameters)

(1) 简单的值注入

将简单的值注入到 beans 里面是很简单的。如果需要,只需要简单地在配置标记中指定值,将其封装在一个 <value> 标记中,默认情况, <value> 标记不仅能读取 String 值,而且也可以将这些值转换到任何原生数据类型或者原生封装类。

示例:

Bean

public class InjectSimple{

private String name;

private int age;

private float height;

private boolean isProgrammer;

private Long ageInSeconds;

//property set method……

}

配置 Bean

<bean id=”injectSimple” class=”com.bean.InjectSimple”>

<property name=”name”>

    <value>John Smith</value>

</property>

<property name=”age”>

    <value>35</value>

</property>

<property name=”height”>

    <value>1.78</value>

</property>

<property name=” isProgrammer”>

    <value>true</value>

</property>

<property name=” ageInSeconds”>

    <value>1103760000</value>

</property>

</bean>

 

(2) 在同一个工厂注入 Beans

Spring 允许使用 <ref> 标记将一个 bean 注入到另一个 bean 中。

 

示例

Bean

public class InjectRef{

private Oracle oracle;

public void setOracle(Oracle oracle){

    this. oracle = oracle;

}

}

配置 Bean

<bean id=”injectRef” class=”com.bean.InjectRef”>

<property name=”oracle”>

    <ref local=”oracle”/>

</property>

</bean>

<bean id=”oracle” class=”com.bean.Oracle”/>

注:

<ref> 标记使用 local 属性,那么意味着 <ref> 标记仅仅通过 bean id 属性查找,而不通过任何别名查找。通过别名查找可以使用 bean 属性。如:

<bean id=”injectRef” class=”com.bean.InjectRef”>

<property name=”oracle”>

    <ref bean=” wiseworm”/>

</property>

</bean>

<bean id=”oracle” name=”wiseworm” class=”com.bean.Oracle”/>

 

 

(3) 使用集合进行注入

很多时候,你的 Bean 需要访问对象的集合,而不是访问一个单一的 bean 或者值。因此,理所当然的, Spring 允许你在你的一个 bean 中注入一个对象的集合。使用集合很简单:你可以选择 <list><map><set> 或者 <props> 来描述 List Map Set 或者 Properties 的实例,然后你就像在其他注入中所用到的方式一样传递这些对象。这个 <props> 标记只允许传递 String 值,因为 Properties 类只允许 String 作为属性的值。当使用 <list> <map> 或者 <set> 时,你可以使用注入到属性时的任何可用标记,甚至可以是其他的集合标记。这样,允许你传递存储 Map List ,存储 Set Map ,甚至是像 List 存储 Map Map 存储 Set Set 中存储 List 这样的嵌套!

 

示例代码:

public class CollectionDI{

private Map map;

private Set set;

private List list;

private Properties props;

 

//setter method……

 

}

 

配置文件:

<bean  id=”collectionDI” class=”com.spring.CollectionDI”>

<property name=”map”>

  <map>

    <entry key=”key1”>

      <value>Lily</value>              //<ref bean=”user”/>

    </entry>

  </map>

</property>

 

<property name=”set”>

  <set>

    <value>Jack</value>               //<ref bean=”user”/>

  </set>

</property>

 

<property name=”list”>

  <list>

    <value>Tom</value>               //<ref bean=”user”/>

  </list>

</property>

 

<property name=”props”>

  <props>

    <prop key=”username”> 

Jack               // 只能给 properties 实例的每个属性指定一个 String 的值

</prop>

  </props>

</property>

 

</bean>

 

自动装配你的 Bean

如果你不喜欢自己将你的程序装配起来,你可以尝试让 Spring 自动装配。默认情况,自动装配是被关闭的。开启它,需要指定你想要使用哪种自动装配方法,给你想要自动装配的 bean 配置指定 autowire 属性。

 

Spring 支持四种自动装配模式:通过命名、通过类型、构造器或自动检测。

 

通过命名自动装配: Spring 尝试将每个属性连接到一个同名的 bean 上。因此,如果目标 bean 拥有一个叫做 foo 的属性而 Bean 工厂中定义了一个命名为 foo Bean ,那么 foo 这个 Bean 会被分配给目标的 foo 属性。

 

部分配置代码:

<bean  id=”foo”  class=”com.autowire.Foo”  autowire=”byName”/>

 

 

通过类型自动装配: Spring 试图将目标 bean 的每个属性与 Bean 工厂中对应的同类型的 bean 连接起来。如果在目标 bean 中有一个 String 类型的属性,而在 Bean 工厂中有 String 类型的 bean ,那么 Spring 会将 String bean 和目标类型的 String 属性连接起来。如果你在同一个 Bean 工厂中有多个相同的类型的 bean ,比如 String ,那么 Spring 不能确定使用哪个进行自动装配,而后会抛出异常。

 

部分配置代码:

<bean  id=”foo”  class=”com.autowire.Foo”  autowire=”byType”/>

 

 

构造器自动装配: 与通过类型的自动装配类似,只是它通过构造器代替 setter 进行注入。 Spring 试图最大数量地匹配构造器中包含的参数。比如,如果你的 bean 拥有两个构造器,一个接受一个 String ,另一个接受一个 String 和一个整数,而你的的 Bean 工厂中同时有 String 和整数 bean Spring 会使用那个接受两个参数的构器。

 

部分配置代码:

<bean  id=”foo”  class=”com.autowire.Foo”  autowire=”constructor”/>

 

 

自动检测自动装配: 通知 Spring 在构造器自动装配和通过类型的自动装配间进行选择。

 

部分配置代码:

<bean  id=”foo”  class=”com.autowire.Foo”  autowire=”autodetect”/>

 

注意:什么时候使用自动装配?

在大部分情况下,关于是否应该使用自动装配这个问题的答案当然是“不!”,虽然自动装配可以在小规模的程序中节省你的时间,但是它会让你养成坏习惯,在大规模的程序中弹性也不够。实际上对 bean 进行精确的定义并不会消耗你太多的工作,那样你通够从精确的语义,完全自由的属性命名还有规定要管理同一个类型的多少个实例这些地方受益。除了非常小的应用程序,无论如何也要绕开使用自动装配。

 

 Bean 继承

某些情况下,你也许需要定义多个实现了共用接口的相同类型的 bean 。这时,如果你希望这些 bean 共享一些配置但又有一些不同的设置,这会是个问题。保持共享配置同步的过程经常出错,在大项目中这样做还非常耗时。为了解决这个问题, Spring 允许你定义一个 <bean> Bean 工厂的其他 bean 处继承属性设置。如果需要,你可以重写需要的子 bean 中的任何一个属性的值,这使你可以进行完全的控制,父 bean 可以给你的每个 bean 提供一个基础配置。

 

配置代码示例:

 

<bean  id=”parentUserBean” class=”com.spring.UserBean”>

<property name=”name”>

  <value>Rob</value>

</property>

<property name=”age”>

  <value>23</value>

</property>

</bean>

 

<bean  id=”childUserBean” class=”com.spring.UserBean” parent=”parentUserBean” >

<property name=”age”>

  <value>21</value>

</property>

</bean>

 

程序中指定了 parent=”parentUserBean” ,表明 spring parentUserBean 视为 childUserBean 的父 bean ,在 childUserBean 中,设置了 age 属性,没有 name 属性的值, Spring 会把来自 parentUserBean 的值传递给 childUserBean

分享到:
评论

相关推荐

    springIoc实现原理

    **二、Spring Ioc容器** Spring Ioc容器是整个Spring框架的基石,它负责创建、配置和管理对象。容器通过读取XML、Java注解或Java配置类等方式,获取对象的定义信息,然后根据这些信息实例化对象并进行依赖注入。 *...

    实验一 Springioc基本操作.docx

    SpringIOC是Spring Framework中的核心组件之一,负责管理应用程序中的对象、依赖关系和生命周期。 在 Spring IOC 中,对象的创建和管理是通过 BeanFactory 或 ApplicationContext 实现的。BeanFactory 是 Spring ...

    springIOC手写框架分析

    springIOC手写框架分析springIOC手写框架分析springIOC手写框架分析springIOC手写框架分析springIOC手写框架分析springIOC手写框架分析springIOC手写框架分析springIOC手写框架分析springIOC手写框架分析springIOC...

    spring ioc模块手写demo

    spring ioc模块手写demospring ioc模块手写demospring ioc模块手写demospring ioc模块手写demospring ioc模块手写demospring ioc模块手写demospring ioc模块手写demospring ioc模块手写demospring ioc模块手写demo...

    spring ioc和aop原理流程图(详细)

    Spring 框架是Java开发中的核心框架,它主要由两个关键部分组成:IOC(Inversion of Control,控制反转)和AOP(Aspect Oriented Programming,面向切面编程)。这两个概念是Spring框架的核心特性,极大地简化了企业...

    Spring IoC加载流程讲解

    Spring IoC 加载流程讲解 在本节中,我们将对 Spring IoC 加载流程进行详细的讲解,并探讨 IoC 思想和依赖倒置原则的应用。 IoC 控制反转 IoC(Inversion of Control)是指在软件设计中,将对象实例的控制权从...

    spring Ioc容器配置

    spring Ioc容器配置 IOC容器数据源配置 &lt;!-- 配置数据源 --&gt; destroy-method="close"&gt; &lt;value&gt;org.gjt.mm.mysql.Driver &lt;value&gt;jdbc:mysql://localhost:3306/demo &lt;value&gt;root ...

    SpringIoc示例代码

    Spring IOC,全称Inversion of Control,即“控制反转”,是Spring框架的核心特性之一。在传统的Java应用程序中,对象的创建和管理通常由开发者自己控制。而在Spring IOC中,这种控制权被反转,对象的创建、初始化、...

    Spring中IoC优点与缺点解析

    Spring 中 IoC 优点与缺点解析 IoC(Inversion of Control)是 Spring 框架中的一种设计模式,它的主要思想是将对象的创建和管理交给容器,从而解耦合对象之间的依赖关系。今天,我们将详细解析 IoC 的优点和缺点。 ...

    spring ioc思维导图源文件

    Spring IOC(Inversion of Control,控制反转)是Spring框架的核心特性之一,它允许开发者将对象的创建和管理交给Spring容器来处理,从而使代码更加松耦合,更易于测试和维护。下面将详细介绍Spring IOC的基本概念、...

    spring ioc

    标题 "Spring IOC" 描述了我们讨论的核心主题——Spring 框架中的依赖注入(Inversion of Control,简称 IOC)机制。Spring 是一个广泛应用的 Java 应用开发框架,其核心特性之一就是IOC,它极大地简化了软件组件...

    SpringIOC经典Demo

    Spring IOC(Inversion of Control,控制反转)是Spring框架的核心特性,它极大地简化了Java应用的开发,通过将对象的创建和管理交由Spring容器来处理,开发者可以更专注于业务逻辑。下面,我们将深入探讨Spring IOC...

    Springioc注入Demo

    Spring IOC(Inversion of Control,控制反转)是Spring框架的核心特性,它将对象的创建和管理权交由Spring容器来负责,从而实现了依赖倒置,增强了代码的可测试性和可维护性。DI(Dependency Injection,依赖注入)...

    Spring IoC依赖包

    Spring IoC,全称为Inversion of Control,即控制反转,是Spring框架的核心特性之一。它是一种设计模式,改变了传统程序中的对象创建和管理的方式,将对象的生命周期管理交由Spring容器来负责,使得代码更加解耦,...

    springioc和spring aop

    Spring框架是Java开发中不可或缺的一部分,它通过提供两种核心特性——控制反转(IoC)和面向切面编程(AOP)来简化应用的构建。理解并掌握这两种技术对于任何Java开发者来说都至关重要。 **控制反转(IoC)**,也...

    Spring IOC.pdf

    Spring IOC,即Spring控制反转,是Spring框架的核心特性之一。控制反转(Inversion of Control,简称IoC)是一种设计原则,用于减少代码间的耦合,提高系统模块化和代码的重用性。在Spring框架中,IOC具体体现在对...

    Spring IoC源码深度剖析开源架构源码2021.pdf

    标题《Spring IoC源码深度剖析开源架构源码2021.pdf》和描述《Spring IoC源码深度剖析开源架构源码2021.pdf》表明该文档主要面向于分析Spring框架中控制反转(IoC)容器的核心源码,解析和理解其内部的工作机制及...

    Java反射_Spring IOC

    Java反射和Spring IOC是Java开发中的两个重要概念,它们在构建灵活、可扩展的应用程序时起着关键作用。本文将深入探讨这两个主题,并提供相关的学习资源。 首先,让我们了解一下Java反射。Java反射机制是Java语言的...

    Spring IoC讲解PPT

    **Spring 的 IoC 容器** IoC(Inversion of Control)即控制反转,是 Spring 的核心特性之一。在传统的编程模式中,对象之间存在依赖关系,程序员需要手动创建和管理这些对象。而在 Spring 中,IoC 容器负责管理和...

    Spring Ioc 注解 依赖注入

    #### 二、IoC容器概述 在传统的Java应用程序中,对象的创建和管理通常由程序员来完成。这种方式会导致代码之间存在高度耦合,难以维护。而Spring通过其IoC容器实现了对对象的创建、配置和管理过程的解耦,使得开发...

Global site tag (gtag.js) - Google Analytics