@Qualifier

当一个接口,有多个实现类且均已注入到spring容器中了,使用时@AutoWired是byType的,而这些实现类类型都相同,此时就需要使用@Qualifier明确指定使用那个实现类。因此,@Qualifier是byName的。

1、基本

public interface Formatter {
    String format();
}

@Component("fooFormatter")
public class FooFormatter implements Formatter {
    @Override
    public String format() {
        return "foo";
    }
}

@Component("barFormatter")
public class BarFormatter implements Formatter {
    @Override
    public String format() {
        return "bar";
    }
}

idea提示,必须添加@Qualifier,否则红线。

 最后,形如:

@SpringBootTest
class QualifierTest {
    @Qualifier("barFormatter")
    @Autowired
    private Formatter formatter;
    @Test
    void test() {
        System.out.println(formatter.format());
    }
}

执行,输出:bar

如果将barFormatter改成fooFormatter,输出:foo。

2、对于实现类,可不用在@Compoment后的括号里声明名称,可以新增@Qualifier指定名称,如:

@Component
@Qualifier("fooFormatter")
public class FooFormatter implements Formatter {
。。。
}
@Component
@Qualifier("barFormatter")
public class BarFormatter implements Formatter {
。。。
}

3、对于实现类,去掉名称,加上@Primary,也可以实现。意思是:默认使用@Primary的实现类,无需使用@Qualifier明确指定使用那个实现类了。

@Component
@Primary
public class FooFormatter implements Formatter {
...
}
@Component
public class BarFormatter implements Formatter {
...
}

但是,如果以上2个实现类都加上了@Primary,依赖时,就会报错:

 如果,@Qualifier与@Primary同时使用呢?优先使用@Qualifier指明的实现类。如:

@Qualifier("barFormatter")
@Autowired
private Formatter formatter;

输出:bar。

@Primary一般在DataSource中用的较多,因为有druid实现、c3p0实现,而一般使用一个具体的连接池,因此为了偷懒,就采用@Primary了。

4、在多个实现类中,使用指定实现类的另外一种方法是,属性名称写全了。

@Component
public class FooFormatter implements Formatter {
。。。
}
@Component
public class BarFormatter implements Formatter {
。。。
}

@SpringBootTest
class QualifierTest {
    @Autowired
    private Formatter barFormatter;
    @Test
    void test() {
        System.out.println(barFormatter.format());
    }
}

输出:bar

原文地址:https://www.cnblogs.com/yaoyuan2/p/11745441.html