自动装配(XML和注解)

来源:互联网 发布:漫画王软件 编辑:程序博客网 时间:2024/06/05 02:57

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的属性中。

原创粉丝点击