Dependencies and configuration in detail

3.4.2 Dependencies and configuration in detail(详细介绍依赖以及配置)

As mentioned in the previous section, you can define bean properties and constructor arguments as references to other managed beans (collaborators), or as values defined inline. Spring’s XML-based configuration metadata supports sub-element types within its and elements for this purpose.


如上一节所述,您可以将bean属性和构造函数参数定义为对其他受管Bean(协作者)的引用,也可以定义为inline。Spring基于XML的配置元数据的使用<property/><constructor-arg/> 子节点来支持。

Straight values (primitives, Strings, and so on)

The value attribute of the element specifies a property or constructor argument as a human-readable string representation. Spring’s conversion service is used to convert these values from a String to the actual type of the property or argument.


<property/> 节点中元素的值时指定的属性或者构造参数的可视化(以String 形式标识),
Spring的 转换服务用于将这些值转换String为属性或参数的实际类型。

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

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


以下示例使用p命名空间进行更简洁的XML配置。

<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 Spring Tool Suite (STS) that support automatic property completion when you create bean definitions. Such IDE assistance is highly recommended.


前面的XML是更简洁; 但是,在运行时可能出现错位u,,除非您在创建bean定义时使用支持自动属性完成的IDE(如IntelliJ IDEA或Spring Tool Suite(STS))。强烈建议您使用此类IDE协助。

You can also configure a java.util.Properties instance as:


您还可以将java.util.Properties实例配置为:

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

The Spring container converts the text inside the element into a java.util.Properties instance by using the JavaBeans PropertyEditor mechanism. This is a nice shortcut, and is one of a few places where the Spring team do favor the use of the nested element over the value attribute style.


Spring容器通过使用JavaBeans 机制将元素内的文本转换为 java.util.Properties实例PropertyEditor。这是一个很好的捷径,而且是Spring团队赞成在value属性样式中使用嵌套元素的几个地方之一。

The idref element

The 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 or element.


该idref元素只是将容器中另一个bean 的id(字符串值 - 而不是引用)传递给一个或多个 元素的方法。

<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定义片段与以下代码片段完全相同(在运行时)

<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. Typos are only discovered (with most likely fatal results) when the client bean is actually instantiated. If the client bean is a prototype bean, this typo and the resulting exception may only be discovered long after the container is deployed.


第一种形式优于第二种形式,因为使用该idref标签可以允许容器在部署时验证引用的,也就是说命名的bean实际存在。在第二个变体中,不会进行验证。当clientbean真正上被实例化时,只发现错误(最可能是致命的结果)。如果client bean是原型 bean,则此类型错误和生成的异常只能在容器部署后才能被发现。

The local attribute on the idref element is no longer supported in the 4.0 beans xsd since it does not provide value over a regular bean reference anymore. Simply change your existing idref local references to idref bean when upgrading to the 4.0 schema.
A common place (at least in versions earlier than Spring 2.0) where the element brings value is in the configuration of AOP interceptors in a ProxyFactoryBean bean definition. Using elements when you specify the interceptor names prevents you from misspelling an interceptor id.

注意:


4.0 beans xsd不在支持 idref元素的local属性,因为它不在提供对普通值bean引用。只需将现有idref local引用更改为idref bean就可以升级到升级到4.0模式。
其中一个共同的地方(至少早于Spring 2.0版本)元素带来的值在配置AOP拦截在 ProxyFactoryBeanbean定义。当指定拦截器名称时使用元素可防止拼写错误。

References to other beans (collaborators)(引用其他bean)

The ref element is the final element inside a or definition element. Here you set the value of the specified property of a bean to be a reference to another bean (a collaborator) managed by the container. The referenced bean is a dependency of the bean whose property will be set, and it is initialized on demand as needed before the property is set. (If the collaborator is a singleton bean, it may be initialized already by the container.) All references are ultimately a reference to another object. Scoping and validation depend on whether you specify the id/name of the other object through the bean, local, or parent attributes.


ref 节点是或 定义的最里层的。在这里,您可以将bean的指定属性的值设置为对由容器管理的另一个bean(协作者)的引用。引用的bean是要配置的bean的依赖bean,并且在设置属性之前根据需要初始化引用的bean。(如果协作者是单例bean,则可以由容器初始化它。)所有引用最终都是引用另一个对象。范围以及有效性取决于是否通过指定其他对象的ID /名称bean,local,或parent属性。

Specifying the target bean through the bean attribute of the tag is the most general form, and allows creation of a reference to any bean in the same container or parent container, regardless of whether it is in the same XML file. The value of the bean attribute may be the same as the id attribute of the target bean, or as one of the values in the name attribute of the target bean.


通过bean标签值来 指定目标bean是最普遍的形式,并且允许在同一容器或父容器创建对所有bean的依赖,而不管其是否是在同一XML文件, bean的属相可以id与目标bean 的属性相同,或者与目标bean的name属性中的值其中一个相同。

<ref bean="someBean"/>

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.


使用parent属性创建对当前容器的父容器的目标 bean 引用。属性的值parent 可能id与目标bean的属性或目标bean的属性中的一个值name相同,并且目标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" <!-- 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>

[Note]
The local attribute on the ref element is no longer supported in the 4.0 beans xsd since it does not provide value over a regular bean reference anymore. Simply change your existing ref local references to ref bean when upgrading to the 4.0 schema.


4.0 beans xsd不在支持 idref元素的local属性,因为它不在提供对普通值bean引用。只需将现有idref local引用更改为idref bean就可以升级到升级到4.0模式。

Inner beans

A element inside the or elements defines a so–called inner bean.


或者 节点里的<bean>节点定义了一个 内部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; if specified, the container does not use such a value as an identifier. The container also ignores the scope flag on creation: Inner beans are always anonymous and they are always created with the outer bean. It is not possible to inject inner beans into collaborating beans other than into the enclosing bean or to access them independently.


内部bean的定义不需要定义的id或名称; 如果指定,容器不使用这样的值作为标识符。容器创建还会忽略scope创建:内部bean 总是匿名的,它们始终使用外部bean创建。不可以将内部bean注入到协作bean以外的的地方。

As a corner case, it is possible to receive destruction callbacks from a custom scope, e.g. for a request-scoped inner bean contained within a singleton bean: The creation of the inner bean instance will be tied to its containing bean, but destruction callbacks allow it to participate in the request scope’s lifecycle. This is not a common scenario; inner beans typically simply share their containing bean’s scope.


极端情况下,可以从自定义作用域接收破坏回调,例如对于单例bean中包含的请求范围的内部bean:内部bean实例的创建将绑定到其包含的bean,但是破坏回调允许它参与请求范围的生命周期。这不是一个常见的情况

Collections(集合)

In the , , , and elements, you set the properties and arguments of the Java Collection types List, Set, Map, and Properties, respectively.


在,,,和元素,使用java 集合 类型 如List,Set,Map,和Properties 等设置 特性以及参数

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

map 的key以及value set的value 可以被下面节点引用。


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

The Spring container also supports the merging of collections. An application developer can define a parent-style , , or element, and have child-style , , or 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.


Spring 容器也支持 集合的合并,应用开发者可以定义一个 父类型的, , 或者 ,并有子类型的 ,,,继承 或者重写 父类型的值,子集合的值是合并父集合和子集合的元素的结果

Spring容器还支持集合的合并。应用程序开发人员可以定义一个父风格,,或元素,并有孩子式的,,或元素继承和父集合覆盖值。也就是说,子集合的值是合并父集合和子集合的元素的结果,子集合元素覆盖父集合中指定的值。

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.

这个部分讨论 合并父子bean的机制。不熟悉父和子bean定义的读者可能希望在继续之前阅读 相关章节。

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


注意 子bean中定义的adminEmails属性 中 元素 里 merge=true的,当childbean由容器解析并实例化时,生成的实例具有一个adminEmails Properties集合,该集合包含将adminEmails子集合与父adminEmails集合合并的结果 。

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 , and the child’s value for the support value overrides the value in the parent collection.


子Properties 集中的 值 集合,继承了 父 Properties 中 节点中的所有值,,并且重写了support 的值。

This merging behavior applies similarly to the , , and collection types. In the specific case of the element, the semantics associated with the List collection type, that is, the notion of an ordered collection of values, is maintained; the parent’s values precede all of the child list’s values. In the case of the Map, Set, and Properties collection types, no ordering exists. Hence no ordering semantics are in effect for the collection types that underlie the associated Map, Set, and Properties implementation types that the container uses internally.


这一合并行为同样适用于,和 集合类型。在元素的具体情况下,维护与List集合类型相关联的语义,即ordered 值集合的概念; 父项的值先于所有子列表的值。使用Map,Set和Properties集合类型,没有顺序存在。因此,没有排序的语义在背后的关联的集合类型的效果Map,Set以及Properties该容器内部使用实现类型。

Limitations of collection merging(集合并的限制)

You cannot merge different collection types (such as a Map and a List), and if you do attempt to do so an appropriate Exception is thrown. The merge attribute must be specified on the lower, inherited, child definition; specifying the merge attribute on a parent collection definition is redundant and will not result in the desired merging.


您不能合并不同的集合类型(例如a Map和a List),并且如果您尝试这样做,Exception则抛出。该merge属性必须是lower,继承,子定义中指定; 指定merge父集合定义上的属性是多余的,不会导致所需的合并。

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 a Collection type such that it can only contain String elements (for example). If you are using Spring to dependency-inject a strongly-typed Collection into a bean, you can take advantage of Spring’s type-conversion support such that the elements of your strongly-typed Collection instances are converted to the appropriate type prior to being added to the Collection.


通过在Java 5中引入通用类型,可以使用强类型集合。也就是说,可以声明一个Collection类型,使得它只能包含 String元素(例如)。如果您使用Spring将依赖注入强类型Collection到bean,则可以利用Spring的类型转换支持,以便将强类型Collection 实例的元素转换为适当的类型,然后才能添加到该类型转换支持Collection。

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 the accounts property of the foo bean is prepared for injection, the generics information about the element type of the strongly-typed Map

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 (“”).


Spring将空参数视为空属性等Strings。以下基于XML的配置元数据片段将电子邮件属性设置为空 String值(“”)。

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

The preceding example is equivalent to the following Java code:


上面的例子与下面的java 代码是一样的。

exampleBean.setEmail("")

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


上面的例子等同与下面的java 代码。

exampleBean.setEmail(null)

XML shortcut with the p-namespace(带有P 命名空间的xml 快捷方式)

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


p命名空间使您能够使用bean元素的属性而不是嵌套 元素来描述属性值和/或协作bean。

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


弹簧支持扩展的配置格式与命名空间,这是基于XML架构定义。beans本章讨论的配置格式在XML Schema文档中定义。但是,p命名空间没有在XSD文件中定义,只存在于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.


以下示例显示了解决相同结果的两个XML片段:第一个使用标准XML格式,第二个使用p命名空间。

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


该示例显示了在bean定义中称为电子邮件的p命名空间中的属性。这告诉Spring包含一个属性声明。如前所述,p命名空间没有模式定义,因此您可以将属性的名称设置为属性名称。

This next example includes two more bean definitions that both have a reference to another bean:


下一个示例包括两个对另一个bean的引用的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 to create a reference from bean john to bean jane, the second bean definition uses p:spouse-ref=”jane” as an attribute to do the exact same thing. In this case spouse is the property name, whereas the -ref part indicates that this is not a straight value but rather a reference to another bean.


您可以看到,此示例不仅包括使用p命名空间的属性值,还使用特殊格式来声明属性引用。而第一个bean定义用于创建从bean john到bean 的引用 jane,第二个bean定义p:spouse-ref=”jane”用作一个属性来完成相同的事情。在这种情况下spouse,属性名称,而该-ref部分表示这不是一个直的值,而是一个引用另一个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 in Ref, 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 the the section called “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.


p命名空间不如标准XML格式那么灵活。例如,声明属性引用的格式与结束的属性冲突Ref,而标准XML格式则不会。我们建议您仔细选择您的方法,并将其传达给您的团队成员,以避免同时生成使用所有三种方法的XML文档。
带有c命名空间的XML快捷方式

类似于名为“具有p命名空间的XML快捷方式” 一节,Spring 3.1中新引入的c命名空间允许使用内联属性来配置构造函数参数而不是嵌套constructor-arg元素。

Let’s review the examples from the section called “Constructor-based dependency injection” with the c: namespace:


我们来回顾一下名为“基于构造函数的依赖注入”一节中名称空间的c:例子:

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

The c: namespace uses the same conventions as the p: one (trailing -ref for 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).


命名空间使用相同的约定作为p:一个(后-ref为bean引用),供他们的名字设置构造函数的参数。同样,它也需要声明,即使它没有在XSD模式中定义(但它存在于Spring内核中)。

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 resolution mechanism is quite efficient in matching arguments so unless one really needs to, we recommend using the name notation through-out your configuration.

由于XML语法,索引符号需要前导的存在,_因为XML属性名称不能以数字开头(即使某些IDE允许)。
在实践中,构造函数 解析机制在匹配参数方面非常有效,除非真的需要,我们建议您使用名称符号通过配置。

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 not null. Consider the following bean definition.


当您设置bean属性时,可以使用复合或嵌套属性名称,只要除了最终属性名称之外的路径的所有组件都不会null。考虑下面的bean定义。

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

The foo bean has a fred property, which has a bob property, which has a sammy property, and that final sammy property is being set to the value 123. In order for this to work, the fred property of foo, and the bob property of fred must not be null after the bean is constructed, or a NullPointerException is thrown.


该foobean具有一个fred属性,它具有一个bob属性,它具有一个sammy 属性,并且该final sammy属性被设置为该值123。为了使它工作,fred属性foo和bob属性fred不能 null在bean之后被构造,或者NullPointerException被抛出。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值