这个是接着上一篇写的,这章内容较多,分开来记录一下。。。
三、处理自动装配的歧义性
自动装配让spring完全负责bean引用注入到构造参数和属性中,不过,仅有一个bean匹配所需的结果时,自动装配才是有效的。如果不仅有一个bean能够匹配的话,这种歧义性会阻碍spring自动装配属性、构造参数或方法参数。虽然这种歧义性十分罕见,但是我看了spring解决方法后,感觉spring提供的是一种这类问题的解决办法,显然在这里主要学习的是这种解决此类问题的思想。
//这里是提供了这种特殊情况的demo,有一个方法,需要自动装配Dessert接口 @Autowired public void setDessert(Dessert dessert){ this.dessert = dessert; } //但是这个Dessert接口却有三个实现类,这就有点尴尬了,spring自动装配的时候到底要装配哪个实现类呢..... spring会报NoUniqueBeanDefinitionException错误的 @Component public class Cake implements Dessert{......} @Component public class Cookies implements Dessert{......} @Component public class IceCream implements Dessert{......} //使用@Primary 注解标注首选bean @Primary @Component public class IceCream implements Dessert{......} <bean id="iceCream" class="com.desserteater.IceCream" primary="true" /> //但是两个同时加上@Primary注解呢!!!spring中会有@Qualifier注解 @Autowired @Qualifier("iceCream") public void setDessert(Dessert dessert){ this.dessert = dessert; } //但是这种方式使用的是bean ID,限制符与要注入的bean是紧耦合的,对类名称的改动都会导致限定符失效,但是spring中允许为bean设置自己的限定符 @Component @Qualifier("cold") public class IceCream implements Dessert{......} @Autowired @Qualifier("cold") public void setDessert(Dessert dessert){ this.dessert = dessert; } //但是如果是两个实现类具有相同特点的限制符呢!!!这个考虑的也太全面了吧,程序员就是要有这种精神的,哈哈哈,就是下面这种情况呢..... @Component @Qualifier("cold") @Qualifier("creamy") public class IceCream implements Dessert{......} @Component @Qualifier("cold") @Qualifier("fruity") public class Popsicle implements Dessert{......} //Java 中不允许出现在同一个条目上出现相同类型的多个注解的,唉,终极办法:自定义限制符注解,这个好牛叉牛叉... //这个对应着就是@Qualifier("cold") @Target({ElementType.CONSTRUCAOR, ElementType.FILELD, ElementType.METHOD, ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Qualifier Public @interface Cold{} //这个对应着就是@Qualifier("creamy") @Target({ElementType.CONSTRUCAOR, ElementType.FILELD, ElementType.METHOD, ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Qualifier Public @interface Creamy{} //这个对应着就是@Qualifier("fruity") @Target({ElementType.CONSTRUCAOR, ElementType.FILELD, ElementType.METHOD, ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Qualifier Public @interface Fruity{} //大功告成,这就彻底解决那个问题了,你在有多少的我也不怕了,嘿嘿嘿,完美的解决这个问题了,spring中太美妙了,这种思想真的让人受益匪浅 @Component @Cold @Creamy public class IceCream implements Dessert{......} @Component @Cold @Fruity public class Popsicle implements Dessert{......} @Autowired @Cold @Creamy public void setDessert(Dessert dessert){ this.dessert = dessert; }
四、bean的作用域