@Autowired 注解支持属性注入、构造函数、方法注入。注入点也支持普通对象注入、数组、List、Map、泛型对象注入。
@Configuration
@ComponentScan
public class AccountConfig4 {
@Bean
public FileService fileService() {
return new FileService(){
};
}
@Bean
public FileService fileService2() {
return new FileService() {
};
}
@Bean
public GenericFileService<String> stringGenericFileService() {
return new GenericFileService<String>() {
};
}
@Bean
public GenericFileService<Integer> integerGenericFileService() {
return new GenericFileService<Integer>() {
};
}
public interface GenericFileService<T> {
}
public interface FileService {
}
}
@Component
public class FileServiceImpl {
@Autowired
private AccountConfig4.FileService fileService;
@Autowired
private List<AccountConfig4.FileService> fileServiceList;
@Autowired
private Map<String, AccountConfig4.FileService> fileServiceMap;
@Autowired
private AccountConfig4.GenericFileService<String> genericFileService;
@Autowired
private List<AccountConfig4.GenericFileService<Integer>> genericFileServices;
@Autowired
private Map<String, AccountConfig4.GenericFileService<Integer>> genericFileServiceMap;
}
public class AnnotationConfigTest {
public static void main(String[] args) throws IOException {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AccountConfig4.class);
FileServiceImpl bean = context.getBean(FileServiceImpl.class);
System.out.println(bean);
}
}
源码分析
@Autowired
注解是由 AutowiredAnnocationBeanPostProcessor
来处理的。Spring会在实例化Bean时有两个触发点:
- 在方法
postProcessMergedBeanDefinition
中,查找该Bean是否有@Autowired
注解
- 在方法
populateBean
进行属性注入时,也会查找该Bean是否有@Autowired
注解。
AutowiredAnnotationBeanPostProcessor
AutowiredAnnotationBeanPostProcessor
实现了两个接口:SmartInstantiationAwareBeanPostProcessor
和 MergedBeanDefinitionPostProcessor
。这个两个接口就针对不同入口点进行处理的。
public class AutowiredAnnotationBeanPostProcessor implements SmartInstantiationAwareBeanPostProcessor,
MergedBeanDefinitionPostProcessor, PriorityOrdered, BeanFactoryAware {
// 省略其他属性和方法
// postProcessMergedBeanDefinition方法会调用这个入口点
@Override
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
InjectionMetadata metadata = findAutowiringMetadata(beanName, beanType, null);
metadata.checkConfigMembers(</