`

Spring学习笔记(三)之依赖

阅读更多
3.3. 依赖
3.3.1. 注入依赖
   DI主要有两种注入方式,即Setter注入和 构造器注入
3.3.1.1. Setter注入
   通过调用无参构造器或无参static工厂方法实例化bean之后,调用该bean的setter方法,即可实现基于setter的DI
public class SimpleMovieLister {
    // the SimpleMovieLister has a dependency on the MovieFinder
    private MovieFinder movieFinder;
    // a setter method so that the Spring container can 
    //'inject' a MovieFinder
    public void setMoveFinder(MovieFinder movieFinder) {
        this.movieFinder = movieFinder;
    }    
    // business logic that actually 'uses' the injected 
    //MovieFinder  is omitted...
}

3.3.1.2. 构造器注入
 
public class SimpleMovieLister {
      // the SimpleMovieLister has a dependency on the MovieFinder
    private MovieFinder movieFinder;
      // a constructor so that the Spring container 
      //can 'inject' a  MovieFinder
    public SimpleMovieLister(MovieFinder movieFinder) {
        this.movieFinder = movieFinder;
    }
    
    // business logic that actually 'uses' the injected 
    //MovieFinder is omitted...
  }

3.3.1.3. 一些例子
  示例一:
 
  <bean id="exampleBean" class="examples.ExampleBean">
     <!-- setter injection using the nested <ref/> element -->
     <property name="beanOne">
        <ref bean="anotherExampleBean"/>
     </property>
     <!-- setter injection using the neater 'ref' attribute -->
     <property name="beanTwo" ref="yetAnotherBean"/>
     <property name="integerProperty" value="1"/>
  </bean>
  <bean id="anotherExampleBean" class="examples.AnotherBean"/>
  <bean id="yetAnotherBean" class="examples.YetAnotherBean"/>


 
public class ExampleBean {

     private AnotherBean beanOne;
     private YetAnotherBean beanTwo;
     private int i;

     public void setBeanOne(AnotherBean beanOne) {
        this.beanOne = beanOne;
     }

     public void setBeanTwo(YetAnotherBean beanTwo) {
        this.beanTwo = beanTwo;
     }

     public void setIntegerProperty(int i) {
        this.i = i;
     }    
  }

 示例二:
 
<bean id="exampleBean" class="examples.ExampleBean">
     <!-- constructor injection using the nested <ref/> element -->
    <constructor-arg>
      <ref bean="anotherExampleBean"/>
   </constructor-arg>
   
    <!-- constructor injection using the neater 'ref' attribute -->
    <constructor-arg ref="yetAnotherBean"/> 

    <constructor-arg type="int" value="1"/>
 </bean>
  <bean id="anotherExampleBean" class="examples.AnotherBean"/>
 <bean id="yetAnotherBean" class="examples.YetAnotherBean"/>

 
  public class ExampleBean {
    private AnotherBean beanOne;
    private YetAnotherBean beanTwo;
    private int i;
    
    public ExampleBean(
       AnotherBean anotherBean, YetAnotherBean yetAnotherBean, int i)   {
       this.beanOne = anotherBean;
       this.beanTwo = yetAnotherBean;
       this.i = i;
    } 
  }


示例三:采用静态工厂方法取代构造方法
 
  <bean id="exampleBean" class="examples.ExampleBean"
      factory-method="createInstance">
    <constructor-arg ref="anotherExampleBean"/>
    <constructor-arg ref="yetAnotherBean"/>
    <constructor-arg value="1"/> 
 </bean>

 <bean id="anotherExampleBean" class="examples.AnotherBean"/>
 <bean id="yetAnotherBean" class="examples.YetAnotherBean"/>
 
public class ExampleBean {
    // a private constructor
    private ExampleBean(...) {
      ...
    }
    
    // a static factory method; the arguments to this method can be
    // considered the dependencies of the bean that is returned,
    // regardless of how those arguments are actually used.
    public static ExampleBean createInstance (
      AnotherBean anotherBean, YetAnotherBean yetAnotherBean, int i) {
        ExampleBean eb = new ExampleBean (...);
        // some other operations
        ...
        return eb;
    }
}

3.3.2. 构造器参数的解析
   构造器参数将根据类型来进行匹配。如果bean定义中的构造器参数类型明确,那么bean定义中的参数顺序就是对应构造器参数的顺序。
   当引用的bean类型已知,则匹配没有问题(如上述的例子)。但是当使用象<value>true<value>这样的简单类型时,Spring将无法决定该值的类型,因而仅仅根据类型是无法进行匹配的。
  package examples;
  public class ExampleBean {
      // No. of years to the calculate the Ultimate Answer
    private int years;
    
    // The Answer to Life, the Universe, and Everything
    private String ultimateAnswer;
      public ExampleBean(int years, String ultimateAnswer) {
        this.years = years;
        this.ultimateAnswer = ultimateAnswer;
    }
}


3.3.2.1. 构造器参数类型匹配
<bean id="exampleBean" class="examples.ExampleBean">
  <constructor-arg index="0" value="7500000"/>
  <constructor-arg index="1" value="42"/>
</bean>

3.3.2.2. 构造器参数的索引
<bean id="exampleBean" class="examples.ExampleBean">
  <constructor-arg index="0" value="7500000"/>
  <constructor-arg index="1" value="42"/>
</bean>

3.3.3. bean属性及构造器参数详解
3.3.3.1. 直接量(基本类型、Strings类型等。)
<bean id="myDataSource" destroy-method="close"
    class="org.apache.commons.dbcp.BasicDataSource">
  <!-- results in a setDriverClassName(String) call -->
  <property name="driverClassName">
    <value>com.mysql.jdbc.Driver</value>
  </property>
  <property name="url">
    <value>jdbc:mysql://localhost:3306/mydb</value>
  </property>
  <property name="username">
    <value>root</value>
  </property>
</bean>


3.3.3.1.1. idref元素

<bean id="theTargetBean" class="..."/>
<bean id="theClientBean" class="...">
    <property name="targetName">
        <idref bean="theTargetBean" />
    </property>
</bean>


如果被引用的bean在同一XML文件内,且bean名字就是bean id,那么可以使用local属性,此属性允许XML解析器在解析XML文件时来对引用的bean进行验证。
<property name="targetName">
   <!-- a bean with an id of 'theTargetBean' must exist, else an XML  exception will be thrown -->
   <idref local="theTargetBean"/>
</property>


3.3.3.2. 引用其它的bean(协作者)

<ref bean="someBean"/>


<ref local="someBean"/>


第三种方式是通过使用ref的parent属性来引用当前容器的父容器中的bean。parent属性值既可以是目标bean的id值,也可以是name属性值。而且目标bean必须在当前容器的父容器中。使用parent属性的主要用途是为了用某个与父容器中的bean同名的代理来包装父容器中的一个bean(例如,子上下文中的一个bean定义覆盖了他的父bean)。

<!-- in the parent context -->
<bean id="accountService" class="com.foo.SimpleAccountService">
    <!-- insert dependencies as required as here -->
</bean>


<!-- in the child (descendant) context -->
<bean id="accountService"  <-- notice that the name of this bean is the same as the name of the 'parent' bean
      class="org.springframework.aop.framework.ProxyFactoryBean">
      <property name="target">
          <ref parent="accountService"/>  <-- notice how we refer to the parent bean
      </property>
    <!-- insert other configuration and dependencies as required as here -->
</bean>


3.3.3.4. 集合
<bean id="moreComplexObject" class="example.ComplexObject">
  <!-- results in a setAdminEmails(java.util.Properties) call -->
  <property name="adminEmails">
    <props>
        <prop key="administrator">administrator@somecompany.org</prop>
        <prop key="support">support@somecompany.org</prop>
        <prop key="development">development@somecompany.org</prop>
    </props>
  </property>
  <!-- results in a setSomeList(java.util.List) call -->
  <property name="someList">
    <list>
        <value>a list element followed by a reference</value>
        <ref bean="myDataSource" />
    </list>
  </property>
  <!-- results in a setSomeMap(java.util.Map) call -->
  <property name="someMap">
    <map>
        <entry>
            <key>
                <value>yup an entry</value>
            </key>
            <value>just some string</value>
        </entry>
        <entry>
            <key>
                <value>yup a ref</value>
            </key>
            <ref bean="myDataSource" />
        </entry>
    </map>
  </property>
  <!-- results in a setSomeSet(java.util.Set) call -->
  <property name="someSet">
    <set>
        <value>just some string</value>
        <ref bean="myDataSource" />
    </set>
  </property>
</bean>


3.3.3.4.1. 集合合并


<beans>
   <bean id="parent" abstract="true" class="example.ComplexObject">
    <property name="adminEmails">
        <props>
            <prop  key="administrator">administrator@somecompany.com</prop>
            <prop key="support">support@somecompany.com</prop>
        </props>
    </property>
</bean>
<bean id="child" parent="parent">
    <property name="adminEmails">
        <!-- the merge is specified on the *child* collection definition -->
        <props merge="true">
            <prop key="sales">sales@somecompany.com</prop>
            <prop key="support">support@somecompany.co.uk</prop>
        </props>
    </property>
</bean>
<beans>


不同的集合类型是不能合并(如map和 list是不能合并的),否则将会抛出相应的Exception。merge属性必须在继承的子bean中定义,而在父bean的集合属性上指定的merge属性将被忽略。

3.3.3.4.2. 强类型集合(仅适用于Java5+)

public class Foo {
                
    private Map<String, Float> accounts;
    
    public void setAccounts(Map<String, Float> accounts) {
        this.accounts = accounts;
    }

}

<beans>
    <bean id="foo" class="x.y.Foo">
        <property name="accounts">
            <map>
                <entry key="one" value="9.99"/>
                <entry key="two" value="2.75"/>
                <entry key="six" value="3.99"/>
            </map>
        </property>
    </bean>
</beans>


3.3.3.5. Nulls

      注意区别空串

3.3.3.6. XML-based configuration metadata shortcuts

<property name="myProperty">
  <value>hello</value>
</property>

<constructor-arg>
  <value>hello</value>
</constructor-arg>

<entry key="myKey">
  <value>hello</value>
</entry>


等同于
<property name="myProperty" value="hello"/>

<constructor-arg value="hello"/>

<entry key="myKey" value="hello"/>


<property/>和<constructor-arg/>支持类似的简写属性ref,它可能用来替代整个内嵌的<ref/>元素。

<property name="myProperty">
  <ref bean="myBean">
</property>

<constructor-arg>
  <ref bean="myBean">
</constructor-arg>


等同于

<property name="myProperty" ref="myBean"/>


<constructor-arg ref="myBean"/>


map中entry元素的简写形式为key/key-ref 和 value /value-ref属性

<entry>
  <key>
    <ref bean="myKeyBean" />
  </key>
  <ref bean="myValueBean" />
</entry>

等同于
<entry key-ref="myKeyBean" value-ref="myValueBean"/>


3.3.3.7. 组合属性名称  

除了最后一个属性外,只要其他属性值不为null,组合或嵌套属性名是完全合法的
<bean id="foo" class="foo.Bar">
  <property name="fred.bob.sammy" value="123" />
</bean>


3.3.4. 使用depends-on


<bean id="beanOne" class="ExampleBean" depends-on="manager"/>

<bean id="manager" class="ManagerBean" />



若需要表达对多个bean的依赖,可以在'depends-on'中将指定的多个bean名字用分隔符进行分隔,分隔符可以是逗号、空格及分号等:
<bean id="beanOne" class="ExampleBean" depends-on="manager,accountDao">
  <property name="manager" ref="manager" />
</bean>
  <bean id="manager" class="ManagerBean" />
<bean id="accountDao" class="x.y.jdbc.JdbcAccountDao" />



3.3.5. 延迟初始化bean
ApplicationContext实现的默认行为就是在启动时将所有singleton bean提前进行实例化。提前实例化意味着作为初始化过程的一部分,ApplicationContext实例会创建并配置所有的singleton bean。
有时候这种默认处理可能并不是你想要的。如果你不想让一个singleton bean在ApplicationContext实现在初始化时被提前实例化,那么可以将bean设置为延迟实例化。一个延迟初始化bean将告诉IoC 容器是在启动时还是在第一次被用到时实例化。

<bean id="lazy" class="com.foo.ExpensiveToCreateBean" lazy-init="true">
    <!-- various properties here... -->
</bean>
  <bean name="not.lazy" class="com.foo.AnotherBean">
    <!-- various properties here... -->
</bean>


需要说明的是,如果一个bean被设置为延迟初始化,而另一个非延迟初始化的singleton bean依赖于它,那么当ApplicationContext提前实例化singleton bean时,它必须也确保所有上述singleton 依赖bean也被预先初始化,当然也包括设置为延迟实例化的bean。因此,如果Ioc容器在启动的时候创建了那些设置为延迟实例化的bean的实例,你也不要觉得奇怪,因为那些延迟初始化的bean可能在配置的某个地方被注入到了一个非延迟初始化singleton bean里面。

在容器层次中通过在<beans/>元素上使用'default-lazy-init'属性来控制延迟初始化也是可能的。如下面的配置:

<beans default-lazy-init="true">
    <!-- no beans will be eagerly pre-instantiated... -->
</beans>



3.3.6. 自动装配(autowire)协作者
[img]C:\Documents and Settings\Administrator\桌面\2222.bmp[/img]

3.3.6.1. 设置Bean使自动装配失效

<bean/>元素的 autowire-candidate属性可被设为false,这样容器在查找自动装配对象时将不考虑该bean

3.3.7. 依赖检查

dependency-check

[img]C:\Documents and Settings\Administrator\桌面\333.bmp[/img]
分享到:
评论

相关推荐

    Spring学习笔记(精华全记录)

    ### Spring学习笔记(精华全记录) #### Spring框架概述 Spring框架源自Rod Johnson的个人项目,最初于2002年末发布。Spring并非一开始就作为一个完整的框架出现,而是从一个项目逐步发展而来。随着项目的成熟,...

    Spring学习笔记+学习源码.zip

    这份"Spring学习笔记+学习源码.zip"资源包含了深入学习Spring及其相关技术的知识点,以及实践代码,对提升Spring技能将大有裨益。 首先,我们来详细讨论Spring框架的主要组件和功能: 1. **依赖注入(Dependency ...

    Spring学习笔记.zip

    依赖注入是Spring框架的核心特性之一,它允许开发者在运行时将对象及其依赖关系解耦。通过DI,组件不再直接创建它所依赖的对象,而是由容器负责创建和管理这些对象,并将它们注入到需要的地方。这有助于提高代码的可...

    Spring学习笔记&源码

    本资料“Spring学习笔记&源码”是基于网易云课堂黑马程序员的Spring四天精通课程,旨在帮助学习者深入理解和实践Spring框架。 笔记部分可能会涵盖以下内容: 1. **Spring概述**:介绍Spring框架的历史、特点和主要...

    Spring框架学习笔记

    这份"Spring框架学习笔记"涵盖了Spring框架的基础知识、核心组件以及高级特性,对于初学者来说是一份宝贵的资料。 一、Spring框架概述 Spring框架是为了解决企业应用开发的复杂性而设计的,它提供了一个全面的基础...

    javaSpring学习笔记

    在“Java Spring学习笔记”中,你将找到对Spring框架的全面介绍,包括IoC(控制反转)和DI(依赖注入)原理、AOP(面向切面编程)、Spring MVC、Spring Boot等核心内容。每个主题都结合了理论知识和实际示例,帮助你...

    Spring学习笔记.doc

    ### Spring学习笔记知识点详解 #### 一、Spring框架概述 **1.1 什么是Spring** Spring框架是一个开源的轻量级应用框架,主要用于简化企业级应用程序的开发过程。它的核心特性在于提供了一种灵活的方式来组织和...

    Spring 学习笔记三

    《Spring 学习笔记三——深入理解Spring框架》 在我们的Spring学习旅程中,这篇笔记将带领大家更深入地探讨Spring框架的核心特性及其工作原理。Spring作为Java开发中广泛使用的轻量级框架,其强大的功能和灵活性...

    spring学习笔记

    ### Spring学习笔记知识点详解 #### 一、Spring框架概述 **Spring** 是一个开源的、分层的企业级应用开发框架,旨在简化Java EE应用程序的开发。它的主要目标是提高开发效率,减少耦合度,并提供一种更为简洁的...

    spring指南学习笔记

    标题和描述均提到了“spring指南学习笔记”,这意味着文档聚焦于Spring框架的学习心得与关键概念。Spring是一个开源的Java企业级应用框架,以其强大的依赖注入(Dependency Injection, DI)和面向切面编程(Aspect ...

    Spring 学习笔记《依赖注入》源文件

    总结来说,Spring的依赖注入机制是其核心特性之一,它极大地提升了代码的可测试性和可维护性。通过对依赖的解耦,开发者可以更专注于业务逻辑,而不是对象的创建和管理。在实际项目中,结合使用构造器和setter注入,...

    springcloud学习笔记.pdf

    Spring Cloud 学习笔记 本笔记主要介绍了从单体架构到微服务架构的演变过程,以及 Spring Cloud 中的微服务架构搭建。下面是本笔记的详细知识点总结: 一、单体架构 单体架构是指整个系统只有一个工程,打包往往...

    SPRING学习笔记2

    Spring学习笔记2涵盖了Spring框架的核心概念和重要特性,旨在帮助开发者深入理解并熟练掌握Spring的使用。 1. **依赖注入(Dependency Injection, DI)**:这是Spring最核心的设计原则,它允许对象之间的依赖关系在...

    SpringCloud学习笔记

    【SpringBoot核心特性】 SpringBoot是Spring框架的一个扩展,它旨在简化Spring应用程序的开发过程,...这份学习笔记涵盖了SpringBoot的基础特性和SpringCloud的负载均衡实践,对于深入理解这两个技术有极大的帮助。

    马士兵老师spring框架学习笔记

    马士兵老师是知名的Java教育专家,他的Spring框架学习笔记深入浅出,对于初学者和进阶者来说都是一份宝贵的资源。这份笔记涵盖了Spring的核心概念、配置、AOP(面向切面编程)、DI(依赖注入)等关键知识点。 1. **...

    Spring学习笔记(6)----编码剖析Spring依赖注入的原理

    本篇学习笔记将深入剖析Spring依赖注入的原理,通过源码分析帮助我们理解这一核心机制。 首先,依赖注入允许我们解耦组件之间的关系,使得各个组件可以独立地进行开发、测试和维护。在Spring中,DI主要通过两种方式...

    Spring 学习笔记 spring帮助文档

    在本篇Spring学习笔记中,我们将深入探讨Spring的基本概念,包括bean的配置、依赖注入、IOC容器以及Bean的实例化方式。 首先,Spring中的核心概念是bean。Bean是Spring框架中的基本构建块,它们是被管理的对象,...

    Spring学习笔记

    ### Spring学习笔记:深入理解AOP与Annotation驱动的动态代理 #### 核心知识点解析: 在探讨Spring框架中AOP(面向切面编程)及基于Annotation的动态代理之前,我们首先需要了解AOP的基本概念及其在Spring中的实现...

Global site tag (gtag.js) - Google Analytics