Spring学习(七)bean装配详解之 【通过注解装配 Bean】【自动装配的歧义解决】
自动装配
1、歧义性
我们知道用@Autowired可以对bean进行注入(按照type注入),但如果有两个相同类型的bean在IOC容器中注册了,要怎么去区分对哪一个Bean进行注入呢?
如下情况,若用@Autowired的方式按类型注入,IOC容器就不知道应该注入哪个了:
<bean name="source1" class="pojo.Source"> <property name="fruit" value="橙子"/> <property name="sugar" value="多糖"/> <property name="size" value="超大杯"/> </bean> <bean name="source2" class="pojo.Source"> <property name="fruit" value="橙子"/> <property name="sugar" value="少糖"/> <property name="size" value="小杯"/> </bean>
Spring对这种情况提供了2个注解进行解决:
@Primary 注解
定义:代表首要的,当 Spring IoC 检测到有多个相同类型的 Bean 资源的时候,会优先注入使用该注解的类。
问题:该注解只是解决了首要的问题,但是并没有选择性的问题。
@Qualifier 注解
定义:此注解可以让Spring使用name的方式进行Bean的装配以及注入
/* 包名和import */ public class JuiceMaker { ...... @Autowired @Qualifier("source1")//指定注入名称为 "source1" 的 Bean 资源 public void setSource(Source source) { this.source = source; } }
2、使用@Bean 装配 Bean
基础用法
定义:@Bean是一个方法级别上的注解,主要用在@Configuration注解的类里,也可以用在@Component注解的类里。
用法:标识这个方法可以产生一个Bean并且交给Spring容器管理,告诉Spring可以在这个方法中拿到一个Bean。
PS:添加的bean的id为方法名
@Configuration public class AppConfig { @Bean//用@Bean注解配置Bean时,bean的ID默认为方法的名称 public TransferService transferService() { return new TransferServiceImpl(); } }
上面的代码等同于
<beans> <bean id="transferService" class="com.acme.TransferServiceImpl"/> </beans>
bean的依赖
@bean 也可以依赖其他任意数量的bean,如果TransferService 依赖 AccountRepository,我们可以通过方法参数实现这个依赖。
@Configuration public class AppConfig { @Bean public TransferService transferService(AccountRepository accountRepository) {//PS:此方法的入参就是返回值所依赖的对象 return new TransferServiceImpl(accountRepository); } }
3、Bean的作用域
可以通过 @Scope 注解或者 <bean> 元素中的 scope 属性来设置Bean的作用域
4、Spring 表达式
一个例子简单了解下:
package pojo; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; @Component("elBean") public class ElBean { // 通过 beanName 获取 bean,然后注入role这个对象 @Value("#{role}") private Role role; // 获取 bean 的属性 id,并注入给id这个变量 @Value("#{role.id}") private Long id; // 调用 bean 的 getNote 方法,并注入给note这个变量 @Value("#{role.getNote().toString()}") private String note; /* getter and setter */ }
小结:
@Value("#{}") 表示SpEl表达式,通常用来获取bean的属性,或者调用bean的某个方法,或者常量注入。
PS:简要的说,就是通过@Value这个注解注入对象或者属性给相应的变量(简单的理解为赋值操作)。
参考资料: