查找bean时的过滤流程: @Value ---> 如果没有@Value,根据type查找 ---> isAutowireCandidate -----> generic ---> qualifier ---> @Primary --> @Priority --> byName (dependencyName ) 1. resolveDependency()方法源码解析 两种情况, 情况一:走缓存 情况二:没缓存 1)如果有@Value注解,就解析返回获取到的值。@value返回的可能是字符串,也可能是对象。是各字符串时,先解析占位符,再解析Spring EL表达式(#{})。如果是字符串后,解析的结果,会根据TypeConverter再解析,如果类型匹配或者可以转换,就返回成功,否则会报错。 2)先bytype 后byname ,中间有6步过滤 findAutowireCandidates 返回的map中,value可能是bean对象(已实例化),也可能是bean的class对象。 2. findAutowireCandidates()方法源码解析 1)如果找到了多个bean,如果有bean有@Primary注解,就返回这个,如果有多个Primary,就报错。如果没有primay, 2)就看有没有@Priority,有的话返回优先级最高的。数字越小,优先级越高。 @Priority注解是增加在类上的,如果是一个类注册了多个实例,那这些实例的优先级都是一样的。如果是一个接口的多个实现分别增加优先级是可以的。 3)否则就根据bean.getDependencyName(属性字段的名字或者set参数的名字来确定的)来确定。
如何根据类型找到所有bean的名字:
找到bean的名字 bean名字对应的beandefinition是否是支持自动注入,可以自动注入的才能被筛选出来 org.springframework.beans.factory.support.SimpleAutowireCandidateResolver#isAutowireCandidate org.springframework.beans.factory.support.GenericTypeAwareAutowireCandidateResolver#isAutowireCandidate 泛型自动注入 class BaseService<T>{ @Autowired private T t; public T getT(){return t ;} } class UserService extends BaseService<OrderService>{ public OrderService test(){return getT() ;} } org.springframework.beans.factory.annotation.QualifierAnnotationAutowireCandidateResolver#isAutowireCandidate @Qualifier 定义在属性或者方法的时候可以指定要引入的bean的名字,定义在bean上的时候,标识
@Qualifier详细应用可以参考这里
问题 1)当注解有多个的时候,注解问题 @Autowired 和@Value 两个主键都有的时候,autowired优先级高,因为这个顺序是在注解类型里面定义的。1 autowired 2 value 3 Inject 2)beanFactory 怎么判断bean的类型,根据BeanDefinition就可以判断 3)占位符(${})填充时,会去Enrionment中取值 4)使用ObjectFactory 或Optional ObjectFactory<> class UserService { @Autowired public ObjectFactory<OrderService> orderService; public void test(){ orderService.getObject(); } } Optional class UserService { @Autowired public Optional<OrderService> orderService; public void test(){ orderService.get(); } }