spring注入方式

spring的注入方式分为两种:设值注入和构造注入,不管是哪种方式都是为了注入依赖对象的。

设值注入方式比较常用。所谓的设值注入是指通过类中的setxxx方法来注入,这种方式简单直观。

   <bean class="cn.itouchtv.Person" id="person" >
        <property name="age" value="10"></property>
        <property name="name" value="cjh"></property>
        <property name="address" ref="address"></property>
    </bean>

    <bean class="cn.itouchtv.Address" id="address">
        <property name="province" value="广东"></property>
        <property name="city" value="广州" > </property>
    </bean>

这里的注入方式都是通过property这个标签来注入,name代表相关的类的属性名称,value代表这个值。当需要引用IOC中的某个bean的时候使用ref来引用,对应的值用IOC中bean的id来表示,比如这里用到ref="address",那么就是说引用IOC中的address这个id对应的bean。

这中注入的方式都是主动的,还可以通过自动的方式注入。使用bean中的autowire属性:

 <bean class="cn.itouchtv.Person" id="person"  autowire="byType">
        <property name="age" value="10"></property>
        <property name="name" value="cjh"></property>
    </bean>

    <bean class="cn.itouchtv.Address" id="address">
        <property name="province" value="广东"></property>
        <property name="city" value="广州" > </property>

这里通过类型自动注入,这里要注意的是当同个类型的bean有两个时,会报错。还可以

autowire="byName",通过类的属性的名字和IOC容器中的bean的id来匹配。

构造器注入:这个方式有时候会显得很难阅读,代码臃肿。当有多个构造器的时候,

    <bean class="cn.itouchtv.Person" id="person1"  autowire="byName">
        <constructor-arg value="cjh"></constructor-arg>
        <constructor-arg value="23"></constructor-arg>
        <constructor-arg ref="address"></constructor-arg>
    </bean>

构造器注入用到<constructor-arg>这个标签,其实也有value和ref这些属性用于复制和引用IOC容器中的bean。构造器的注入配置中还可以通过:bean标签的index属性来指明注入的属性的顺序。其实上述的的顺序没写,默认就是0 1 2

 <bean class="cn.itouchtv.Person" id="person1"  autowire="byName">
        <constructor-arg value="cjh" index="0"></constructor-arg>
        <constructor-arg ref="address" index="2"></constructor-arg>
        <constructor-arg value="23" index="1"></constructor-arg>
        
    </bean>

但是如果是有两个三个参数的构造器的话,那么这个构造器必须是有不同类型的参数,或者是参数类型的顺序不同,不然会报错。也就是说,不可以有按顺序类型相同,个数相同的的构造器。

那么这个index就可以制定是使用哪个构造器了。假设出现赋值都满足的构造器就出现歧义 。

package cn.itouchtv;

public class Person {
    private String name;
    private int age;
    private Address address;
    private long weight;

    public Person() {
    }

    public Person(String name, long weight, Address address) {
        this.name = name;
        this.address = address;
        this.weight = weight;
    }

    public Person(String name, int age, Address address) {
        this.name = name;
        this.age = age;
        this.address = address;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public Address getAddress() {
        return address;
    }

    public void setAddress(Address address) {
        this.address = address;
    }

    public long getWeight() {
        return weight;
    }

    public void setWeight(long weight) {
        this.weight = weight;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", address=" + address +
                ", weight=" + weight +
                '}';
    }
}

很明显,上述的构造器赋值两个都是可以的。

 <bean class="cn.itouchtv.Person" id="person1"  autowire="byName">
        <constructor-arg value="cjh" ></constructor-arg>
        <constructor-arg value="23"></constructor-arg>
        <constructor-arg ref="address"></constructor-arg>
    </bean>

    <bean class="cn.itouchtv.Person" id="person2"  autowire="byName">
        <constructor-arg value="cjh" ></constructor-arg>
        <constructor-arg value="56"></constructor-arg>
        <constructor-arg ref="address"></constructor-arg>
    </bean>

结果:

person1: Person{name='cjh', age=23, address=Address{province='广东', city='广州'}, weight=0}

person2: Person{name='cjh', age=56, address=Address{province='广东', city='广州'}, weight=0}

那么这两个都会赋值给同一个bean,我这里是都给age了。此时为了防止出现歧义,可以制定参数的类型。

加上type="long",那么对应的就会赋值给weight了。

<bean class="cn.itouchtv.Person" id="person1"  autowire="byName">
        <constructor-arg value="cjh" ></constructor-arg>
        <constructor-arg value="23"></constructor-arg>
        <constructor-arg ref="address"></constructor-arg>
    </bean>

    <bean class="cn.itouchtv.Person" id="person2"  autowire="byName">
        <constructor-arg value="cjh" ></constructor-arg>
        <constructor-arg value="56" type="long"></constructor-arg>
        <constructor-arg ref="address"></constructor-arg>
    </bean>

结果:person1: Person{name='cjh', age=10, address=Address{province='广东', city='广州'}, weight=0}

           person2: Person{name='cjh', age=0, address=Address{province='广东', city='广州'}, weight=56}

 

建议:这个是网上看到的建议》建议采用设值注入为主,构造注为辅的策略,对于依赖关系不变的,使用构造注入,其他使用设值注入,比如datasource的注入,建议使用构造注入。

 

这里而外插入xml配置的继承。这个跟java的继承不一样,这个只是配置的继承。

  <bean abstract="true" id="common">
        <property name="province" value="广东"></property>
    </bean>

    <bean class="cn.itouchtv.Address" id="address" parent="common">
        <property name="city" value="广州" > </property>
    </bean>

对于配置的继承,比如上述的common,这个bean可以是抽象的和shili的,还可以没有class属性,也可以有。当引用这个配置的bean时,使用parent属性,此时进行属性的设置,没有的继承,有的则覆盖。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值