(笔记)Spring实战_最小化Spring XML配置(2)_使用注解装配

Spring容器默认禁止注解装配。最简单的启用方式是使用Spring的context命名空间配置中的<context:annotation-config>元素。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    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">

    <context:annotation-config />

</beans>

1.使用@Autowired

package com.springinaction.springicon;


import org.springframework.beans.factory.annotation.Autowired;


public class Instrumentalist implements Performer
{

    public Instrumentalist()
    {

    }

    public Instrumentalist(Instrument instrument)
    {
        this.instrument = instrument;
    }

    public void perform()
    {
        System.out.print("Playing " + song + " : ");
        instrument.play();
    }

    private String song;

    public void setSong(String song)
    {
        this.song = song;
    }

    public String getSong()
    {
        return song;
    }

    private Instrument instrument;

    public void setInstrument(Instrument instrument)
    {
        this.instrument = instrument;
    }

    public void heresYourInstrument(Instrument instrument)
    {
        this.instrument = instrument;
    }

}

标注stter方法

    @Autowired
    public void setInstrument(Instrument instrument)
    {
        this.instrument = instrument;
    }

不仅能使用它标注setter方法,还可以标注需要自动装配Bean引用的任意方法

    @Autowired
    public void heresYourInstrument(Instrument instrument)
    {
        this.instrument = instrument;
    }

标注构造器

    @Autowired
    public Instrumentalist(Instrument instrument)
    {
        this.instrument = instrument;
    }

直接标注属性,并删除setter方法

    @Autowired
    private Instrument instrument;

应用中必须只能有一个Bean适合装配到@Autowired注解所标注的属性或参数中。如果没有匹配的Bean,或者存在多个匹配的Bean,@Autowired注解就会遇到一些麻烦。
可选的自动装配
默认情况下,@Autowired具有强契约特征,其所标注的属性或参数必须是可装配的。属性不一定非要装配,null值也是可以接受的。可以通过设置@Autowired的required属性为false来配置自动装配式可选的。

    @Autowired(required = false)
    private Instrument instrument;

required属性可以用于@Autowired注解所使用的任意地方。
当使用构造器装配时,只有一个构造器可以将@Autowired的required属性设置为true。其他使用@Autowired注解所标注的构造器只能将required属性设置为false。
当使用@Autowired标注多个构造器时,Spring就会从所有满足装配条件的构造器中选择入参最多的那个构造器。
限定歧义性的依赖
为了帮助@Autowired鉴别出哪一个Bean才是我们所需要的,我们可以配合使用Spring的@Qualifier注解。

    @Autowired
    @Qualifier("saxophone")
    private Instrument instrument;

除了通过Bean的ID来缩小选择范围,我们还可以通过在Bean上直接使用qualifier来缩小范围。
在XML中指定qualifier

    @Autowired
    @Qualifier("stringed")
    private Instrument instrument;
    <bean class="com.springinaction.springicon.Saxophone">
        <qualifier value="stringed" />
    </bean>

使用@Qualifier注解标注Flute类

    @Autowired
    @Qualifier("musical")
    private Instrument instrument;
package com.springinaction.springicon;


import org.springframework.beans.factory.annotation.Qualifier;


@Qualifier("musical")
public class Flute implements Instrument
{

    public void play()
    {
        System.out.println("WOO WOO WOO");
    }

}

创建自定义的限定器(Qualifier)

package com.springinaction.springicon;


import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import org.springframework.beans.factory.annotation.Qualifier;


@Target({ElementType.FIELD, ElementType.PARAMETER, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Qualifier
public @interface StringedInstrument {

}
    @Autowired
    @StringedInstrument
    @Strummed
    private Instrument instrument;
package com.springinaction.springicon;

@StringedInstrument
public class Saxophone implements Instrument
{
    public Saxophone()
    {

    }

    public void play()
    {
        System.out.println("TOOT TOOT TOOT");
    }
}

Spring的@Autowired注解是减少Spring XML配置的一种方式。但是使用它的类会引入对Spring的特定依赖(即使这种依赖只是一个注解)。
2.借助@Inject实现基于标准的自动装配
和@Autowired一样,@Inject可以用来自动装配属性、方法和构造器;与@Autowired不同的是,@Inject没有required属性。因此,@Inject注解所标注的依赖关系必须存在,如果不存在,则会抛出异常。
Provider接口可以实现Bean引用的延迟注入以及注入Bean的多个实例等功能。

        <dependency>
            <groupId>javax.inject</groupId>
            <artifactId>javax.inject</artifactId>
            <version>1</version>
        </dependency>
package com.springinaction.springicon;

public class Knife
{

}
package com.springinaction.springicon;


import java.util.HashSet;
import java.util.Set;

import javax.inject.Inject;
import javax.inject.Provider;


public class KnifeJuggler extends Juggler
{
    private Set<Knife> knives;

    @Inject
    public KnifeJuggler(Provider<Knife> knifeProvider)
    {
        super();
        knives = new HashSet<Knife>();
        for (int i = 0; i < 5; i++ )
        {
            knives.add(knifeProvider.get());
        }
    }

    public void perform()
    {
        super.perform();
        System.out.println("knife size:" + knives.size());
    }
}
    <bean id="knife" class="com.springinaction.springicon.Knife" scope="prototype" />

    <bean id="jenny" class="com.springinaction.springicon.KnifeJuggler" />

因为Knife Bean作用域为prototype,所以knife的Set集合将被赋予5个不同的Knife对象。
限定@Inject所标注的属性
相对于@Autowired所对应的@Qualifier,@Inject所对应的是@Named注解。

    @Inject
    @Named("saxophone")
    private Instrument instrument;

@Qualifier注解帮助我们缩小所匹配Bean的选择范围(默认使用Bean的ID),而@Named通过Bean的ID来标识可选择的Bean。
创建自定义的JSR-330 Qualifier
我们导入javax.inject包来使用标准的@Qualifier

package com.springinaction.springicon;


import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import javax.inject.Qualifier;


@Target({ElementType.FIELD, ElementType.PARAMETER, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Qualifier
public @interface ViolInstrument {

}

3.在注解注入中使用表达式
使用@Value注解装配String类型的值和基本类型的值。
我们可以通过@Value直接标注某个属性、方法或者方法参数,并传入一个String类型的表达式来装配属性。

    @Value("Jingle Bells")
    private String song;

借助SpEL表达式,@Value被赋予了魔力。它可以根据SpEL表达式来进行动态的求值计算。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值