`
zwh910621
  • 浏览: 143756 次
  • 性别: 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

分享到:
评论

相关推荐

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

    spring ioc容器初始化流程图 spring ioc容器依赖注入流程图 spring aop实现原理流程图

    springIoc实现原理

    spring ioc指的是控制反转,IOC容器负责实例化、定位、配置应用程序中的对象及建立这些对象间的依赖。交由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...

    SpringIoc示例代码

    SpringIoc示例代码,SpringIoc示例代码,SpringIoc示例代码,SpringIoc示例代码

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

    spring ioc思维导图源文件

    spring ioc思维导图,让自己快速、详尽地了解spring ioc知识。

    Spring ioc Spring ioc

    Spring ioc Spring ioc

    以注解方式模拟Spring IoC AOP

    以注解方式模拟Spring IoC AOP,了解Spring是如何实现的.

    Spring中IoC优点与缺点解析

    主要为大家详细解析了Spring中IoC优点与缺点,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

    Springioc注入Demo

    详细讲解了springioc的各种注入方式以及对应的java方式。讲解了springioc和DI的区别,以及注入特殊复杂的属性

    Spring IoC加载流程讲解

    Spring IoC加载流程讲解以及IoC思想和依赖倒置原则

    SpringIOC经典Demo

    SpringIOC经典Demo,绝对的经典.

    Spring Ioc 注解 依赖注入

    Spring Ioc 注解 依赖注入

    模拟spring ioc过程

    这是个模拟spring ioc的学习例子,是个java工程。有助于对aop和ioc的理解

    springioc的详细讲解

    spring的ioc容器详细讲解,理解springioc容器

    springioc加载流程图.pdf

    springioc加载流程图.pdf

    spring_ioc

    这是spring_ioc部分的内容。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。...

    Spring IOC基础jar包

    Spring IOC基础jar包

    Spring IoC实现

    Spring IoC实现Spring IoC实现Spring IoC实现Spring IoC实现

Global site tag (gtag.js) - Google Analytics