依赖注入的详细配置

前端之家收集整理的这篇文章主要介绍了依赖注入的详细配置前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

Dependencies and configuration in detail

直接代码

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

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

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

    <!-- typed as a java.util.Properties -->
    <property name="properties">
        <value>
            jdbc.driver.className=com.MysqL.jdbc.Driver
            jdbc.url=jdbc:MysqL://localhost:3306/mydb
        </value>
    </property>
</bean>

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

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

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

<bean id="client" class="...">
    <property name="targetName" value="theTargetBean" />
</bean>

<property name="targetName">
    <!-- a bean with id theTargetBean must exist; otherwise an exception will be thrown -->
    <idref bean="theTargetBean"/>
</property>

References to other beans (collaborators)

引用其他bean(collaborators)


<ref bean="someBean"/>
<!-- 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>


Inner beans

A<bean/>element inside the<property/>or<constructor-arg/>elements defines a so-calledinner 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 thescopeflag. Inner beans arealwaysanonymous and they arealwayscreated with the outer bean. It isnotpossible to inject inner beans into collaborating beans other than into the enclosing bean.

Collections

In the<list/>,<set/>,<map/>,and<props/>elements,you set the properties and arguments of the JavaCollectiontypesList,Set,Map,andProperties,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:

bean | ref | idref | list | set | map | props | value | null
Collection merging

The Spring container also supports themergingof collections. An application developer can define a parent-style<list/>,<set/>or<props/>element,and have child-style<list/>,<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 therelevant sectionbefore 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 themerge=trueattribute on the<props/>element of theadminEmailsproperty of thechildbean definition. When thechildbean is resolved and instantiated by the container,the resulting instance has anadminEmailsPropertiescollection that contains the result of the merging of the child’sadminEmailscollection with the parent’sadminEmailscollection.

administrator=administrator@example.com
sales=sales@example.com
support=support@example.co.uk


The childPropertiescollection’s value set inherits all property elements from the parent<props/>,and the child’s value for thesupportvalue overrides the value in the parent collection.

This merging behavior applies similarly to the<list/>,and<set/>collection types. In the specific case of the<list/>element,the semantics associated with theListcollection type,that is,the notion of anorderedcollection of values,is maintained; the parent’s values precede all of the child list’s values. In the case of theMap,andPropertiescollection types,no ordering exists. Hence no ordering semantics are in effect for the collection types that underlie the associatedMap,andPropertiesimplementation types that the container uses internally.

Limitations of collection merging

You cannot merge different collection types (such as aMapand aList),and if you do attempt to do so an appropriateExceptionis thrown. Themergeattribute must be specified on the lower,inherited,child definition; specifying themergeattribute on a parent collection definition is redundant and will not result in the desired merging.

Strongly-typed collection

With the introduction of generic types in Java 5,you can use strongly typed collections. That is,it is possible to declare aCollectiontype such that it can only containStringelements (for example). If you are using Spring to dependency-inject a strongly-typedCollectioninto a bean,you can take advantage of Spring’s type-conversion support such that the elements of your strongly-typedCollectioninstances are converted to the appropriate type prior to being added to theCollection.

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>

When theaccountsproperty of thefoobean is prepared for injection,the generics information about the element type of the strongly-typedMap<String,Float>is available by reflection. Thus Spring’s type conversion infrastructure recognizes the varIoUs value elements as being of typeFloat,and the string values9.99,2.75,and3.99are converted into an actualFloattype.

Null and empty string values

Spring treats empty arguments for properties and the like as emptyStrings. The following XML-based configuration Metadata snippet sets the email property to the emptyStringvalue ("").

<bean class="ExampleBean">
    <property name="email" value=""/>
</bean>

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

<bean class="ExampleBean">
    <property name="email">
        <null/>
    </property>
</bean>

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

XML shortcut with the p-namespace

The p-namespace enables you to use thebeanelement’s attributes,instead of nested<property/>elements,to describe your property values and/or collaborating beans.

Spring supports extensible configuration formatswith namespaces,which are based on an XML Schema definition. Thebeansconfiguration 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>

As you can see,this example includes not only a property value using the p-namespace,but also uses a special format to declare property references. Whereas the first bean definition uses<property name="spouse" ref="jane"/>to create a reference from beanjohnto beanjane,the second bean definition usesp:spouse-ref="jane"as an attribute to do the exact same thing. In this casespouseis the property name,whereas the-refpart indicates that this is not a straight value but rather a reference to another bean.

Note

The p-namespace is not as flexible as the standard XML format. For example,the format for declaring property references clashes with properties that end inRef,whereas the standard XML format does not. We recommend that you choose your approach carefully and communicate this to your team members,to avoid producing XML documents that use all three approaches at the same time.

XML shortcut with the c-namespace

Similar to thethe section called “XML shortcut with the p-namespace”,thec-namespace,newly introduced in Spring 3.1,allows usage of inlined attributes for configuring the constructor arguments rather then nestedconstructor-argelements.

Let’s review the examples fromthe section called “Constructor-based dependency injection”with thec: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>

Thec:namespace uses the same conventions as thep:one (trailing-reffor bean references) for setting the constructor arguments by their names. And just as well,it needs to be declared even though it is not defined in an XSD schema (but it exists inside the Spring core).

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

Due to the XML grammar,the index notation requires the presence of the leading_as XML attribute names cannot start with a number (even though some IDE allow it).

In practice,the constructor resolutionmechanismis quite efficient in matching arguments so unless one really needs to,we recommend using the name notation through-out your configuration.

Compound property names

You can use compound or nested property names when you set bean properties,as long as all components of the path except the final property name are notnull. Consider the following bean definition.

<bean id="foo" class="foo.Bar">
    <property name="fred.bob.sammy" value="123" />
</bean>

Thefoobean has afredproperty,which has abobproperty,which has asammyproperty,and that finalsammyproperty is being set to the value123. In order for this to work,thefredproperty offoo,and thebobproperty offredmust not benullafter the bean is constructed,or aNullPointerExceptionis thrown.

4.4.3Using 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/>elementin 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. Thedepends-onattribute can explicitly force one or more beans to be initialized before the bean using this element is initialized. The following example uses thedepends-onattribute 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 thedepends-onattribute,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" />
Note

Thedepends-onattribute in the bean definition can specify both an initialization time dependency and,in the case ofsingletonbeans only,a corresponding destroy time dependency. Dependent beans that define adepends-onrelationship with a given bean are destroyed first,prior to the given bean itself being destroyed. Thusdepends-oncan also control shutdown order.

猜你在找的设计模式相关文章