依赖注入的三种方式

基于构造器的注入;基于setter方法的注入;注解注入

一、基于构造器的依赖注入

xml内容简介

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd">
<!--我们可以将xml文件理解位ioc容器,我们将需要创建对象的类注入到xml文件中也就是ioc容器里,当我们需要时从中取出即可,这样当需求改变时我们不需要修改源代码,只需要修改xml配置文件即可.
-->
<!--JpaAccountDao accountDao = new JpaAccountDao();
一个bean相当于上面一个创建对象的语句
bean标识符中id等价于accountDao
class等价于new JpaAccountDao();这里clss要写具体路径
如果有属性即变量的话,用property标识符,<property name = "age" value = "15"/>
等价于age = 15;
-->
    <bean id="accountDao" class="org.springframework.samples.jpetstore.dao.jpa.JpaAccountDao">
        <!-- additional collaborators and configuration for this bean go here -->
    </bean>

    <bean id="itemDao" class="org.springframework.samples.jpetstore.dao.jpa.JpaItemDao">
        <!-- additional collaborators and configuration for this bean go here -->
    </bean>

    <!-- more bean definitions for data access objects go here -->

</beans>

注入

//首先,给出一个POJO类,不依赖于特定于容器的接口,基类或注释
package examples;

public class ExampleBean {

    // Number of years to 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;
    }
}

1、构造函数参数类型匹配
在上述情况下,如果通过使用type属性显式指定构造函数参数的类型,则容器可以使用简单类型的类型匹配。如以下示例所示:

<bean id="exampleBean" class="examples.ExampleBean">
    <constructor-arg type="int" value="7500000"/>
    <constructor-arg type="java.lang.String" value="42"/>
</bean>

2、构造函数参数索引
您可以使用该index属性来明确指定构造函数参数的索引,如以下示例所示:

<bean id="exampleBean" class="examples.ExampleBean">
    <constructor-arg index="0" value="7500000"/>
    <constructor-arg index="1" value="42"/>
</bean>

二、基于setter的依赖注入

通过使用无参数构造函数或无参数static工厂方法实例化bean之后,容器通过在bean上调用setter方法来实现基于setter的DI;也就是说注入bean中的类只能有无参构造方法或是实例化无参static工厂,ioc会通过调用setter方法来实现依赖注入,如果没有setter方法,xml会报错。

//给出一个pojo类
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">
    <!-- setter injection using the nested ref element -->
    <property name="beanOne">
        <ref bean="anotherExampleBean"/>//不懂这个的看一下元素<ref/>
    </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"/>

以上两种都是在xml配置文件中进行依赖注入(DI:Dependency Injection)

三、注解注入

//JAVA配置
@Confirguration //相当于spring的配置文件XML
@Bean //用到方法上,表示当前方法的返回值是一个bean

java配置是使用java配置类,这个类的作用和xml一样,只是依赖注入方式不同。大致是一样的,不再详细介绍;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
 
@Configuration
public class JavaConfig {
    //通过这种方式,获得spring的依赖注入
    //一个@Bean相当于xml中的一个<bean></bean>
    @Bean
    public UseFunctionService useFunctionService () {
        return new UseFunctionService ();
    }
    @Bean
    .
    .
    .
    
}

这种方式是通过java类加上注解进行依赖注入

四、p-namespace和c-namespace

4.1具有p-namespace的XML快捷方式

使用p-namespace,可以使用bean元素的属性来描述协作Bean的属性值,而不是嵌套 元素,,也可以同时使用这两者。

Spring支持具有名称空间的可扩展配置格式,这些名称空间基于XML Schema定义。beans本章讨论的配置格式在XML Schema文档中定义。但是,p命名空间未在XSD文件中定义,仅存在于Spring的核心中。

下面的示例显示了两个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
        https://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean name="classic" class="com.example.ExampleBean">
        <property name="email" value="someone@somewhere.com"/>
    </bean>

    <bean name="p-namespace" class="com.example.ExampleBean"
        p:email="someone@somewhere.com"/>
</beans>

该示例显示了email在bean定义中调用的p-namespace中的属性。这告诉Spring包含一个属性声明。如前所述,p名称空间没有架构定义,因此您可以将属性的名称设置为属性名称。

下一个示例包括另外两个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
        https://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>

p命名空间不如标准XML格式灵活。例如,用于声明属性引用的格式与以结尾的属性发生冲突Ref,而标准XML格式则没有。我们建议您谨慎选择方法,并将其传达给团队成员,以避免同时使用这三种方法生成XML文档。

4.2具有c-namespace的XML快捷方式

与具有p-namespace的XML Shortcut相似,在Spring 3.1中引入的c-namespace允许使用内联属性来配置构造函数参数,而不是嵌套constructor-arg元素。

以下示例使用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
        https://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="beanTwo" class="x.y.ThingTwo"/>
    <bean id="beanThree" class="x.y.ThingThree"/>

    <!-- traditional declaration with optional argument names -->
    <bean id="beanOne" class="x.y.ThingOne">
        <constructor-arg name="thingTwo" ref="beanTwo"/>
        <constructor-arg name="thingThree" ref="beanThree"/>
        <constructor-arg name="email" value="something@somewhere.com"/>
    </bean>

    <!-- c-namespace declaration with argument names -->
    <bean id="beanOne" class="x.y.ThingOne" c:thingTwo-ref="beanTwo"
        c:thingThree-ref="beanThree" c:email="something@somewhere.com"/>

</beans>

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

对于极少数情况下无法使用构造函数自变量名称的情况(通常,如果字节码是在没有调试信息的情况下编译的),则可以对参数索引使用后备,如下所示:

<!-- c-namespace index declaration -->
<bean id="beanOne" class="x.y.ThingOne" c:_0-ref="beanTwo" c:_1-ref="beanThree"
    c:_2="something@somewhere.com"/>

由于XML语法的原因,索引符号要求使用前导_,因为XML属性名称不能以数字开头(即使某些IDE允许)。相应的索引符号也可用于元素,但并不常用,因为声明的简单顺序通常就足够了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值