自动装配(XML和注解)

Spring提供四种自动装配策略(针对XML配置):

1、byName :把与bean的属性具有相同名字(或者ID)的其他Bean自动装配到Bean的对应属性中。如果没有跟属性的名字相匹配的Bean,则该属性不进行装配。

2、byType :把与Bean的属性具有相同类型的其他Bean自动装配到Bean对应属性中,如果没有跟属性的类型相匹配的Bean,则该属性不被装配。

3、constructor :把与Bean的构造器入参具有相同类型的其他Bean自动装配到Bean构造器对应入参中。

4、autodetect :首先使用constructor进行自动装配。如果失败,再尝试使用byType进行自动装配。

一、byName自动装配

<!--Instrument Bean的sgtPeppers属性的名字是一样的-->
    <bean id="instr" class="org.springaction.Instrument">
        <property name="name" value="lisi"/>
        <property name="sgtPeppers" ref="sgtPeppers"/>
    </bean>

    <bean id="sgtPeppers" class="org.springaction.SgtPeppers"/>

byName自动装配遵循一项约定:为属性自动装配ID与该属性的名字相同的Bean。

<!--Instrument Bean配置autowire属性,可以自动装配,减少XML-->
    <bean id="instr" class="org.springaction.Instrument" autowire="byName">
        <property name="name" value="lisi"/>
    </bean>

    <bean id="sgtPeppers" class="org.springaction.SgtPeppers"/>

二、byType自动装配
使用byType自动装配时,会寻找一个Bean的类型与属性的类型相匹配。

 <!--Instrument Bean配置autowire属性按照byType自动装配,-->
    <bean id="instr" class="org.springaction.Instrument" autowire="byType">
        <property name="name" value="lisi"/>
    </bean>

    <bean id="sgt" class="org.springaction.SgtPeppers"/>

如果Spring找到多个Bean,它们的类型与需要自动装配的属性的类型都是相匹配,Spring会抛出异常。所以应用只允许存在一个Bean与需要自动装配的属性类型相匹配。解决办法:
1、标识一个首选Bean

<bean id="instr" class="org.springaction.Instrument" autowire="byType">
        <property name="name" value="lisi"/>
    </bean>

    <bean id="sgtPeppers" class="org.springaction.SgtPeppers"/>

    <!--primary用来标识首选Bean,但是它的默认值是true。所以将其他非首选的Bean的primary设置为false-->
    <bean id="cdPlat" class="org.springaction.CDPlat" primary="false"/>

2、排除某些Bean

<!--设置autowire-candidate属性为false,会排除该Bean。自动装配时会忽略该Bean的候选资格-->
    <bean id="cdPlat" class="org.springaction.CDPlat" autowire-candidate="false"/>

三、constructor自动装配
它也是根据相同类型进行注入,通过构造器注入来配置Bean,使用constructor装配,可以移除<\constructor-arg>元素。

<bean id="instr" class="org.springaction.Instrument" autowire="constructor">
        <property name="name" value="lisi"/>
    </bean>

四、默认自动装配
如果需要为Spring应用上下文中的每个Bean(或者其中的大多数)配置相同的autowire。那么可以在根元素<\beans>上增加一个属性:

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:c="http://www.springframework.org/schema/c"
       xmlns:p="http://www.springframework.org/schema/p"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd"
        default-autowire="byName">

默认情况下,default-autowire属性被设置为none。标识所有Bean都不使用自动装配,除非Bean自己配置了autowire属性。
default-autowire应用于指定Spring配置文件中的所有Bean。而不是应用上下文中所有的Bean。可以每个配置文件都有自己的默认自动装配策略。

可以使用<\bean>元素的autowire属性来覆盖<\beans>元素所配置的默认自动装配策略。

五、混合使用自动装配和显式装配

<bean id="instr" class="org.springaction.Instrument" autowire="byType">
        <property name="name" value="lisi"/>
        <property name="sgtPeppers" ref="sgtPeppers"/>
    </bean>

    <bean id="sgtPeppers" class="org.springaction.SgtPeppers"/>

混合使用自动装配和手工装配可以解决使用byType自动装配策略可能产生的装配不确定问题。显式装配可以覆盖自动装配。

使用constructor自动装配策略时,必须让Spring自动装配构造器的所有入参,不能混合使用constructor自动装配策略和<\constructor-arg>元素。

二、使用注解自动装配(基于注解)
Spring容器默认禁用注解装配,在使用前需要在Spring配置中启用:

<!--能够指导Bean装配,但是仍需要使用<bean>元素显式定义Bean,被<context:component-scan取代,既能自动装配,也能实现Bean的定义>-->
<context:annotation-config/>

1、使用@Autowired
当使用注解自动装配,可以移除<\property>元素和<\constructor-arg>元素。Spring会尝试对该方法执行byType自动装配。不仅能标注构造器、Setter方法,也可以标注任意的方法

@Autowired
    public Instrument(CompactDisc sgtPeppers){
        this.sgtPeppers=sgtPeppers;
    }

    @Autowired
    public void setSgtPeppers(CompactDisc sgtPeppers) {
        this.sgtPeppers = sgtPeppers;
    }

    @Autowired
    public void hearInst(CompactDisc sgtPeppers){
        this.sgtPeppers=sgtPeppers;
    }

也可以直接标注属性,不会受到private影响,并删除Setter方法:

@Autowired
    private CompactDisc sgtPeppers;

如果没有匹配的Bean,或者存在多个匹配的Bean。@Autowire注解会遇到麻烦。

1、没有匹配的bean(可选的自动装配)
默认情况下,@Autowire所标注的属性或参数必须是可装配的,如果没有Bean可以装配到所标注的属性中,自动装配就会失败。

可以通过设置@Autowire的required属性为false来配置自动装配是可选的:

@Autowired(required = false)
    private CompactDisc sgtPeppers;

在这里如果没有查找到与之匹配的类型为CompactDisc 的Bean,应用也不会发生问题,而属性值会被设置为null。

@Autowired(required = true)
    public Instrument(CompactDisc sgtPeppers){
        this.sgtPeppers=sgtPeppers;
    }

当使用构造器装配时,只有一个构造器可以将required属性设置为true。其他构造器只能设置为false。
当标注多个构造器时,Spring容器会从所有满足装配条件的构造器中选择入参最多的那个构造器。

2、存在多个匹配的Bean(限定歧义性的依赖)
@Qualifier注解是使用限定符的主要方式,可以与@Autowire和@Inject协同使用,在注入时指定想要注入进去的是那个bean。

   @Autowired
   //参数就是要注入的bean的ID
    @Qualifier("sgtPeppers")
    public void setSgtPeppers(CompactDisc sgtPeppers) {
        this.sgtPeppers = sgtPeppers;
    }

@Inject注解和@Autowire注解一样,可以用来自动装配属性、方法和构造器;不同的是@Inject没有required属性,因此,所标注的依赖关系必须存在,否则抛出异常。
@Inject使用@Named注解限定

   @Inject
   @Named("sgtPeppers")
    public void setSgtPeppers(CompactDisc sgtPeppers) {
        this.sgtPeppers = sgtPeppers;
    }

使用注解装配简单值

使用@Value注解可以装配String类型的值和基本类型的值。
可以直接标注某个属性、方法或者方法参数

    public class Student {
    //不需要setter方法
    @Value("${test.age}")
    private int age;
    @Value("${test.name}")
    private String name;
    }

XML配置
<context:property-placeholder location="testvalue.properties"/>

    <bean id="student" class="org.springaction.Student"/>

传入@Value的String类型的参数只是一个表达式,它的计算结果可以是任意类型,因此@Value可以标注任意类型的属性。

可以在运行期使用SpEL动态计算复杂表达式的值并把结果装配到Bean的属性中。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值