spring学习心得-第1篇-spring中@Qualifier注解的两种用法

spring中@Qualifier注解的两种用法

  • spring源码中的@Qualifier
    • 第一种用法
    • 第二种用法
    • Ribbon中使用了@Qualifier的第二种用法

spring源码中的@Qualifier

/**
 * This annotation may be used on a field or parameter as a qualifier for
 * candidate beans when autowiring. It may also be used to annotate other
 * custom annotations that can then in turn be used as qualifiers.
 *
 * @author Mark Fisher
 * @author Juergen Hoeller
 * @since 2.5
 * @see Autowired
 */
@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.TYPE, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Qualifier {

	String value() default "";

}

源码中注释的部分翻译过来就是:
此注释可在字段或参数上,用作自动连线时的候选bean。它也可用于其他自定义注解上,该自定义注解可以当作一个Qualifier。
上面这句话就是说明两个功能:
(1)使用@Autowired自动注入的时候,可以在属性或参数加上@Qualifier(“xxx”)指定注入到对象;

(2)可以作为筛选的限定符,我们在写自定义的注解时,可以在其定义上增加@Qualifier,在自动注入时,来筛选需要的对象。也可以直接使用Qualifier注解来实现类的筛选

第一种用法

这种用法比较常见,比如一个Animal接口,有多个实现,@Autowired注入到时候,可以使用@Qualifier指定哪个bean生效。

public interface Animal {
    void say(String word);
}
-------
@Component
public class Dog implements Animal {
    @Override
    public void say(String word) {
        System.out.println("汪汪");
    }
}
-------
@Component
public class Cat implements Animal {
    @Override
    public void say(String word) {
        System.out.println("喵喵");
    }
}
-------
@SpringBootTest(classes = {AutodeliverApplication8090.class})
@RunWith(SpringJUnit4ClassRunner.class)
public class AutodeliverApplication8090Test {
    @Autowired
    @Qualifier("dog")
    private Animal animals;
    
    @Test
    public void testAutoInject(){ 
         animal.say("123");
    }

运行测试代码后,控制台打印汪汪,既自动注入了Dog类

第二种用法

对上面的代码做一些改动,加入一个自定义注解@MyMark

public interface Animal {
    void say(String word);
}
-------
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD, ElementType.METHOD, ElementType.TYPE})
@Qualifier
public @interface MyMark {
}
-------
@Component
@MyMark
public class Dog implements Animal {
    @Override
    public void say(String word) {
        System.out.println("汪汪");
    }
}
-------
@Component
@MyMark
public class Cat implements Animal {
    @Override
    public void say(String word) {
        System.out.println("喵喵");
    }
}
-------
@Component
public class Fish implements Animal {
    @Override
    public void say(String word) {
        System.out.println("鱼鱼");
    }
}
-------
@SpringBootTest(classes = {AutodeliverApplication8090.class})
@RunWith(SpringJUnit4ClassRunner.class)
public class AutodeliverApplication8090Test {
    @Autowired
    @MyMark // 筛选功能,在自动注入的属性上要加注解,且注入的属性类型为集合
    private List<Animal> animals;
    
    @Test
    public void testAutoInject(){ 
    
         for(Animal animal: animals){
            animal.say("123");
        }
    }

运行后,控制台打印,汪汪,喵喵,没有打印鱼鱼,因为只有Dog和Cat类使用了@MyMark。这里直接把代码种的@MyMark注解换成@Qualifier注解,是一样的效果。
注意:筛选功能,在自动注入的属性上要加注解,且注入的属性类型为集合。

另外,@Qualifier注解是可以指定value的,这样我们可以通过values来分类筛选想要的对象了,这里不列举代码了,感兴趣的同学自己试试。

Ribbon中使用了@Qualifier的第二种用法

我们使用ribbon的时候一般都有类似这样的代码:

@Configuration
public class RestTemplateConfiguration {

@Bean
@LoadBalanced
public RestTemplate getRestTemplate(){
return  new RestTemplate();
    }
}

疑问:为什么这里加上@LoadBalanced既可以实现负载均衡呢?答案就在@LoadBalanced里。

@Target({ ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Qualifier
public @interface LoadBalanced {

}

@LoadBalanced注解上加了@Qualifier注解,在程序启动初始化的时候,在spring配置类
LoadBalancerAutoConfiguration中会筛选出来所有加了@LoadBalanced注解的RestTemplate对象,执行http请求的时候就可以从按负载均衡规则从list选择RestTemplate执行实际的请求,这样就达到负载均衡的目的。

spring学习心得-第1篇-spring中@Qualifier注解的两种用法_第1张图片
谢谢你的阅读,如果你喜欢这篇文章,请进行点赞,评论,收藏!

你可能感兴趣的:(java进大厂拿高薪,spring,java)