@Autowired通过类型自动装配依赖项
@Autowired注释可以在构造函数级、方法级、字段级使用
1、字段级的注释
@Service(value="accountStatementService")
public class AccountStatementServiceImpl implements AccountStatementService{
@Autowired
private AccountStatementDao accountStatementDao;
@Override
public AccountStatement getAccountStatement(Date from,Date to){
return accountStatementDao.getAccountStatement(from,to);
}
}
其中,在accountStatementDao使用了注解@Autowired,创建了一个AccountStatementDao的实例,同时Spring的AutowiredAnnotationBeanPostProcessor(一个BeanPostProcessor的实现)负责自动装配accountStatementDao字段。AutowiredAnnotationBeanPostProcessor从Spring的容器获取对AccountStatementDao类型bean的引用,并将其分配给accountStatementDao字段。
注意:使用@Autowired可以不需要相应的setter方法。
2、方法级的注释
@Service("customerRegistrationService")
@Scope(value=ConfigurableBeanFactiry.SCOPE_PROTOTYPE)
public class CustomerRegistrationServiceImpl implements CustomerRegistrationService
{
private CustomerRegistrationDetails customerRegistrationDetails;
...
@Autowired
public void obtainCustomerRegistrationDetails(CustomerRegistrationDetails customerRegistrationDetails)
{
this.customerRegistrationDetails = customerRegistrationDetails;
}
...
}
如果一个方法使用了@Autowired的注释,意味着该方法的参数是自动装配的。
注意:注释方法不需要一定是公有的。
3、构造函数级的注释
注意:从Spring4.3开始,如果bean类只定义了一个构造方法,则不需要使用@Autowired来注释。@Autowired的required特性指定一个依赖项时必选还是可选的。如果定义多个@Autowired注释的构造方法,需要将required特性的值设置为false。
@Qualifier 按名称自动装配依赖项
@Qualifier注释可以在字段级、方法参数级、构造函数级来按名称自动装配依赖项
@Service(value="fixedDepositService")
...
public class FixedDepositServiceImpl implements FixedDepositService{
@Autowired
@Qualifier(value="myFixedDepositDao")
pivate FixedDepositDao myFixedDepositDao;
...
}
过程: Spring首先通过使用@Autowired注释的字段、构造函数参数和方法参数“按类型”找到自动装配候选项。然后,Spring使用@Qualifier注释指定的bean名称来定位自动装配候选列表中唯一的bean。
public class Sample{
@Autowired
public Sample(@Qualifier("aBean") ABean aBean){...}
@Autowired
public void doSomething(@Qualifier("bBean") BBean bBean,CBean cBean){...}
}
此为一个构造函数参数和一个方法参数指定了@Qualifier注释
过程: 当创建一个Sample类的实例时,Spring会寻找一个名为aBean、类型为ABean的bean,并将其作为参数传递给Sample类的构造函数。 BBean,CBean同上,不过BBean时通过名称自动装配的,CBean时按照类型自动装配的。
可以使用qualifiers以取代按bean名称来自动装配bean依赖项。
qualifiers是使用@Qualifier注释与bean关联的字符串值没并且在向Spring容器注册的bean中不要求是唯一的。
Ⅰ自动装配bean
@Repository(value="egDao")
@Qualifier("myEg")
public class EgDaoImpl implements EgDao{
...
}
@Service("egService")
public class EgServiceImpl implememts EgService{
@Autowired
@Qualifier("myEg")
private EgDao egDao;
...
}
Ⅱ自定义限定符注释@FundTransfer
@Qualifier
public @interface FundTransfer{
TransferMode transferSpeed();
BankType bankType();
}
@FundTransfer使用了Spring的@Qualifier进行元注释,意味着@FundTransfer注释是一个自定义限定符注释。如果不使用@Qualifier对@FundTransfer注释进行元注释,则需要使用Spring的CustomAutowireConfigurer bean显式地向Spring容器注册@FundTransfer注释。两者具有相同的用途,允许基于transferSpeed和bankType特性对bean进行自动装配。
注意:如果一个自定义限定符注释没有使用@Qualifier进行元注释,那么就需要使用显式注册。
如下。
<bean class="org.springframework.beans.factory.annotation.CustomAutowireConfigurer">
<property name="customQualifierTypes">
<set>
<value>sample.MyCustomQualifier</value>
</set>
</property>
</bean>
JSR 330 的@Inject 和 @Named注释
与@Autowired和@Qualifier类似
@Inject可以在方法级、构造函数级、字段级使用==>与@Autowired具有相同的语义
@Named:如果在类型级别使用,那它的作用就像@Component一样。如果在方法参数级或者构造函数参数级使用@Named注释,那它的作用就像@Qualifier一样。如果一个类使用@Named注释,则Spring的context模式的context模式的<component-scan>元素对它的处理方式等同于使用@Component注释的bean类
注意:由于@Autowired有required的特性,而@Inject无法等同于这个特性,可以使用Java8的Optional类型来实现。
JSR 250 的@Resource注释
@Resource注释支持按字段和setter方法的名称自动装配
注意:@Resource不能用来自动装配构造函数参数和接收多个参数方法。
因为@Autowired注释不适用与本身为集合或Map类型的bean,在这种场景下可以使用@Resource注释来自动装配bean。
@Scope , @Lazy , @DependsOn , @Primary注释
注释 | 描述 |
@Scope | 指定bean范围(与<bean>元素的scope特性相同) |
@Lazy | 指定该bean由Spring容器延迟创建(与<bean>元素的lazy-init特性相同) |
@DependsOn | 指定bean的隐式依赖项(与<bean>元素的depends-on特性相同) |
@Primary | 将bean指定为自动装配的主要候选项(与<bean>元素的primary特性相同) |
@Value简化注释的bean类配置
可以在字段级、方法级、方法参数级、构造函数参数级使用
用途与<property>和<constructor-arg>元素的value特性相同