您的位置:首页 > 编程语言 > Java开发

Spring基础处理-自动装配的歧义性

2018-01-20 12:07 381 查看

1.出现歧义性的原因

当自动装配的多个bean,同时继承同一个接口的时候,使用@Autowired注解对接口进行bean的注入,会出现歧义性.如:

@Autowired
public void setDessert(Dessert dessert){
this.dessert= dessert;
}

@Component
public class Cake implement Dessert{...}

@Component
public class Cookies implement Dessert{...}

@Component
public class IceCream implement Dessert {...}


这三个类都实现了Dessert接口,所以在进行注入的时候,不知道会注入哪一个

2.解决方法

2.1 标记首选的bean

在有@Component 注解的类上加上@Primary注解,表明他是一个首选的类,不能通同时标记两个首选类,如:

//使用组件扫描
@Component
@Primary
public class IceCream implements Dessert{...}

//使用java配置类的显式配置
@Bean
@Primary
public Dessert iceCream() {
return new IceCream;
}
//使用xml的显式配置
<bean id="iceCream" class="包名.IceCream" primary="true"/>


这种方式无法将可选的方案的范围限定到唯一一个无歧义性的选项中,他只能标记一个优先的方案,没有办法进一步缩小范围.

2.限定自动装配的bean

使用@Qualifier 注解,可以和@Autowired和@Inject注解一起使用,如:

@Autowired
@Qualifier("iceCream")//里面的参数就是想要注入的bean的ID,@Component注解的类,都会被创建为bean,默认的id就是类名的首字母小写,这就表示要把iD为iceCream的类注入进去.如果没有iceCream作为限定符,那默认的就是这个bean的ID
public Dessert dessert;


这种方法有一些问题,比如,如果重构了IceCream方法,那么iceCream这个ID就不能找到任何方法,自动装配就会失败.所以要创建自定义的限定符来解除这种紧耦合.

在类的定义上也是用@Qualifier注解:

@Component
@Qualifier("cold")//给类起一个ID ,这个ID不能乱起,应该表达这个类的一些特性
public class IceCream implements Dessert{...}


然后使用上面的@Autowired和@Qualifier(“cold”)就可以啦

PS:如果有相同的cold作为限定符,还是有歧义,可以想到的方法是使用多个@Qualifier 来给类进行限定多个ID,但是,上面的方法可能会报错,Java不允许在统一条目上重复出现多个相同类型的注解,如下是可能报错的:

@Component
@Qualifier("cold")
@Qualifier("creamy")
public class IceCream implements Dessert{...}

@Autowired
@Qualifier("cold")
@Qualifier("creamy")
public Dessert dessert;


所以根据这种需求可以创建多个自定义的注解来实现这个功能,比如创建@Cold注解来代替@Qualifier(“cold”)

@Target({ElementType.CONSTRUCTOR,ElementType.FIELD,ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Qualifier
public @interface Cold{}  //这个方法写在哪还没实践确定

@Target({ElementType.CONSTRUCTOR,ElementType.FIELD,ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Qualifier
public @interface Creamy{}

@Component
@Cold
@Creamy
public class IceCream implements Dessert{...}

@Autowired
@Cold
@Creamy
public Dessert Dessert;
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: