一、@Autowired用法
替换:autowire属性,自动装配(按照类型装配,通过set方法,且方法可以省略)
位置:修饰属性,set方法
语法:@Autowired(required="true")
注意:1.如果容器中没有一个可以与之匹配且required属性为true则会报异常
NoSuchBeanDefinitionException;
2.如果容器中有多个可以类型可以与之匹配,则自动切换为按照名称装配;
3.如果容器中有多个可以类型可以与之匹配,则自动切换为按照名称装配,如果名称也没有匹配,则报异常NoUniqueBeanDefinitionException;
在controller层使用@Autowired注入一个service层对象:
@Controller
public class AccountControllerImp implements IAccountController{
@Autowired
public IAccountService service;
public void save(Account account) {
service.save(account);
}
public void deleteById(int id) {
service.deleteById(id);
}
public Account findByName(String name) {
return service.findByName(name);
}
public List<Account> findAll() {
return service.findAll();
}
}
二、@Autowired实现自动装配的过程
首先先了解Spring框架创建Bean对象的生命周期:实例化=>属性赋值=>初始化=>销毁。而在Spring框架对属性赋值的populateBean()方法上,有这样一段代码:
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
if (filteredPds == null) {
filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
return;
}
}
pvs = pvsToUse;
}
}
这段代码的意思就是首先获取到spring中所有实现了 BeanPostProcessor接口的类,并循环逐个处理,如果某个BeanPostProcessor实现类又实现了InstantiationAwareBeanPostProcessor,则调用其postProcessProperties方法,
而@Autowired就是使用AutowiredAnnotationBeanPostProcessor注解解析器实现的,AutowiredAnnotationBeanPostProcessor类间接实现了InstantiationAwareBeanPostProcessor,而InstantiationAwareBeanPostProcessor又实现了BeanPostProcessor。
这里就是调用@Autowired的注解解析器AutowiredAnnotationBeanPostProcessor中的postProcessProperties方法,这个方法的主要目的就是对属性进行注入。
代码如下:
@Override
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);
try {
metadata.inject(bean, beanName, pvs);
}
catch (BeanCreationException ex) {
throw ex;
}
catch (Throwable ex) {
throw new BeanCreationException(beanName, "Injection of autowired dependencies failed", ex);
}
return pvs;
}
这个方法中使用了两个方法,一个是findAutowiringMetadata,另一个是metadata.inject(bean, beanName, pvs)。其中,前者就是通过反射机制找到该对象所有标注了@Autowired注解的属性或方法等,并以InjectionMetadata对象返回,后者就是通过metadata对象对相关属性进行属性注入,从而实现自动装配。
三、总结
Spring框架在很大程度上为程序业务开发降低了耦合关系,@Autowired自动装配就是Spring IOC和DI核心思想的体现,通过将对象的控制权转交给Spring框架,由IOC容器在运行时向每个bean对象注入所依赖的另一个bean对象,从而实现自动装配。