`

注入的方式

    博客分类:
  • J2EE
 
阅读更多

 

一、依赖注入概述

 

Dependency injection (DI) is a process whereby objects define their dependencies, that is, the other 

objects they work with,The container then injects those dependencies when it creates the bean. This 

process is fundamentally the inverse, hence the name Inversion of Control (IoC).DI exists in two major variants, Constructor-based dependency injection and Setter-based dependency injection.

 

 

二、依赖注入分类

 

1.基于构造函数的注入

 

  1)自动依据类型的动态绑定注入

 

No potential ambiguity exists, assuming that Bar and Baz classes are not related by inheritance. Thus 

the following configuration works fine, and you do not need to specify the constructor argument indexes and/or types explicitly in the <constructor-arg/> element.

 

<beans>

  <bean id="foo" class="x.y.Foo">

      <constructor-arg ref="bar"/>

      <constructor-arg ref="baz"/>

  </bean>

 

  <bean id="bar" class="x.y.Bar"/>

  <bean id="baz" class="x.y.Baz"/>

 

</beans>

 

2)指定类型的动态绑定注入

 

In the preceding scenario, the container can use type matching with simple types if you explicitly 

specify the type of the constructor argument using the type attribute. For example:

 

<bean id="exampleBean" class="examples.ExampleBean">

<constructor-arg type="int" value="7500000"/>

<constructor-arg type="java.lang.String" value="42"/>

</bean>

 

3)指定位置的绑定注入

 

Use the index attribute to specify explicitly the index of constructor arguments. For example:

 

<bean id="exampleBean" class="examples.ExampleBean">

<constructor-arg index="0" value="7500000"/>

<constructor-arg index="1" value="42"/>

</bean>

In addition to resolving the ambiguity of multiple simple values, specifying an index resolves ambiguity 

 

where a constructor has two arguments of the same type. Note that the index is 0 based.

 

4)指定参数名称的绑定注入

 

As of Spring 3.0 you can also use the constructor parameter name for value disambiguation:

 

<bean id="exampleBean" class="examples.ExampleBean">

<constructor-arg name="years" value="7500000"/>

<constructor-arg name="ultimateanswer" value="42"/>

</bean>

 

2.依据setter方法的注入

 

The following example shows a class that can only be dependency-injected using pure setter injection. This class is conventional Java. It is a POJO that has no dependencies on container specific interfaces, base classes or annotations.

 

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 setMovieFinder(MovieFinder movieFinder) {

      this.movieFinder = movieFinder;

  }

 

  // business logic that actually 'uses' the injected MovieFinder is omitted...

}

 

POJO类里面,必须有set方法。

 

三、注入值时的一些方法

 

 

1.

<bean id="myDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">

 

<!-- results in a setDriverClassName(String) call -->

<property name="driverClassName" value="com.mysql.jdbc.Driver"/>

<property name="url" value="jdbc:mysql://localhost:3306/mydb"/>

<property name="username" value="root"/>

<property name="password" value="masterkaoli"/>

</bean>

 

2.

The following example uses the p-namespace for even more succinct XML configuration.

 

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

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

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

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

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

 

<bean id="myDataSource" class="org.apache.commons.dbcp.BasicDataSource"

      destroy-method="close"

      p:driverClassName="com.mysql.jdbc.Driver"

      p:url="jdbc:mysql://localhost:3306/mydb"

      p:username="root"

      p:password="masterkaoli"/>

 

</beans>

The preceding XML is more succinct; however, typos are discovered at runtime rather than design time, unless you use an IDE such as IntelliJ IDEA or the SpringSource Tool Suite (STS) that support automatic property completion when you create bean definitions. Such IDE assistance is highly recommended.

 

3.

The idref elementThe idref element is simply an error-proof way to pass the id (string value - not a reference) of another bean in the container to a <constructor-arg/> or <property/> element.

 

<bean id="theTargetBean" class="..."/>

 

<bean id="theClientBean" class="...">

  <property name="targetName">

      <idref bean="theTargetBean" />

  </property>

</bean>

The above bean definition snippet is exactly equivalent (at runtime) to the following snippet:

 

<bean id="theTargetBean" class="..." />

 

<bean id="client" class="...">

  <property name="targetName" value="theTargetBean" />

</bean>

The first form is preferable to the second, because using the idref tag allows the container to validate 

at deployment time that the referenced, named bean actually exists. In the second variation, no 

validation is performed on the value that is passed to the targetName property of the client bean. 

Additionally, if the referenced bean is in the same XML unit, and the bean name is the bean id, you can use the local attribute, which allows the XML parser itself to validate the bean id earlier, at XML 

document parse time.

 

<property name="targetName">

 <!-- a bean with id 'theTargetBean' must exist; otherwise an exception will be thrown -->

 <idref local="theTargetBean"/>

</property>

</bean>

 

4.

 

Specifying the target bean through the parent attribute creates a reference to a bean that is in a 

parent container of the current container. The value of the parent attribute may be the same as either 

the id attribute of the target bean, or one of the values in the name attribute of the target bean, and 

the target bean must be in a parent container of the current one. You use this bean reference variant 

mainly when you have a hierarchy of containers and you want to wrap an existing bean in a parent 

container with a proxy that will have the same name as the parent 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"  <-- bean name is the same as 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 here -->

</bean>

 

5.

 

A <bean/> element inside the <property/> or <constructor-arg/> elements defines a so-called inner bean.

 

<bean id="outer" class="...">

<!-- instead of using a reference to a target bean, simply define the target bean inline -->

<property name="target">

  <bean class="com.example.Person"> <!-- this is the inner bean -->

    <property name="name" value="Fiona Apple"/>

    <property name="age" value="25"/>

  </bean>

</property>

</bean>

An inner bean definition does not require a defined id or name; the container ignores these values. It 

also ignores the scope flag. Inner beans are always anonymous and they are always scoped as prototypes. It is not possible to inject inner beans into collaborating beans other than into the enclosing bean.

 

6.集合注入

 

In the <list/>, <set/>, <map/>, and <props/> elements, you set the properties and arguments of the Java 

 

Collection types List, Set, Map, and Properties, respectively.

 

<bean id="moreComplexObject" class="example.ComplexObject">

<!-- results in a setAdminEmails(java.util.Properties) call -->

<property name="adminEmails">

  <props>

      <prop key="administrator">administrator@example.org</prop>

      <prop key="support">support@example.org</prop>

      <prop key="development">development@example.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="an entry" value="just some string"/>

      <entry key ="a ref" value-ref="myDataSource"/>

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

The value of a map key or value, or a set value, can also again be any of the following elements:Collection merging

As of Spring 2.0, the container supports the merging of collections. An application developer can define 

 

a parent-style <list/>, <map/>, <set/> or <props/> element, and have child-style <list/>, <map/>, <set/> or <props/> elements inherit and override values from the parent collection. That is, the child 

collection's values are the result of merging the elements of the parent and child collections, with the 

child's collection elements overriding values specified in the parent collection.This section on merging discusses the parent-child bean mechanism. Readers unfamiliar with parent and child bean definitions may wish to read the relevant section before continuing.

 

The following example demonstrates collection merging:

 

<beans>

<bean id="parent" abstract="true" class="example.ComplexObject">

  <property name="adminEmails">

      <props>

          <prop key="administrator">administrator@example.com</prop>

          <prop key="support">support@example.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@example.com</prop>

          <prop key="support">support@example.co.uk</prop>

      </props>

  </property>

</bean>

<beans>

Notice the use of the merge=true attribute on the <props/> element of the adminEmails property of the child bean definition. When the child bean is resolved and instantiated by the container, the resulting instance has an adminEmails Properties collection that contains the result of the merging of the child's adminEmails collection with the parent's adminEmails collection.

 

administrator=administrator@example.com

sales=sales@example.com

support=support@example.co.uk

 

The child Properties collection's value set inherits all property elements from the parent <props/>, and 

the child's value for the support value overrides the value in the parent collection.

 

7.Null and empty string values

 

Spring treats empty arguments for properties and the like as empty Strings. The following XML-based 

configuration metadata snippet sets the email property to the empty String value ("")

 

<bean class="ExampleBean">

<property name="email" value=""/>

</bean>

The preceding example is equivalent to the following Java code: exampleBean.setEmail(""). The <null/> 

 

element handles null values. For example:

 

<bean class="ExampleBean">

<property name="email"><null/></property>

</bean>

The above configuration is equivalent to the following Java code: exampleBean.setEmail(null).

 

8.XML shortcut with the p-namespace

 

The p-namespace enables you to use the bean element's attributes, instead of nested <property/> 

elements, to describe your property values and/or collaborating beans.Spring 2.0 and later supports extensible configuration formats with namespaces, which are based on an XML Schema definition. The beans configuration format discussed in this chapter is defined in an XML Schema document. However, the p-namespace is not defined in an XSD file and exists only in the core of Spring.

 

The following example shows two XML snippets that resolve to the same result: The first uses standard 

 

XML format and the second uses the p-namespace.

 

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

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

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

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

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

 

  <bean name="classic" class="com.example.ExampleBean">

      <property name="email" value="foo@bar.com"/>

  </bean>

 

  <bean name="p-namespace" class="com.example.ExampleBean"

        p:email="foo@bar.com"/>

</beans>

The example shows an attribute in the p-namespace called email in the bean definition. This tells Spring to include a property declaration. As previously mentioned, the p-namespace does not have a schema definition, so you can set the name of the attribute to the property name.This next example includes two more bean definitions that both have a reference to another bean:

 

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

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

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

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

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

 

  <bean name="john-classic" class="com.example.Person">

      <property name="name" value="John Doe"/>

      <property name="spouse" ref="jane"/>

  </bean>

 

  <bean name="john-modern"

      class="com.example.Person"

      p:name="John Doe"

      p:spouse-ref="jane"/>

 

  <bean name="jane" class="com.example.Person">

      <property name="name" value="Jane Doe"/>

  </bean>

</beans>

 

9.XML shortcut with the c-namespace

 

Similar to the Section 5.4.2.6, “XML shortcut with the p-namespace”, the c-namespace, newly introduced in Spring 3.1, allows usage of inlined attributes for configuring the constructor arguments rather then nested constructor-arg elements.Let's review the examples from Section 5.4.1.1, “Constructor-based dependency injection” with the c namespace:

 

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

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

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

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

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

 

  <bean id="bar" class="x.y.Bar"/>

  <bean id="baz" class="x.y.Baz"/>

 

  <-- 'traditional' declaration -->

  <bean id="foo" class="x.y.Foo">

      <constructor-arg ref="bar"/>

      <constructor-arg ref="baz"/>

      <constructor-arg value="foo@bar.com"/>

  </bean>

 

  <-- 'c-namespace' declaration -->

  <bean id="foo" class="x.y.Foo" c:bar-ref="bar" c:baz-ref="baz" c:email="foo@bar.com">

 

</beans>

For the rare cases where the constructor argument names are not available (usually if the bytecode was compiled without debugging information), one can use fallback to the argument indexes:

 

<-- 'c-namespace' index declaration -->

<bean id="foo" class="x.y.Foo" c:_0-ref="bar" c:_1-ref="baz">

 

10.Using depends-on

 

If a bean is a dependency of another that usually means that one bean is set as a property of another. Typically you accomplish this with the <ref/> element in XML-based configuration metadata. However, sometimes dependencies between beans are less direct; for example, a static initializer in a class needs to be triggered, such as database driver registration. The depends-on attribute can explicitly force one or more beans to be initialized before the bean using this element is initialized. The following example uses the depends-on attribute to express a dependency on a single bean:

 

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

 

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

To express a dependency on multiple beans, supply a list of bean names as the value of the depends-on attribute, with commas, whitespace and semicolons, used as valid delimiters:

 

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

 

11.Lazy-initialized beans

 

By default, ApplicationContext implementations eagerly create and configure all singleton beans as part of the initialization process. Generally, this pre-instantiation is desirable, because errors in the 

configuration or surrounding environment are discovered immediately, as opposed to hours or even days later. When this behavior is not desirable, you can prevent pre-instantiation of a singleton bean by marking the bean definition as lazy-initialized. A lazy-initialized bean tells the IoC container to create a bean instance when it is first requested, rather than at startup.

In XML, this behavior is controlled by the lazy-init attribute on the <bean/> element; for example:

 

<bean id="lazy" class="com.foo.ExpensiveToCreateBean" lazy-init="true"/>

 

<bean name="not.lazy" class="com.foo.AnotherBean"/>

 

When the preceding configuration is consumed by an ApplicationContext, the bean named lazy is not 

eagerly pre-instantiated when the ApplicationContext is starting up, whereas the not.lazy bean is 

eagerly pre-instantiated.However, when a lazy-initialized bean is a dependency of a singleton bean that is not lazy-initialized, the ApplicationContext creates the lazy-initialized bean at startup, because it must satisfy the singleton's dependencies. The lazy-initialized bean is injected into a singleton bean elsewhere that is not lazy-initialized.You can also control lazy-initialization at the container level by using the default-lazy-init attribute on the <beans/> element; for example:

 

<beans default-lazy-init="true">

  <!-- no beans will be pre-instantiated... -->

</beans>

 

分享到:
评论

相关推荐

    Spring三种注入方式(三)

    本篇主要介绍Spring中的三种注入方式,包括构造器注入、设值注入和接口注入。 **一、构造器注入** 构造器注入是通过构造函数来传递依赖对象的一种方式。当类有多个构造函数时,Spring会使用带有最多参数的构造函数...

    Spring的注入方式详解

    下面我们将详细探讨Spring 中的三种注入方式:接口依赖注入(Type1)、setter/getter 注入(Type2,也称为属性注入)和构造方法注入(Type3)。 1. **接口依赖注入(Type1)** 这种注入方式相对不常见,主要适用于...

    Spring三种注入方式(二)

    本篇主要介绍Spring中的三种注入方式,着重讲解在"Spring三种注入方式(二)"中的内容。我们将深入探讨setter注入,这是Spring中最常见的注入方式之一。 ### 一、setter注入 setter注入是通过Spring容器调用对象的...

    Spring三种注入方式(一)

    本篇主要介绍Spring中的三种注入方式,包括构造器注入、设值注入和接口注入。 首先,我们来看构造器注入。构造器注入是在创建对象时,通过构造器传递依赖对象。这种方式强制了对象在创建时就必须提供所有必要的依赖...

    mybatis 注入方式

    本篇文章将详细介绍 MyBatis 的注入方式,以帮助你更好地理解和应用这一强大的框架。 一、XML 配置文件注入 在 MyBatis 3.0 中,主要通过 XML 配置文件进行数据源和 SQL 映射的注入。以下是一个简单的例子: ```...

    Spring 三种依赖注入方式.doc

    Spring 三种依赖注入方式 Spring 框架中提供了多种依赖注入方式,其中最常用的三种依赖注入方式分别是接口注入、设值注入和构造函数注入。下面,我们将分别对这三种依赖注入方式进行详细的介绍和分析。 一、接口...

    spring的注入方式

    Spring提供了多种注入方式,包括set注入、构造注入和自动注入,让我们逐一深入探讨。 1. **Set注入** Set注入是最常见的注入方式,它通过setter方法来设置对象的依赖。首先,你需要在类中声明需要注入的属性,并...

    Spring IOC的注入方式总结

    综上所述,Spring的IOC机制提供了多种灵活的依赖注入方式,可以根据实际需求选择合适的方法。在实践中,通常推荐使用构造器注入,因为它能确保对象在创建时就具备完整状态,有助于提升代码的可读性和可测试性。同时...

    各种注入方式源码

    在IT安全领域,"注入方式"通常指的是攻击者利用应用程序处理输入数据时的漏洞,将恶意代码注入到系统中执行。这里的"各种注入方式源码"可能包含了多种常见的注入攻击技术的示例代码,比如SQL注入、命令注入、XSS(跨...

    spring学习:依赖注入的几种方式讨论

    Spring Boot引入了一种更智能的依赖注入方式——自动配置。自动配置是通过`@EnableAutoConfiguration`注解启动的,它根据项目中的类路径和特定条件自动配置Bean。例如,如果类路径下存在`MongoClient`的jar,Spring ...

    Spring注释 注入方式源码示例,Annotation

    要用注解注入方式,还需要在applicationContext.xml文件加入一行代码: &lt;context:component-scan base-package="Mode"&gt;&lt;/context:component-scan&gt; //表示在包mode下面的类将扫描带有@Component,@Controller,@Service...

    Spring中你不知道的注入方式编程开发技术共6页.pdf

    本资料“Spring中你不知道的注入方式编程开发技术共6页.pdf”深入探讨了一些不常见但实用的Spring注入方式。尽管描述中提到的文件是一个压缩包,但从其标题我们可以推测其内容可能包括以下几点: 1. **构造器注入**...

    Spring注入的方式

    本文将详细探讨Spring中的两种主要注入方式:构造器注入和setter注入,以及它们各自的特点和适用场景。 首先,让我们理解什么是依赖注入(Dependency Injection,简称DI)。在传统的编程模式中,一个类通常会直接...

    spring的三种注入方式

    Spring提供了三种主要的注入方式,分别是:构造器注入、setter注入(类型2)和基于注解的注入(类型3)。下面我们将详细探讨这三种注入方式及其应用场景。 ### 1. Setter注入 (Type2) setter注入是最常见的注入方式...

    Spring定义bean的三种方式和自动注入

    Spring提供两种主要的自动注入方式:`byName`和`byType`,以及更推荐的`@Autowired`注解。 - `byName`:根据Bean的属性名查找相同名称的Bean进行注入。 - `byType`:如果Bean的属性类型只有一个匹配的Bean,那么...

    java巩固练习Spring 的bean注入方式有几种demo例子

    本篇将深入探讨Spring框架中bean的几种注入方式,通过具体的demo实例来帮助你巩固理解和实践。 首先,我们来了解Spring中的bean注入主要有以下四种方式: 1. **设值注入(Setter Injection)**:这是最常见的一种...

    static静态变量使用@Value注入方式.md

    ### static静态变量使用@Value注入方式 #### 一、引言 在Java开发中,特别是基于Spring框架的应用程序中,开发者经常会遇到需要为类中的成员变量注入外部配置值的情况。Spring框架提供了多种注入机制,其中`@Value...

    spring的注入方式.doc

    详细介绍spring的三种注入方式,带有实例和图片

    Spring对集合的装配(各种集合类型的属性的注入方式)

    首先,我们来了解Spring支持的集合注入方式: 1. **基于XML的配置**: 在Spring的XML配置文件中,可以使用`&lt;list&gt;`, `&lt;set&gt;`, `&lt;map&gt;`和`&lt;props&gt;`元素来指定集合的元素。例如,要注入一个List,可以这样写: ```...

Global site tag (gtag.js) - Google Analytics